[source navigation] [diff markup] [identifier search] [freetext search] [file search]

Oldlinux Cross Reference
Linux/fs/namei.c

Version: [1.0] [0.99.11] [0.99] [0.98] [0.97] [0.96a] [0.95] [0.12] [0.11] [0.01]
Architecture: [i386]

  1 /*
  2  *  linux/fs/namei.c
  3  *
  4  *  (C) 1991  Linus Torvalds
  5  */
  6 
  7 /*
  8  * Some corrections by tytso.
  9  */
 10 
 11 #include <linux/sched.h>
 12 #include <linux/kernel.h>
 13 #include <asm/segment.h>
 14 
 15 #include <string.h>
 16 #include <fcntl.h>
 17 #include <errno.h>
 18 #include <const.h>
 19 #include <sys/stat.h>
 20 
 21 #define ACC_MODE(x) ("\004\002\006\377"[(x)&O_ACCMODE])
 22 
 23 /*
 24  * comment out this line if you want names > NAME_LEN chars to be
 25  * truncated. Else they will be disallowed.
 26  */
 27 /* #define NO_TRUNCATE */
 28 
 29 #define MAY_EXEC 1
 30 #define MAY_WRITE 2
 31 #define MAY_READ 4
 32 
 33 /*
 34  *      permission()
 35  *
 36  * is used to check for read/write/execute permissions on a file.
 37  * I don't know if we should look at just the euid or both euid and
 38  * uid, but that should be easily changed.
 39  */
 40 static int permission(struct m_inode * inode,int mask)
 41 {
 42         int mode = inode->i_mode;
 43 
 44 /* special case: not even root can read/write a deleted file */
 45         if (inode->i_dev && !inode->i_nlinks)
 46                 return 0;
 47         else if (current->euid==inode->i_uid)
 48                 mode >>= 6;
 49         else if (current->egid==inode->i_gid)
 50                 mode >>= 3;
 51         if (((mode & mask & 0007) == mask) || suser())
 52                 return 1;
 53         return 0;
 54 }
 55 
 56 /*
 57  * ok, we cannot use strncmp, as the name is not in our data space.
 58  * Thus we'll have to use match. No big problem. Match also makes
 59  * some sanity tests.
 60  *
 61  * NOTE! unlike strncmp, match returns 1 for success, 0 for failure.
 62  */
 63 static int match(int len,const char * name,struct dir_entry * de)
 64 {
 65         register int same __asm__("ax");
 66 
 67         if (!de || !de->inode || len > NAME_LEN)
 68                 return 0;
 69         if (len < NAME_LEN && de->name[len])
 70                 return 0;
 71         __asm__("cld\n\t"
 72                 "fs ; repe ; cmpsb\n\t"
 73                 "setz %%al"
 74                 :"=a" (same)
 75                 :"" (0),"S" ((long) name),"D" ((long) de->name),"c" (len)
 76                 :"cx","di","si");
 77         return same;
 78 }
 79 
 80 /*
 81  *      find_entry()
 82  *
 83  * finds an entry in the specified directory with the wanted name. It
 84  * returns the cache buffer in which the entry was found, and the entry
 85  * itself (as a parameter - res_dir). It does NOT read the inode of the
 86  * entry - you'll have to do that yourself if you want to.
 87  *
 88  * This also takes care of the few special cases due to '..'-traversal
 89  * over a pseudo-root and a mount point.
 90  */
 91 static struct buffer_head * find_entry(struct m_inode ** dir,
 92         const char * name, int namelen, struct dir_entry ** res_dir)
 93 {
 94         int entries;
 95         int block,i;
 96         struct buffer_head * bh;
 97         struct dir_entry * de;
 98         struct super_block * sb;
 99 
100 #ifdef NO_TRUNCATE
101         if (namelen > NAME_LEN)
102                 return NULL;
103 #else
104         if (namelen > NAME_LEN)
105                 namelen = NAME_LEN;
106 #endif
107         entries = (*dir)->i_size / (sizeof (struct dir_entry));
108         *res_dir = NULL;
109         if (!namelen)
110                 return NULL;
111 /* check for '..', as we might have to do some "magic" for it */
112         if (namelen==2 && get_fs_byte(name)=='.' && get_fs_byte(name+1)=='.') {
113 /* '..' in a pseudo-root results in a faked '.' (just change namelen) */
114                 if ((*dir) == current->root)
115                         namelen=1;
116                 else if ((*dir)->i_num == ROOT_INO) {
117 /* '..' over a mount-point results in 'dir' being exchanged for the mounted
118    directory-inode. NOTE! We set mounted, so that we can iput the new dir */
119                         sb=get_super((*dir)->i_dev);
120                         if (sb->s_imount) {
121                                 iput(*dir);
122                                 (*dir)=sb->s_imount;
123                                 (*dir)->i_count++;
124                         }
125                 }
126         }
127         if (!(block = (*dir)->i_zone[0]))
128                 return NULL;
129         if (!(bh = bread((*dir)->i_dev,block)))
130                 return NULL;
131         i = 0;
132         de = (struct dir_entry *) bh->b_data;
133         while (i < entries) {
134                 if ((char *)de >= BLOCK_SIZE+bh->b_data) {
135                         brelse(bh);
136                         bh = NULL;
137                         if (!(block = bmap(*dir,i/DIR_ENTRIES_PER_BLOCK)) ||
138                             !(bh = bread((*dir)->i_dev,block))) {
139                                 i += DIR_ENTRIES_PER_BLOCK;
140                                 continue;
141                         }
142                         de = (struct dir_entry *) bh->b_data;
143                 }
144                 if (match(namelen,name,de)) {
145                         *res_dir = de;
146                         return bh;
147                 }
148                 de++;
149                 i++;
150         }
151         brelse(bh);
152         return NULL;
153 }
154 
155 /*
156  *      add_entry()
157  *
158  * adds a file entry to the specified directory, using the same
159  * semantics as find_entry(). It returns NULL if it failed.
160  *
161  * NOTE!! The inode part of 'de' is left at 0 - which means you
162  * may not sleep between calling this and putting something into
163  * the entry, as someone else might have used it while you slept.
164  */
165 static struct buffer_head * add_entry(struct m_inode * dir,
166         const char * name, int namelen, struct dir_entry ** res_dir)
167 {
168         int block,i;
169         struct buffer_head * bh;
170         struct dir_entry * de;
171 
172         *res_dir = NULL;
173 #ifdef NO_TRUNCATE
174         if (namelen > NAME_LEN)
175                 return NULL;
176 #else
177         if (namelen > NAME_LEN)
178                 namelen = NAME_LEN;
179 #endif
180         if (!namelen)
181                 return NULL;
182         if (!(block = dir->i_zone[0]))
183                 return NULL;
184         if (!(bh = bread(dir->i_dev,block)))
185                 return NULL;
186         i = 0;
187         de = (struct dir_entry *) bh->b_data;
188         while (1) {
189                 if ((char *)de >= BLOCK_SIZE+bh->b_data) {
190                         brelse(bh);
191                         bh = NULL;
192                         block = create_block(dir,i/DIR_ENTRIES_PER_BLOCK);
193                         if (!block)
194                                 return NULL;
195                         if (!(bh = bread(dir->i_dev,block))) {
196                                 i += DIR_ENTRIES_PER_BLOCK;
197                                 continue;
198                         }
199                         de = (struct dir_entry *) bh->b_data;
200                 }
201                 if (i*sizeof(struct dir_entry) >= dir->i_size) {
202                         de->inode=0;
203                         dir->i_size = (i+1)*sizeof(struct dir_entry);
204                         dir->i_dirt = 1;
205                         dir->i_ctime = CURRENT_TIME;
206                 }
207                 if (!de->inode) {
208                         dir->i_mtime = CURRENT_TIME;
209                         for (i=0; i < NAME_LEN ; i++)
210                                 de->name[i]=(i<namelen)?get_fs_byte(name+i):0;
211                         bh->b_dirt = 1;
212                         *res_dir = de;
213                         return bh;
214                 }
215                 de++;
216                 i++;
217         }
218         brelse(bh);
219         return NULL;
220 }
221 
222 /*
223  *      get_dir()
224  *
225  * Getdir traverses the pathname until it hits the topmost directory.
226  * It returns NULL on failure.
227  */
228 static struct m_inode * get_dir(const char * pathname)
229 {
230         char c;
231         const char * thisname;
232         struct m_inode * inode;
233         struct buffer_head * bh;
234         int namelen,inr,idev;
235         struct dir_entry * de;
236 
237         if (!current->root || !current->root->i_count)
238                 panic("No root inode");
239         if (!current->pwd || !current->pwd->i_count)
240                 panic("No cwd inode");
241         if ((c=get_fs_byte(pathname))=='/') {
242                 inode = current->root;
243                 pathname++;
244         } else if (c)
245                 inode = current->pwd;
246         else
247                 return NULL;    /* empty name is bad */
248         inode->i_count++;
249         while (1) {
250                 thisname = pathname;
251                 if (!S_ISDIR(inode->i_mode) || !permission(inode,MAY_EXEC)) {
252                         iput(inode);
253                         return NULL;
254                 }
255                 for(namelen=0;(c=get_fs_byte(pathname++))&&(c!='/');namelen++)
256                         /* nothing */ ;
257                 if (!c)
258                         return inode;
259                 if (!(bh = find_entry(&inode,thisname,namelen,&de))) {
260                         iput(inode);
261                         return NULL;
262                 }
263                 inr = de->inode;
264                 idev = inode->i_dev;
265                 brelse(bh);
266                 iput(inode);
267                 if (!(inode = iget(idev,inr)))
268                         return NULL;
269         }
270 }
271 
272 /*
273  *      dir_namei()
274  *
275  * dir_namei() returns the inode of the directory of the
276  * specified name, and the name within that directory.
277  */
278 static struct m_inode * dir_namei(const char * pathname,
279         int * namelen, const char ** name)
280 {
281         char c;
282         const char * basename;
283         struct m_inode * dir;
284 
285         if (!(dir = get_dir(pathname)))
286                 return NULL;
287         basename = pathname;
288         while (c=get_fs_byte(pathname++))
289                 if (c=='/')
290                         basename=pathname;
291         *namelen = pathname-basename-1;
292         *name = basename;
293         return dir;
294 }
295 
296 /*
297  *      namei()
298  *
299  * is used by most simple commands to get the inode of a specified name.
300  * Open, link etc use their own routines, but this is enough for things
301  * like 'chmod' etc.
302  */
303 struct m_inode * namei(const char * pathname)
304 {
305         const char * basename;
306         int inr,dev,namelen;
307         struct m_inode * dir;
308         struct buffer_head * bh;
309         struct dir_entry * de;
310 
311         if (!(dir = dir_namei(pathname,&namelen,&basename)))
312                 return NULL;
313         if (!namelen)                   /* special case: '/usr/' etc */
314                 return dir;
315         bh = find_entry(&dir,basename,namelen,&de);
316         if (!bh) {
317                 iput(dir);
318                 return NULL;
319         }
320         inr = de->inode;
321         dev = dir->i_dev;
322         brelse(bh);
323         iput(dir);
324         dir=iget(dev,inr);
325         if (dir) {
326                 dir->i_atime=CURRENT_TIME;
327                 dir->i_dirt=1;
328         }
329         return dir;
330 }
331 
332 /*
333  *      open_namei()
334  *
335  * namei for open - this is in fact almost the whole open-routine.
336  */
337 int open_namei(const char * pathname, int flag, int mode,
338         struct m_inode ** res_inode)
339 {
340         const char * basename;
341         int inr,dev,namelen;
342         struct m_inode * dir, *inode;
343         struct buffer_head * bh;
344         struct dir_entry * de;
345 
346         if ((flag & O_TRUNC) && !(flag & O_ACCMODE))
347                 flag |= O_WRONLY;
348         mode &= 0777 & ~current->umask;
349         mode |= I_REGULAR;
350         if (!(dir = dir_namei(pathname,&namelen,&basename)))
351                 return -ENOENT;
352         if (!namelen) {                 /* special case: '/usr/' etc */
353                 if (!(flag & (O_ACCMODE|O_CREAT|O_TRUNC))) {
354                         *res_inode=dir;
355                         return 0;
356                 }
357                 iput(dir);
358                 return -EISDIR;
359         }
360         bh = find_entry(&dir,basename,namelen,&de);
361         if (!bh) {
362                 if (!(flag & O_CREAT)) {
363                         iput(dir);
364                         return -ENOENT;
365                 }
366                 if (!permission(dir,MAY_WRITE)) {
367                         iput(dir);
368                         return -EACCES;
369                 }
370                 inode = new_inode(dir->i_dev);
371                 if (!inode) {
372                         iput(dir);
373                         return -ENOSPC;
374                 }
375                 inode->i_uid = current->euid;
376                 inode->i_mode = mode;
377                 inode->i_dirt = 1;
378                 bh = add_entry(dir,basename,namelen,&de);
379                 if (!bh) {
380                         inode->i_nlinks--;
381                         iput(inode);
382                         iput(dir);
383                         return -ENOSPC;
384                 }
385                 de->inode = inode->i_num;
386                 bh->b_dirt = 1;
387                 brelse(bh);
388                 iput(dir);
389                 *res_inode = inode;
390                 return 0;
391         }
392         inr = de->inode;
393         dev = dir->i_dev;
394         brelse(bh);
395         iput(dir);
396         if (flag & O_EXCL)
397                 return -EEXIST;
398         if (!(inode=iget(dev,inr)))
399                 return -EACCES;
400         if ((S_ISDIR(inode->i_mode) && (flag & O_ACCMODE)) ||
401             !permission(inode,ACC_MODE(flag))) {
402                 iput(inode);
403                 return -EPERM;
404         }
405         inode->i_atime = CURRENT_TIME;
406         if (flag & O_TRUNC)
407                 truncate(inode);
408         *res_inode = inode;
409         return 0;
410 }
411 
412 int sys_mknod(const char * filename, int mode, int dev)
413 {
414         const char * basename;
415         int namelen;
416         struct m_inode * dir, * inode;
417         struct buffer_head * bh;
418         struct dir_entry * de;
419         
420         if (!suser())
421                 return -EPERM;
422         if (!(dir = dir_namei(filename,&namelen,&basename)))
423                 return -ENOENT;
424         if (!namelen) {
425                 iput(dir);
426                 return -ENOENT;
427         }
428         if (!permission(dir,MAY_WRITE)) {
429                 iput(dir);
430                 return -EPERM;
431         }
432         bh = find_entry(&dir,basename,namelen,&de);
433         if (bh) {
434                 brelse(bh);
435                 iput(dir);
436                 return -EEXIST;
437         }
438         inode = new_inode(dir->i_dev);
439         if (!inode) {
440                 iput(dir);
441                 return -ENOSPC;
442         }
443         inode->i_mode = mode;
444         if (S_ISBLK(mode) || S_ISCHR(mode))
445                 inode->i_zone[0] = dev;
446         inode->i_mtime = inode->i_atime = CURRENT_TIME;
447         inode->i_dirt = 1;
448         bh = add_entry(dir,basename,namelen,&de);
449         if (!bh) {
450                 iput(dir);
451                 inode->i_nlinks=0;
452                 iput(inode);
453                 return -ENOSPC;
454         }
455         de->inode = inode->i_num;
456         bh->b_dirt = 1;
457         iput(dir);
458         iput(inode);
459         brelse(bh);
460         return 0;
461 }
462 
463 int sys_mkdir(const char * pathname, int mode)
464 {
465         const char * basename;
466         int namelen;
467         struct m_inode * dir, * inode;
468         struct buffer_head * bh, *dir_block;
469         struct dir_entry * de;
470 
471         if (!suser())
472                 return -EPERM;
473         if (!(dir = dir_namei(pathname,&namelen,&basename)))
474                 return -ENOENT;
475         if (!namelen) {
476                 iput(dir);
477                 return -ENOENT;
478         }
479         if (!permission(dir,MAY_WRITE)) {
480                 iput(dir);
481                 return -EPERM;
482         }
483         bh = find_entry(&dir,basename,namelen,&de);
484         if (bh) {
485                 brelse(bh);
486                 iput(dir);
487                 return -EEXIST;
488         }
489         inode = new_inode(dir->i_dev);
490         if (!inode) {
491                 iput(dir);
492                 return -ENOSPC;
493         }
494         inode->i_size = 32;
495         inode->i_dirt = 1;
496         inode->i_mtime = inode->i_atime = CURRENT_TIME;
497         if (!(inode->i_zone[0]=new_block(inode->i_dev))) {
498                 iput(dir);
499                 inode->i_nlinks--;
500                 iput(inode);
501                 return -ENOSPC;
502         }
503         inode->i_dirt = 1;
504         if (!(dir_block=bread(inode->i_dev,inode->i_zone[0]))) {
505                 iput(dir);
506                 free_block(inode->i_dev,inode->i_zone[0]);
507                 inode->i_nlinks--;
508                 iput(inode);
509                 return -ERROR;
510         }
511         de = (struct dir_entry *) dir_block->b_data;
512         de->inode=inode->i_num;
513         strcpy(de->name,".");
514         de++;
515         de->inode = dir->i_num;
516         strcpy(de->name,"..");
517         inode->i_nlinks = 2;
518         dir_block->b_dirt = 1;
519         brelse(dir_block);
520         inode->i_mode = I_DIRECTORY | (mode & 0777 & ~current->umask);
521         inode->i_dirt = 1;
522         bh = add_entry(dir,basename,namelen,&de);
523         if (!bh) {
524                 iput(dir);
525                 free_block(inode->i_dev,inode->i_zone[0]);
526                 inode->i_nlinks=0;
527                 iput(inode);
528                 return -ENOSPC;
529         }
530         de->inode = inode->i_num;
531         bh->b_dirt = 1;
532         dir->i_nlinks++;
533         dir->i_dirt = 1;
534         iput(dir);
535         iput(inode);
536         brelse(bh);
537         return 0;
538 }
539 
540 /*
541  * routine to check that the specified directory is empty (for rmdir)
542  */
543 static int empty_dir(struct m_inode * inode)
544 {
545         int nr,block;
546         int len;
547         struct buffer_head * bh;
548         struct dir_entry * de;
549 
550         len = inode->i_size / sizeof (struct dir_entry);
551         if (len<2 || !inode->i_zone[0] ||
552             !(bh=bread(inode->i_dev,inode->i_zone[0]))) {
553                 printk("warning - bad directory on dev %04x\n",inode->i_dev);
554                 return 0;
555         }
556         de = (struct dir_entry *) bh->b_data;
557         if (de[0].inode != inode->i_num || !de[1].inode || 
558             strcmp(".",de[0].name) || strcmp("..",de[1].name)) {
559                 printk("warning - bad directory on dev %04x\n",inode->i_dev);
560                 return 0;
561         }
562         nr = 2;
563         de += 2;
564         while (nr<len) {
565                 if ((void *) de >= (void *) (bh->b_data+BLOCK_SIZE)) {
566                         brelse(bh);
567                         block=bmap(inode,nr/DIR_ENTRIES_PER_BLOCK);
568                         if (!block) {
569                                 nr += DIR_ENTRIES_PER_BLOCK;
570                                 continue;
571                         }
572                         if (!(bh=bread(inode->i_dev,block)))
573                                 return 0;
574                         de = (struct dir_entry *) bh->b_data;
575                 }
576                 if (de->inode) {
577                         brelse(bh);
578                         return 0;
579                 }
580                 de++;
581                 nr++;
582         }
583         brelse(bh);
584         return 1;
585 }
586 
587 int sys_rmdir(const char * name)
588 {
589         const char * basename;
590         int namelen;
591         struct m_inode * dir, * inode;
592         struct buffer_head * bh;
593         struct dir_entry * de;
594 
595         if (!suser())
596                 return -EPERM;
597         if (!(dir = dir_namei(name,&namelen,&basename)))
598                 return -ENOENT;
599         if (!namelen) {
600                 iput(dir);
601                 return -ENOENT;
602         }
603         if (!permission(dir,MAY_WRITE)) {
604                 iput(dir);
605                 return -EPERM;
606         }
607         bh = find_entry(&dir,basename,namelen,&de);
608         if (!bh) {
609                 iput(dir);
610                 return -ENOENT;
611         }
612         if (!(inode = iget(dir->i_dev, de->inode))) {
613                 iput(dir);
614                 brelse(bh);
615                 return -EPERM;
616         }
617         if ((dir->i_mode & S_ISVTX) && current->euid &&
618             inode->i_uid != current->euid) {
619                 iput(dir);
620                 iput(inode);
621                 brelse(bh);
622                 return -EPERM;
623         }
624         if (inode->i_dev != dir->i_dev || inode->i_count>1) {
625                 iput(dir);
626                 iput(inode);
627                 brelse(bh);
628                 return -EPERM;
629         }
630         if (inode == dir) {     /* we may not delete ".", but "../dir" is ok */
631                 iput(inode);
632                 iput(dir);
633                 brelse(bh);
634                 return -EPERM;
635         }
636         if (!S_ISDIR(inode->i_mode)) {
637                 iput(inode);
638                 iput(dir);
639                 brelse(bh);
640                 return -ENOTDIR;
641         }
642         if (!empty_dir(inode)) {
643                 iput(inode);
644                 iput(dir);
645                 brelse(bh);
646                 return -ENOTEMPTY;
647         }
648         if (inode->i_nlinks != 2)
649                 printk("empty directory has nlink!=2 (%d)",inode->i_nlinks);
650         de->inode = 0;
651         bh->b_dirt = 1;
652         brelse(bh);
653         inode->i_nlinks=0;
654         inode->i_dirt=1;
655         dir->i_nlinks--;
656         dir->i_ctime = dir->i_mtime = CURRENT_TIME;
657         dir->i_dirt=1;
658         iput(dir);
659         iput(inode);
660         return 0;
661 }
662 
663 int sys_unlink(const char * name)
664 {
665         const char * basename;
666         int namelen;
667         struct m_inode * dir, * inode;
668         struct buffer_head * bh;
669         struct dir_entry * de;
670 
671         if (!(dir = dir_namei(name,&namelen,&basename)))
672                 return -ENOENT;
673         if (!namelen) {
674                 iput(dir);
675                 return -ENOENT;
676         }
677         if (!permission(dir,MAY_WRITE)) {
678                 iput(dir);
679                 return -EPERM;
680         }
681         bh = find_entry(&dir,basename,namelen,&de);
682         if (!bh) {
683                 iput(dir);
684                 return -ENOENT;
685         }
686         if (!(inode = iget(dir->i_dev, de->inode))) {
687                 iput(dir);
688                 brelse(bh);
689                 return -ENOENT;
690         }
691         if ((dir->i_mode & S_ISVTX) && !suser() &&
692             current->euid != inode->i_uid &&
693             current->euid != dir->i_uid) {
694                 iput(dir);
695                 iput(inode);
696                 brelse(bh);
697                 return -EPERM;
698         }
699         if (S_ISDIR(inode->i_mode)) {
700                 iput(inode);
701                 iput(dir);
702                 brelse(bh);
703                 return -EPERM;
704         }
705         if (!inode->i_nlinks) {
706                 printk("Deleting nonexistent file (%04x:%d), %d\n",
707                         inode->i_dev,inode->i_num,inode->i_nlinks);
708                 inode->i_nlinks=1;
709         }
710         de->inode = 0;
711         bh->b_dirt = 1;
712         brelse(bh);
713         inode->i_nlinks--;
714         inode->i_dirt = 1;
715         inode->i_ctime = CURRENT_TIME;
716         iput(inode);
717         iput(dir);
718         return 0;
719 }
720 
721 int sys_link(const char * oldname, const char * newname)
722 {
723         struct dir_entry * de;
724         struct m_inode * oldinode, * dir;
725         struct buffer_head * bh;
726         const char * basename;
727         int namelen;
728 
729         oldinode=namei(oldname);
730         if (!oldinode)
731                 return -ENOENT;
732         if (S_ISDIR(oldinode->i_mode)) {
733                 iput(oldinode);
734                 return -EPERM;
735         }
736         dir = dir_namei(newname,&namelen,&basename);
737         if (!dir) {
738                 iput(oldinode);
739                 return -EACCES;
740         }
741         if (!namelen) {
742                 iput(oldinode);
743                 iput(dir);
744                 return -EPERM;
745         }
746         if (dir->i_dev != oldinode->i_dev) {
747                 iput(dir);
748                 iput(oldinode);
749                 return -EXDEV;
750         }
751         if (!permission(dir,MAY_WRITE)) {
752                 iput(dir);
753                 iput(oldinode);
754                 return -EACCES;
755         }
756         bh = find_entry(&dir,basename,namelen,&de);
757         if (bh) {
758                 brelse(bh);
759                 iput(dir);
760                 iput(oldinode);
761                 return -EEXIST;
762         }
763         bh = add_entry(dir,basename,namelen,&de);
764         if (!bh) {
765                 iput(dir);
766                 iput(oldinode);
767                 return -ENOSPC;
768         }
769         de->inode = oldinode->i_num;
770         bh->b_dirt = 1;
771         brelse(bh);
772         iput(dir);
773         oldinode->i_nlinks++;
774         oldinode->i_ctime = CURRENT_TIME;
775         oldinode->i_dirt = 1;
776         iput(oldinode);
777         return 0;
778 }
779 

[source navigation] [diff markup] [identifier search] [freetext search] [file search]

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.