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

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