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

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