root/fs/ext2/namei.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ext2_match
  2. ext2_find_entry
  3. ext2_lookup
  4. ext2_add_entry
  5. ext2_delete_entry
  6. ext2_create
  7. ext2_mknod
  8. ext2_mkdir
  9. empty_dir
  10. ext2_rmdir
  11. ext2_unlink
  12. ext2_symlink
  13. ext2_link
  14. subdir
  15. do_ext2_rename
  16. ext2_rename

   1 /*
   2  *  linux/fs/ext2/namei.c
   3  *
   4  *  Copyright (C) 1992, 1993  Remy Card (card@masi.ibp.fr)
   5  *
   6  *  from
   7  *
   8  *  linux/fs/minix/namei.c
   9  *
  10  *  Copyright (C) 1991, 1992  Linus Torvalds
  11  */
  12 
  13 #include <linux/sched.h>
  14 #include <linux/ext2_fs.h>
  15 #include <linux/kernel.h>
  16 #include <linux/string.h>
  17 #include <linux/stat.h>
  18 #include <linux/fcntl.h>
  19 #include <linux/errno.h>
  20 
  21 #include <asm/segment.h>
  22 
  23 /*
  24  * comment out this line if you want names > EXT2_NAME_LEN chars to be
  25  * truncated. Else they will be disallowed.
  26  */
  27 /* #define NO_TRUNCATE */
  28         
  29 /*
  30  * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
  31  */
  32 static int ext2_match (int len, const char * const name,
     /* [previous][next][first][last][top][bottom][index][help] */
  33                        struct ext2_dir_entry * de)
  34 {
  35         unsigned char same;
  36 
  37         if (!de || !de->inode || len > EXT2_NAME_LEN)
  38                 return 0;
  39         /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
  40         if (!len && de->name_len == 1 && (de->name[0] == '.') &&
  41            (de->name[1] == '\0'))
  42                 return 1;
  43         if (len != de->name_len)
  44                 return 0;
  45         __asm__("cld\n\t"
  46                 "repe ; cmpsb\n\t"
  47                 "setz %0"
  48                 :"=q" (same)
  49                 :"S" ((long) name), "D" ((long) de->name), "c" (len)
  50                 :"cx", "di", "si");
  51         return (int) same;
  52 }
  53 
  54 /*
  55  *      ext2_find_entry()
  56  *
  57  * finds an entry in the specified directory with the wanted name. It
  58  * returns the cache buffer in which the entry was found, and the entry
  59  * itself (as a parameter - res_dir). It does NOT read the inode of the
  60  * entry - you'll have to do that yourself if you want to.
  61  *
  62  */
  63 static struct buffer_head * ext2_find_entry (struct inode * dir,
     /* [previous][next][first][last][top][bottom][index][help] */
  64                                              const char * const name, int namelen,
  65                                              struct ext2_dir_entry ** res_dir)
  66 {
  67         long offset;
  68         struct buffer_head * bh;
  69         struct ext2_dir_entry * de;
  70         struct super_block * sb;
  71         int err;
  72 
  73         *res_dir = NULL;
  74         if (!dir)
  75                 return NULL;
  76         sb = dir->i_sb;
  77 #ifdef NO_TRUNCATE
  78         if (namelen > EXT2_NAME_LEN)
  79                 return NULL;
  80 #else
  81         if (namelen > EXT2_NAME_LEN)
  82                 namelen = EXT2_NAME_LEN;
  83 #endif
  84         bh = ext2_bread (dir, 0, 0, &err);
  85         if (!bh)
  86                 return NULL;
  87         offset = 0;
  88         de = (struct ext2_dir_entry *) bh->b_data;
  89         while (offset < dir->i_size) {
  90                 if (!bh || (char *)de >= sb->s_blocksize + bh->b_data) {
  91                         brelse (bh);
  92                         bh = ext2_bread (dir, offset >> EXT2_BLOCK_SIZE_BITS(sb), 0, &err);
  93                         if (!bh) {
  94                                 offset += sb->s_blocksize;
  95                                 continue;
  96                         }
  97                         de = (struct ext2_dir_entry *) bh->b_data;
  98                 }
  99                 if (! ext2_check_dir_entry ("ext2_find_entry", dir, de, bh,
 100                                             offset)) {
 101                         brelse (bh);
 102                         return NULL;
 103                 }
 104                 if (ext2_match (namelen, name, de)) {
 105                         *res_dir = de;
 106                         return bh;
 107                 }
 108                 offset += de->rec_len;
 109                 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
 110         }
 111         brelse (bh);
 112         return NULL;
 113 }
 114 
 115 int ext2_lookup (struct inode * dir, const char * name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 116                  struct inode ** result)
 117 {
 118         int ino;
 119         struct ext2_dir_entry * de;
 120         struct buffer_head * bh;
 121 
 122         *result = NULL;
 123         if (!dir)
 124                 return -ENOENT;
 125         if (!S_ISDIR(dir->i_mode)) {
 126                 iput (dir);
 127                 return -ENOENT;
 128         }
 129 #ifndef DONT_USE_DCACHE
 130         if (!(ino = ext2_dcache_lookup (dir->i_dev, dir->i_ino, name, len))) {
 131 #endif
 132                 if (!(bh = ext2_find_entry (dir, name, len, &de))) {
 133                         iput (dir);
 134                         return -ENOENT;
 135                 }
 136                 ino = de->inode;
 137 #ifndef DONT_USE_DCACHE
 138                 ext2_dcache_add (dir->i_dev, dir->i_ino, de->name,
 139                                  de->name_len, ino);
 140 #endif
 141                 brelse (bh);
 142 #ifndef DONT_USE_DCACHE
 143         }
 144 #endif
 145         if (!(*result = iget (dir->i_sb, ino))) {
 146                 iput (dir);
 147                 return -EACCES;
 148         }
 149         iput (dir);
 150         return 0;
 151 }
 152 
 153 /*
 154  *      ext2_add_entry()
 155  *
 156  * adds a file entry to the specified directory, using the same
 157  * semantics as ext2_find_entry(). It returns NULL if it failed.
 158  *
 159  * NOTE!! The inode part of 'de' is left at 0 - which means you
 160  * may not sleep between calling this and putting something into
 161  * the entry, as someone else might have used it while you slept.
 162  */
 163 static struct buffer_head * ext2_add_entry (struct inode * dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 164                                             const char * name, int namelen,
 165                                             struct ext2_dir_entry ** res_dir,
 166                                             int *err)
 167 {
 168         int i;
 169         long offset;
 170         unsigned short rec_len;
 171         struct buffer_head * bh;
 172         struct ext2_dir_entry * de, * de1;
 173         struct super_block * sb;
 174 
 175         *err = -EINVAL;
 176         *res_dir = NULL;
 177         if (!dir)
 178                 return NULL;
 179         sb = dir->i_sb;
 180 #ifdef NO_TRUNCATE
 181         if (namelen > EXT2_NAME_LEN)
 182                 return NULL;
 183 #else
 184         if (namelen > EXT2_NAME_LEN)
 185                 namelen = EXT2_NAME_LEN;
 186 #endif
 187         if (!namelen)
 188                 return NULL;
 189         /* Is this a busy deleted directory?  Can't create new files 
 190            if so */
 191         if (dir->i_size == 0)
 192         {
 193                 *err = -ENOENT;
 194                 return NULL;
 195         }
 196         bh = ext2_bread (dir, 0, 0, err);
 197         if (!bh)
 198                 return NULL;
 199         rec_len = EXT2_DIR_REC_LEN(namelen);
 200         offset = 0;
 201         de = (struct ext2_dir_entry *) bh->b_data;
 202         *err = -ENOSPC;
 203         while (1) {
 204                 if ((char *)de >= sb->s_blocksize + bh->b_data) {
 205                         brelse (bh);
 206                         bh = NULL;
 207                         bh = ext2_bread (dir, offset >> EXT2_BLOCK_SIZE_BITS(sb), 1, err);
 208                         if (!bh)
 209                                 return NULL;
 210                         if (dir->i_size <= offset) {
 211                                 if (dir->i_size == 0) {
 212                                         *err = -ENOENT;
 213                                         return NULL;
 214                                 }
 215 #ifdef EXT2FS_DEBUG
 216                                 printk ("ext2_add_entry: creating next block\n");
 217 #endif
 218                                 de = (struct ext2_dir_entry *) bh->b_data;
 219                                 de->inode = 0;
 220                                 de->rec_len = sb->s_blocksize;
 221                                 dir->i_size = offset + sb->s_blocksize;
 222                                 dir->i_dirt = 1;
 223                                 dir->i_ctime = CURRENT_TIME;
 224                         } else {
 225 #ifdef EXT2FS_DEBUG
 226                                 printk ("ext2_add_entry: skipping to next block\n");
 227 #endif
 228                                 de = (struct ext2_dir_entry *) bh->b_data;
 229                         }
 230                 }
 231                 if (! ext2_check_dir_entry ("ext2_add_entry", dir, de, bh,
 232                                             offset)) {
 233                         *err = -ENOENT;
 234                         brelse (bh);
 235                         return NULL;
 236                 }
 237                 if (de->inode) {
 238                         if (ext2_match (namelen, name, de)) {
 239                                 *err = -EEXIST;
 240                                 brelse (bh);
 241                                 return NULL;
 242                         }
 243                 }
 244                 if ((!de->inode && de->rec_len >= rec_len) ||
 245                     (de->rec_len >= EXT2_DIR_REC_LEN(de->name_len) + rec_len)) {
 246                         offset += de->rec_len;
 247                         if (de->inode) {
 248                                 de1 = (struct ext2_dir_entry *) ((char *) de +
 249                                         EXT2_DIR_REC_LEN(de->name_len));
 250                                 de1->rec_len = de->rec_len -
 251                                         EXT2_DIR_REC_LEN(de->name_len);
 252                                 de->rec_len = EXT2_DIR_REC_LEN(de->name_len);
 253                                 de = de1;
 254                         }
 255                         de->inode = 0;
 256                         de->name_len = namelen;
 257                         for (i = 0; i < namelen ; i++)
 258                                 de->name[i] = name [i];
 259                         dir->i_mtime = dir->i_ctime = CURRENT_TIME;
 260                         dir->i_dirt = 1;
 261                         bh->b_dirt = 1;
 262                         *res_dir = de;
 263                         *err = 0;
 264                         return bh;
 265                 }
 266                 offset += de->rec_len;
 267                 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
 268         }
 269         brelse (bh);
 270         return NULL;
 271 }
 272 
 273 /*
 274  * ext2_delete_entry deletes a directory entry by merging it with the
 275  * previous entry
 276  */
 277 static int ext2_delete_entry (struct ext2_dir_entry * dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 278                               struct buffer_head *bh)
 279 {
 280         struct ext2_dir_entry * de, * pde;
 281         int i;
 282 
 283         i = 0;
 284         pde = NULL;
 285         de = (struct ext2_dir_entry *) bh->b_data;
 286         while (i < bh->b_size) {
 287                 if (! ext2_check_dir_entry ("ext2_delete_entry", NULL, 
 288                                             de, bh, i))
 289                         return -EIO;
 290                 if (de == dir)  {
 291                         if (pde)
 292                                 pde->rec_len += dir->rec_len;
 293                         else
 294                                 dir->inode = 0;
 295                         return 0;
 296                 }
 297                 i += de->rec_len;
 298                 pde = de;
 299                 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
 300         }
 301         return -ENOENT;
 302 }
 303 
 304 int ext2_create (struct inode * dir,const char * name, int len, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
 305                  struct inode ** result)
 306 {
 307         struct inode * inode;
 308         struct buffer_head * bh;
 309         struct ext2_dir_entry * de;
 310         int err;
 311 
 312         *result = NULL;
 313         if (!dir)
 314                 return -ENOENT;
 315         inode = ext2_new_inode (dir, mode);
 316         if (!inode) {
 317                 iput (dir);
 318                 return -ENOSPC;
 319         }
 320         inode->i_op = &ext2_file_inode_operations;
 321         inode->i_mode = mode;
 322         inode->i_dirt = 1;
 323         bh = ext2_add_entry (dir, name, len, &de, &err);
 324         if (!bh) {
 325                 inode->i_nlink--;
 326                 inode->i_dirt = 1;
 327                 iput (inode);
 328                 iput (dir);
 329                 return err;
 330         }
 331         de->inode = inode->i_ino;
 332 #ifndef DONT_USE_DCACHE
 333         ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
 334                          de->inode);
 335 #endif
 336         bh->b_dirt = 1;
 337         brelse (bh);
 338         iput (dir);
 339         *result = inode;
 340         return 0;
 341 }
 342 
 343 int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
 344                 int rdev)
 345 {
 346         struct inode * inode;
 347         struct buffer_head * bh;
 348         struct ext2_dir_entry * de;
 349         int err;
 350 
 351         if (!dir)
 352                 return -ENOENT;
 353         bh = ext2_find_entry (dir, name, len, &de);
 354         if (bh) {
 355                 brelse (bh);
 356                 iput (dir);
 357                 return -EEXIST;
 358         }
 359         inode = ext2_new_inode (dir, mode);
 360         if (!inode) {
 361                 iput (dir);
 362                 return -ENOSPC;
 363         }
 364         inode->i_uid = current->euid;
 365         inode->i_mode = mode;
 366         inode->i_op = NULL;
 367         if (S_ISREG(inode->i_mode))
 368                 inode->i_op = &ext2_file_inode_operations;
 369         else if (S_ISDIR(inode->i_mode)) {
 370                 inode->i_op = &ext2_dir_inode_operations;
 371                 if (dir->i_mode & S_ISGID)
 372                         inode->i_mode |= S_ISGID;
 373         }
 374         else if (S_ISLNK(inode->i_mode))
 375                 inode->i_op = &ext2_symlink_inode_operations;
 376         else if (S_ISCHR(inode->i_mode))
 377                 inode->i_op = &chrdev_inode_operations;
 378         else if (S_ISBLK(inode->i_mode))
 379                 inode->i_op = &blkdev_inode_operations;
 380         else if (S_ISFIFO(inode->i_mode)) 
 381                 init_fifo(inode);
 382         if (S_ISBLK(mode) || S_ISCHR(mode))
 383                 inode->i_rdev = rdev;
 384         inode->i_mtime = inode->i_atime = CURRENT_TIME;
 385         inode->i_dirt = 1;
 386         bh = ext2_add_entry (dir, name, len, &de, &err);
 387         if (!bh) {
 388                 inode->i_nlink--;
 389                 inode->i_dirt = 1;
 390                 iput (inode);
 391                 iput (dir);
 392                 return err;
 393         }
 394         de->inode = inode->i_ino;
 395 #ifndef DONT_USE_DCACHE
 396         ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
 397                          de->inode);
 398 #endif
 399         bh->b_dirt = 1;
 400         brelse (bh);
 401         iput (dir);
 402         iput (inode);
 403         return 0;
 404 }
 405 
 406 int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 407 {
 408         struct inode * inode;
 409         struct buffer_head * bh, * dir_block;
 410         struct ext2_dir_entry * de;
 411         int err;
 412 
 413         if (!dir)
 414                 return -ENOENT;
 415         bh = ext2_find_entry (dir, name, len, &de);
 416         if (bh) {
 417                 brelse (bh);
 418                 iput (dir);
 419                 return -EEXIST;
 420         }
 421         if (dir->i_nlink >= EXT2_LINK_MAX) {
 422                 iput (dir);
 423                 return -EMLINK;
 424         }
 425         inode = ext2_new_inode (dir, S_IFDIR);
 426         if (!inode) {
 427                 iput (dir);
 428                 return -ENOSPC;
 429         }
 430         inode->i_op = &ext2_dir_inode_operations;
 431         inode->i_size = inode->i_sb->s_blocksize;
 432         inode->i_mtime = inode->i_atime = CURRENT_TIME;
 433         dir_block = ext2_bread (inode, 0, 1, &err);
 434         if (!dir_block) {
 435                 iput (dir);
 436                 inode->i_nlink--;
 437                 inode->i_dirt = 1;
 438                 iput (inode);
 439                 return err;
 440         }
 441         inode->i_blocks = inode->i_sb->s_blocksize / 512;
 442         de = (struct ext2_dir_entry *) dir_block->b_data;
 443         de->inode = inode->i_ino;
 444         de->name_len = 1;
 445         de->rec_len = EXT2_DIR_REC_LEN(de->name_len);
 446         strcpy (de->name, ".");
 447         de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
 448         de->inode = dir->i_ino;
 449         de->rec_len = inode->i_sb->s_blocksize - EXT2_DIR_REC_LEN(1);
 450         de->name_len = 2;
 451         strcpy (de->name, "..");
 452         inode->i_nlink = 2;
 453         dir_block->b_dirt = 1;
 454         brelse (dir_block);
 455         inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->umask);
 456         if (dir->i_mode & S_ISGID)
 457                 inode->i_mode |= S_ISGID;
 458         inode->i_dirt = 1;
 459         bh = ext2_add_entry (dir, name, len, &de, &err);
 460         if (!bh) {
 461                 iput (dir);
 462                 inode->i_nlink = 0;
 463                 iput (inode);
 464                 return err;
 465         }
 466         de->inode = inode->i_ino;
 467 #ifndef DONT_USE_DCACHE
 468         ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
 469                          de->inode);
 470 #endif
 471         bh->b_dirt = 1;
 472         dir->i_nlink++;
 473         dir->i_dirt = 1;
 474         iput (dir);
 475         iput (inode);
 476         brelse (bh);
 477         return 0;
 478 }
 479 
 480 /*
 481  * routine to check that the specified directory is empty (for rmdir)
 482  */
 483 static int empty_dir (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 484 {
 485         unsigned long offset;
 486         struct buffer_head * bh;
 487         struct ext2_dir_entry * de, * de1;
 488         struct super_block * sb;
 489         int err;
 490 
 491         sb = inode->i_sb;
 492         if (inode->i_size < EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) ||
 493             !(bh = ext2_bread (inode, 0, 0, &err))) {
 494                 printk ("warning - bad directory (dev %04x, dir %d)\n",
 495                         inode->i_dev, inode->i_ino);
 496                 return 1;
 497         }
 498         de = (struct ext2_dir_entry *) bh->b_data;
 499         de1 = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
 500         if (de->inode != inode->i_ino || !de1->inode || 
 501             strcmp (".", de->name) || strcmp ("..", de1->name)) {
 502                 printk ("warning - bad directory (dev %04x, dir %d)\n",
 503                         inode->i_dev, inode->i_ino);
 504                 return 1;
 505         }
 506         offset = de->rec_len + de1->rec_len;
 507         de = (struct ext2_dir_entry *) ((char *) de1 + de1->rec_len);
 508         while (offset < inode->i_size ) {
 509                 if ((void *) de >= (void *) (bh->b_data + sb->s_blocksize)) {
 510                         brelse (bh);
 511                         bh = ext2_bread (inode, offset >> EXT2_BLOCK_SIZE_BITS(sb), 1, &err);
 512                         if (!bh) {
 513                                 offset += sb->s_blocksize;
 514                                 continue;
 515                         }
 516                         de = (struct ext2_dir_entry *) bh->b_data;
 517                 }
 518                 if (! ext2_check_dir_entry ("empty_dir", inode, de, bh,
 519                                             offset)) {
 520                         brelse (bh);
 521                         return 1;
 522                 }
 523                 if (de->inode) {
 524                         brelse (bh);
 525                         return 0;
 526                 }
 527                 offset += de->rec_len;
 528                 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
 529         }
 530         brelse (bh);
 531         return 1;
 532 }
 533 
 534 int ext2_rmdir (struct inode * dir, const char * name, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 535 {
 536         int retval;
 537         struct inode * inode;
 538         struct buffer_head * bh;
 539         struct ext2_dir_entry * de;
 540 
 541 repeat:
 542         if (!dir)
 543                 return -ENOENT;
 544         inode = NULL;
 545         bh = ext2_find_entry (dir, name, len, &de);
 546         retval = -ENOENT;
 547         if (!bh)
 548                 goto end_rmdir;
 549         retval = -EPERM;
 550         if (!(inode = iget (dir->i_sb, de->inode)))
 551                 goto end_rmdir;
 552         if (inode->i_dev != dir->i_dev)
 553                 goto end_rmdir;
 554         if (de->inode != inode->i_ino) {
 555                 iput(inode);
 556                 brelse(bh);
 557                 current->counter = 0;
 558                 schedule();
 559                 goto repeat;
 560         }
 561         if ((dir->i_mode & S_ISVTX) && current->euid &&
 562             inode->i_uid != current->euid)
 563                 goto end_rmdir;
 564         if (inode == dir)       /* we may not delete ".", but "../dir" is ok */
 565                 goto end_rmdir;
 566         if (!S_ISDIR(inode->i_mode)) {
 567                 retval = -ENOTDIR;
 568                 goto end_rmdir;
 569         }
 570         if (!empty_dir (inode)) {
 571                 retval = -ENOTEMPTY;
 572                 goto end_rmdir;
 573         }
 574         if (inode->i_count > 1 && inode->i_nlink <= 2) {
 575                 /* Are we deleting the last instance of a busy directory?
 576                    Better clean up if so. */
 577                 /* Make directory empty (it will be truncated when finally
 578                    dereferenced).  This also inhibits ext2_add_entry. */
 579                 inode->i_size = 0;
 580 #ifndef DONT_USE_DCACHE
 581                 ext2_dcache_remove(inode->i_dev, inode->i_ino, ".", 1);
 582                 ext2_dcache_remove(inode->i_dev, inode->i_ino, "..", 2);
 583 #endif
 584         }
 585         if (inode->i_nlink != 2)
 586                 printk ("empty  directory has nlink!=2 (%d)\n", inode->i_nlink);
 587 #ifndef DONT_USE_DCACHE
 588         ext2_dcache_remove (dir->i_dev, dir->i_ino, de->name, de->name_len);
 589 #endif
 590         retval = ext2_delete_entry (de, bh);
 591         if (retval)
 592                 goto end_rmdir;
 593         bh->b_dirt = 1;
 594         inode->i_nlink = 0;
 595         inode->i_dirt = 1;
 596         dir->i_nlink--;
 597         dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 598         dir->i_dirt = 1;
 599 end_rmdir:
 600         iput (dir);
 601         iput (inode);
 602         brelse (bh);
 603         return retval;
 604 }
 605 
 606 int ext2_unlink (struct inode * dir, const char * name, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 607 {
 608         int retval;
 609         struct inode * inode;
 610         struct buffer_head * bh;
 611         struct ext2_dir_entry * de;
 612 
 613 repeat:
 614         if (!dir)
 615                 return -ENOENT;
 616         retval = -ENOENT;
 617         inode = NULL;
 618         bh = ext2_find_entry (dir, name, len, &de);
 619         if (!bh)
 620                 goto end_unlink;
 621         if (!(inode = iget (dir->i_sb, de->inode)))
 622                 goto end_unlink;
 623         retval = -EPERM;
 624         if (S_ISDIR(inode->i_mode))
 625                 goto end_unlink;
 626         if (de->inode != inode->i_ino) {
 627                 iput(inode);
 628                 brelse(bh);
 629                 current->counter = 0;
 630                 schedule();
 631                 goto repeat;
 632         }
 633         if ((dir->i_mode & S_ISVTX) && !suser() &&
 634             current->euid != inode->i_uid &&
 635             current->euid != dir->i_uid)
 636                 goto end_unlink;
 637         if (!inode->i_nlink) {
 638                 printk ("Deleting nonexistent file (%04x:%d), %d\n",
 639                         inode->i_dev, inode->i_ino, inode->i_nlink);
 640                 inode->i_nlink = 1;
 641         }
 642 #ifndef DONT_USE_DCACHE
 643         ext2_dcache_remove (dir->i_dev, dir->i_ino, de->name, de->name_len);
 644 #endif
 645         retval = ext2_delete_entry (de, bh);
 646         if (retval)
 647                 goto end_unlink;
 648         bh->b_dirt = 1;
 649         dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 650         dir->i_dirt = 1;
 651         inode->i_nlink--;
 652         inode->i_dirt = 1;
 653         inode->i_ctime = CURRENT_TIME;
 654         retval = 0;
 655 end_unlink:
 656         brelse (bh);
 657         iput (inode);
 658         iput (dir);
 659         return retval;
 660 }
 661 
 662 int ext2_symlink (struct inode * dir, const char * name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 663                   const char * symname)
 664 {
 665         struct ext2_dir_entry * de;
 666         struct inode * inode = NULL;
 667         struct buffer_head * bh = NULL, * name_block = NULL;
 668         char * link;
 669         int i, err;
 670         int l;
 671         char c;
 672 
 673         if (!(inode = ext2_new_inode (dir, S_IFLNK))) {
 674                 iput (dir);
 675                 return -ENOSPC;
 676         }
 677         inode->i_mode = S_IFLNK | S_IRWXUGO;
 678         inode->i_op = &ext2_symlink_inode_operations;
 679         for (l = 0; l < inode->i_sb->s_blocksize - 1 &&
 680              symname [l]; l++)
 681                 ;
 682         if (l >= EXT2_N_BLOCKS * sizeof (unsigned long)) {
 683 #ifdef EXT2FS_DEBUG
 684                 printk ("ext2_symlink: l=%d, normal symlink\n", l);
 685 #endif
 686                 name_block = ext2_bread (inode, 0, 1, &err);
 687                 if (!name_block) {
 688                         iput (dir);
 689                         inode->i_nlink--;
 690                         inode->i_dirt = 1;
 691                         iput (inode);
 692                         return err;
 693                 }
 694                 link = name_block->b_data;
 695         } else {
 696                 link = (char *) inode->u.ext2_i.i_data;
 697 #ifdef EXT2FS_DEBUG
 698                 printk ("ext2_symlink: l=%d, fast symlink\n", l);
 699 #endif
 700         }
 701         i = 0;
 702         while (i < inode->i_sb->s_blocksize - 1 && (c = *(symname++)))
 703                 link[i++] = c;
 704         link[i] = 0;
 705         if (name_block) {
 706                 name_block->b_dirt = 1;
 707                 brelse (name_block);
 708         }
 709         inode->i_size = i;
 710         inode->i_dirt = 1;
 711         bh = ext2_find_entry (dir, name, len, &de);
 712         if (bh) {
 713                 inode->i_nlink--;
 714                 inode->i_dirt = 1;
 715                 iput (inode);
 716                 brelse (bh);
 717                 iput (dir);
 718                 return -EEXIST;
 719         }
 720         bh = ext2_add_entry (dir, name, len, &de, &err);
 721         if (!bh) {
 722                 inode->i_nlink--;
 723                 inode->i_dirt = 1;
 724                 iput (inode);
 725                 iput (dir);
 726                 return err;
 727         }
 728         de->inode = inode->i_ino;
 729 #ifndef DONT_USE_DCACHE
 730         ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
 731                          de->inode);
 732 #endif
 733         bh->b_dirt = 1;
 734         brelse (bh);
 735         iput (dir);
 736         iput (inode);
 737         return 0;
 738 }
 739 
 740 int ext2_link (struct inode * oldinode, struct inode * dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 741                const char * name, int len)
 742 {
 743         struct ext2_dir_entry * de;
 744         struct buffer_head * bh;
 745         int err;
 746 
 747         if (S_ISDIR(oldinode->i_mode)) {
 748                 iput (oldinode);
 749                 iput (dir);
 750                 return -EPERM;
 751         }
 752         if (oldinode->i_nlink > EXT2_LINK_MAX) {
 753                 iput (oldinode);
 754                 iput (dir);
 755                 return -EMLINK;
 756         }
 757         bh = ext2_find_entry (dir, name, len, &de);
 758         if (bh) {
 759                 brelse (bh);
 760                 iput (dir);
 761                 iput (oldinode);
 762                 return -EEXIST;
 763         }
 764         bh = ext2_add_entry (dir, name, len, &de, &err);
 765         if (!bh) {
 766                 iput (dir);
 767                 iput (oldinode);
 768                 return err;
 769         }
 770         de->inode = oldinode->i_ino;
 771 #ifndef DONT_USE_DCACHE
 772         ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
 773                          de->inode);
 774 #endif
 775         bh->b_dirt = 1;
 776         brelse (bh);
 777         iput (dir);
 778         oldinode->i_nlink++;
 779         oldinode->i_ctime = CURRENT_TIME;
 780         oldinode->i_dirt = 1;
 781         iput (oldinode);
 782         return 0;
 783 }
 784 
 785 static int subdir (struct inode * new_inode, struct inode * old_inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 786 {
 787         int ino;
 788         int result;
 789 
 790         new_inode->i_count++;
 791         result = 0;
 792         for (;;) {
 793                 if (new_inode == old_inode) {
 794                         result = 1;
 795                         break;
 796                 }
 797                 if (new_inode->i_dev != old_inode->i_dev)
 798                         break;
 799                 ino = new_inode->i_ino;
 800                 if (ext2_lookup (new_inode, "..", 2, &new_inode))
 801                         break;
 802                 if (new_inode->i_ino == ino)
 803                         break;
 804         }
 805         iput (new_inode);
 806         return result;
 807 }
 808 
 809 #define PARENT_INO(buffer) \
 810         ((struct ext2_dir_entry *) ((char *) buffer + \
 811         ((struct ext2_dir_entry *) buffer)->rec_len))->inode
 812 
 813 #define PARENT_NAME(buffer) \
 814         ((struct ext2_dir_entry *) ((char *) buffer + \
 815         ((struct ext2_dir_entry *) buffer)->rec_len))->name
 816 
 817 /*
 818  * rename uses retrying to avoid race-conditions: at least they should be
 819  * minimal.
 820  * it tries to allocate all the blocks, then sanity-checks, and if the sanity-
 821  * checks fail, it tries to restart itself again. Very practical - no changes
 822  * are done until we know everything works ok.. and then all the changes can be
 823  * done in one fell swoop when we have claimed all the buffers needed.
 824  *
 825  * Anybody can rename anything with this: the permission checks are left to the
 826  * higher-level routines.
 827  */
 828 static int do_ext2_rename (struct inode * old_dir, const char * old_name,
     /* [previous][next][first][last][top][bottom][index][help] */
 829                            int old_len, struct inode * new_dir,
 830                            const char * new_name, int new_len)
 831 {
 832         struct inode * old_inode, * new_inode;
 833         struct buffer_head * old_bh, * new_bh, * dir_bh;
 834         struct ext2_dir_entry * old_de, * new_de;
 835         int retval;
 836 
 837         goto start_up;
 838 try_again:
 839         if (new_bh && new_de)
 840                 ext2_delete_entry(new_de, new_bh);
 841         brelse (old_bh);
 842         brelse (new_bh);
 843         brelse (dir_bh);
 844         iput (old_inode);
 845         iput (new_inode);
 846         current->counter = 0;
 847         schedule ();
 848 start_up:
 849         old_inode = new_inode = NULL;
 850         old_bh = new_bh = dir_bh = NULL;
 851         new_de = NULL;
 852         old_bh = ext2_find_entry (old_dir, old_name, old_len, &old_de);
 853         retval = -ENOENT;
 854         if (!old_bh)
 855                 goto end_rename;
 856         old_inode = __iget (old_dir->i_sb, old_de->inode, 0); /* don't cross mnt-points */
 857         if (!old_inode)
 858                 goto end_rename;
 859         retval = -EPERM;
 860         if ((old_dir->i_mode & S_ISVTX) && 
 861             current->euid != old_inode->i_uid &&
 862             current->euid != old_dir->i_uid && !suser())
 863                 goto end_rename;
 864         new_bh = ext2_find_entry (new_dir, new_name, new_len, &new_de);
 865         if (new_bh) {
 866                 new_inode = __iget (new_dir->i_sb, new_de->inode, 0); /* no mntp cross */
 867                 if (!new_inode) {
 868                         brelse (new_bh);
 869                         new_bh = NULL;
 870                 }
 871         }
 872         if (new_inode == old_inode) {
 873                 retval = 0;
 874                 goto end_rename;
 875         }
 876         if (new_inode && S_ISDIR(new_inode->i_mode)) {
 877                 retval = -EISDIR;
 878                 if (!S_ISDIR(old_inode->i_mode))
 879                         goto end_rename;
 880                 retval = -EINVAL;
 881                 if (subdir (new_dir, old_inode))
 882                         goto end_rename;
 883                 retval = -ENOTEMPTY;
 884                 if (!empty_dir (new_inode))
 885                         goto end_rename;
 886                 retval = -EBUSY;
 887                 if (new_inode->i_count > 1)
 888                         goto end_rename;
 889         }
 890         retval = -EPERM;
 891         if (new_inode && (new_dir->i_mode & S_ISVTX) &&
 892             current->euid != new_inode->i_uid &&
 893             current->euid != new_dir->i_uid && !suser())
 894                 goto end_rename;
 895         if (S_ISDIR(old_inode->i_mode)) {
 896                 retval = -ENOTDIR;
 897                 if (new_inode && !S_ISDIR(new_inode->i_mode))
 898                         goto end_rename;
 899                 retval = -EINVAL;
 900                 if (subdir (new_dir, old_inode))
 901                         goto end_rename;
 902                 dir_bh = ext2_bread (old_inode, 0, 0, &retval);
 903                 if (!dir_bh)
 904                         goto end_rename;
 905                 if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
 906                         goto end_rename;
 907                 retval = -EMLINK;
 908                 if (!new_inode && new_dir->i_nlink >= EXT2_LINK_MAX)
 909                         goto end_rename;
 910         }
 911         if (!new_bh)
 912                 new_bh = ext2_add_entry (new_dir, new_name, new_len, &new_de,
 913                                          &retval);
 914         if (!new_bh)
 915                 goto end_rename;
 916 /* sanity checking before doing the rename - avoid races */
 917         if (new_inode && (new_de->inode != new_inode->i_ino))
 918                 goto try_again;
 919         if (new_de->inode && !new_inode)
 920                 goto try_again;
 921         if (old_de->inode != old_inode->i_ino)
 922                 goto try_again;
 923 /* ok, that's it */
 924         new_de->inode = old_inode->i_ino;
 925 #ifndef DONT_USE_DCACHE
 926         ext2_dcache_remove (old_dir->i_dev, old_dir->i_ino, old_de->name,
 927                             old_de->name_len);
 928         ext2_dcache_add (new_dir->i_dev, new_dir->i_ino, new_de->name,
 929                          new_de->name_len, new_de->inode);
 930 #endif
 931         retval = ext2_delete_entry (old_de, old_bh);
 932         if (retval == -ENOENT)
 933                 goto try_again;
 934         if (retval)
 935                 goto end_rename;
 936         if (new_inode) {
 937                 new_inode->i_nlink--;
 938                 new_inode->i_dirt = 1;
 939         }
 940         old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
 941         old_dir->i_dirt = 1;
 942         old_bh->b_dirt = 1;
 943         new_bh->b_dirt = 1;
 944         if (dir_bh) {
 945                 PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
 946                 dir_bh->b_dirt = 1;
 947                 old_dir->i_nlink--;
 948                 new_dir->i_nlink++;
 949                 old_dir->i_dirt = 1;
 950                 new_dir->i_dirt = 1;
 951         }
 952         retval = 0;
 953 end_rename:
 954         brelse (dir_bh);
 955         brelse (old_bh);
 956         brelse (new_bh);
 957         iput (old_inode);
 958         iput (new_inode);
 959         iput (old_dir);
 960         iput (new_dir);
 961         return retval;
 962 }
 963 
 964 /*
 965  * Ok, rename also locks out other renames, as they can change the parent of
 966  * a directory, and we don't want any races. Other races are checked for by
 967  * "do_rename()", which restarts if there are inconsistencies.
 968  *
 969  * Note that there is no race between different filesystems: it's only within
 970  * the same device that races occur: many renames can happen at once, as long
 971  * as they are on different partitions.
 972  *
 973  * In the second extended file system, we use a lock flag stored in the memory
 974  * super-block.  This way, we really lock other renames only if they occur
 975  * on the same file system
 976  */
 977 int ext2_rename (struct inode * old_dir, const char * old_name, int old_len,
     /* [previous][next][first][last][top][bottom][index][help] */
 978                  struct inode * new_dir, const char * new_name, int new_len)
 979 {
 980         int result;
 981 
 982         while (old_dir->i_sb->u.ext2_sb.s_rename_lock)
 983                 sleep_on (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
 984         old_dir->i_sb->u.ext2_sb.s_rename_lock = 1;
 985         result = do_ext2_rename (old_dir, old_name, old_len, new_dir,
 986                                  new_name, new_len);
 987         old_dir->i_sb->u.ext2_sb.s_rename_lock = 0;
 988         wake_up (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
 989         return result;
 990 }

/* [previous][next][first][last][top][bottom][index][help] */