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                         } else {
 279 
 280                                 ext2_debug ("skipping to next block\n");
 281 
 282                                 de = (struct ext2_dir_entry *) bh->b_data;
 283                         }
 284                 }
 285                 if (!ext2_check_dir_entry ("ext2_add_entry", dir, de, bh,
 286                                            offset)) {
 287                         *err = -ENOENT;
 288                         brelse (bh);
 289                         return NULL;
 290                 }
 291                 if (de->inode != 0 && ext2_match (namelen, name, de)) {
 292                                 *err = -EEXIST;
 293                                 brelse (bh);
 294                                 return NULL;
 295                 }
 296                 if ((de->inode == 0 && de->rec_len >= rec_len) ||
 297                     (de->rec_len >= EXT2_DIR_REC_LEN(de->name_len) + rec_len)) {
 298                         offset += de->rec_len;
 299                         if (de->inode) {
 300                                 de1 = (struct ext2_dir_entry *) ((char *) de +
 301                                         EXT2_DIR_REC_LEN(de->name_len));
 302                                 de1->rec_len = de->rec_len -
 303                                         EXT2_DIR_REC_LEN(de->name_len);
 304                                 de->rec_len = EXT2_DIR_REC_LEN(de->name_len);
 305                                 de = de1;
 306                         }
 307                         de->inode = 0;
 308                         de->name_len = namelen;
 309                         memcpy (de->name, name, namelen);
 310                         /*
 311                          * XXX shouldn't update any times until successful
 312                          * completion of syscall, but too many callers depend
 313                          * on this.
 314                          *
 315                          * XXX similarly, too many callers depend on
 316                          * ext2_new_inode() setting the times, but error
 317                          * recovery deletes the inode, so the worst that can
 318                          * happen is that the times are slightly out of date
 319                          * and/or different from the directory change time.
 320                          */
 321                         dir->i_mtime = dir->i_ctime = CURRENT_TIME;
 322                         dir->i_dirt = 1;
 323                         mark_buffer_dirty(bh, 1);
 324                         *res_dir = de;
 325                         *err = 0;
 326                         return bh;
 327                 }
 328                 offset += de->rec_len;
 329                 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
 330         }
 331         brelse (bh);
 332         return NULL;
 333 }
 334 
 335 /*
 336  * ext2_delete_entry deletes a directory entry by merging it with the
 337  * previous entry
 338  */
 339 static int ext2_delete_entry (struct ext2_dir_entry * dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 340                               struct buffer_head * bh)
 341 {
 342         struct ext2_dir_entry * de, * pde;
 343         int i;
 344 
 345         i = 0;
 346         pde = NULL;
 347         de = (struct ext2_dir_entry *) bh->b_data;
 348         while (i < bh->b_size) {
 349                 if (!ext2_check_dir_entry ("ext2_delete_entry", NULL, 
 350                                            de, bh, i))
 351                         return -EIO;
 352                 if (de == dir)  {
 353                         if (pde)
 354                                 pde->rec_len += dir->rec_len;
 355                         dir->inode = 0;
 356                         return 0;
 357                 }
 358                 i += de->rec_len;
 359                 pde = de;
 360                 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
 361         }
 362         return -ENOENT;
 363 }
 364 
 365 int ext2_create (struct inode * dir,const char * name, int len, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
 366                  struct inode ** result)
 367 {
 368         struct inode * inode;
 369         struct buffer_head * bh;
 370         struct ext2_dir_entry * de;
 371         int err;
 372 
 373         *result = NULL;
 374         if (!dir)
 375                 return -ENOENT;
 376         inode = ext2_new_inode (dir, mode);
 377         if (!inode) {
 378                 iput (dir);
 379                 return -ENOSPC;
 380         }
 381         inode->i_op = &ext2_file_inode_operations;
 382         inode->i_mode = mode;
 383         inode->i_dirt = 1;
 384         bh = ext2_add_entry (dir, name, len, &de, &err);
 385         if (!bh) {
 386                 inode->i_nlink--;
 387                 inode->i_dirt = 1;
 388                 iput (inode);
 389                 iput (dir);
 390                 return err;
 391         }
 392         de->inode = inode->i_ino;
 393         dir->i_version++;
 394 #ifndef DONT_USE_DCACHE
 395         ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
 396                          de->inode);
 397 #endif
 398         mark_buffer_dirty(bh, 1);
 399         if (IS_SYNC(dir)) {
 400                 ll_rw_block (WRITE, 1, &bh);
 401                 wait_on_buffer (bh);
 402         }
 403         brelse (bh);
 404         iput (dir);
 405         *result = inode;
 406         return 0;
 407 }
 408 
 409 int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
 410                 int rdev)
 411 {
 412         struct inode * inode;
 413         struct buffer_head * bh;
 414         struct ext2_dir_entry * de;
 415         int err;
 416 
 417         if (!dir)
 418                 return -ENOENT;
 419         bh = ext2_find_entry (dir, name, len, &de);
 420         if (bh) {
 421                 brelse (bh);
 422                 iput (dir);
 423                 return -EEXIST;
 424         }
 425         inode = ext2_new_inode (dir, mode);
 426         if (!inode) {
 427                 iput (dir);
 428                 return -ENOSPC;
 429         }
 430         inode->i_uid = current->euid;
 431         inode->i_mode = mode;
 432         inode->i_op = NULL;
 433         if (S_ISREG(inode->i_mode))
 434                 inode->i_op = &ext2_file_inode_operations;
 435         else if (S_ISDIR(inode->i_mode)) {
 436                 inode->i_op = &ext2_dir_inode_operations;
 437                 if (dir->i_mode & S_ISGID)
 438                         inode->i_mode |= S_ISGID;
 439         }
 440         else if (S_ISLNK(inode->i_mode))
 441                 inode->i_op = &ext2_symlink_inode_operations;
 442         else if (S_ISCHR(inode->i_mode))
 443                 inode->i_op = &chrdev_inode_operations;
 444         else if (S_ISBLK(inode->i_mode))
 445                 inode->i_op = &blkdev_inode_operations;
 446         else if (S_ISFIFO(inode->i_mode)) 
 447                 init_fifo(inode);
 448         if (S_ISBLK(mode) || S_ISCHR(mode))
 449                 inode->i_rdev = rdev;
 450         inode->i_dirt = 1;
 451         bh = ext2_add_entry (dir, name, len, &de, &err);
 452         if (!bh) {
 453                 inode->i_nlink--;
 454                 inode->i_dirt = 1;
 455                 iput (inode);
 456                 iput (dir);
 457                 return err;
 458         }
 459         de->inode = inode->i_ino;
 460         dir->i_version++;
 461 #ifndef DONT_USE_DCACHE
 462         ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
 463                          de->inode);
 464 #endif
 465         mark_buffer_dirty(bh, 1);
 466         if (IS_SYNC(dir)) {
 467                 ll_rw_block (WRITE, 1, &bh);
 468                 wait_on_buffer (bh);
 469         }
 470         brelse (bh);
 471         iput (dir);
 472         iput (inode);
 473         return 0;
 474 }
 475 
 476 int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 477 {
 478         struct inode * inode;
 479         struct buffer_head * bh, * dir_block;
 480         struct ext2_dir_entry * de;
 481         int err;
 482 
 483         if (!dir)
 484                 return -ENOENT;
 485         bh = ext2_find_entry (dir, name, len, &de);
 486         if (bh) {
 487                 brelse (bh);
 488                 iput (dir);
 489                 return -EEXIST;
 490         }
 491         if (dir->i_nlink >= EXT2_LINK_MAX) {
 492                 iput (dir);
 493                 return -EMLINK;
 494         }
 495         inode = ext2_new_inode (dir, S_IFDIR);
 496         if (!inode) {
 497                 iput (dir);
 498                 return -ENOSPC;
 499         }
 500         inode->i_op = &ext2_dir_inode_operations;
 501         inode->i_size = inode->i_sb->s_blocksize;
 502         dir_block = ext2_bread (inode, 0, 1, &err);
 503         if (!dir_block) {
 504                 iput (dir);
 505                 inode->i_nlink--;
 506                 inode->i_dirt = 1;
 507                 iput (inode);
 508                 return err;
 509         }
 510         inode->i_blocks = inode->i_sb->s_blocksize / 512;
 511         de = (struct ext2_dir_entry *) dir_block->b_data;
 512         de->inode = inode->i_ino;
 513         de->name_len = 1;
 514         de->rec_len = EXT2_DIR_REC_LEN(de->name_len);
 515         strcpy (de->name, ".");
 516         de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
 517         de->inode = dir->i_ino;
 518         de->rec_len = inode->i_sb->s_blocksize - EXT2_DIR_REC_LEN(1);
 519         de->name_len = 2;
 520         strcpy (de->name, "..");
 521         inode->i_nlink = 2;
 522         mark_buffer_dirty(dir_block, 1);
 523         brelse (dir_block);
 524         inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->fs->umask);
 525         if (dir->i_mode & S_ISGID)
 526                 inode->i_mode |= S_ISGID;
 527         inode->i_dirt = 1;
 528         bh = ext2_add_entry (dir, name, len, &de, &err);
 529         if (!bh) {
 530                 iput (dir);
 531                 inode->i_nlink = 0;
 532                 inode->i_dirt = 1;
 533                 iput (inode);
 534                 return err;
 535         }
 536         de->inode = inode->i_ino;
 537         dir->i_version++;
 538 #ifndef DONT_USE_DCACHE
 539         ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
 540                          de->inode);
 541 #endif
 542         mark_buffer_dirty(bh, 1);
 543         if (IS_SYNC(dir)) {
 544                 ll_rw_block (WRITE, 1, &bh);
 545                 wait_on_buffer (bh);
 546         }
 547         dir->i_nlink++;
 548         dir->i_dirt = 1;
 549         iput (dir);
 550         iput (inode);
 551         brelse (bh);
 552         return 0;
 553 }
 554 
 555 /*
 556  * routine to check that the specified directory is empty (for rmdir)
 557  */
 558 static int empty_dir (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 559 {
 560         unsigned long offset;
 561         struct buffer_head * bh;
 562         struct ext2_dir_entry * de, * de1;
 563         struct super_block * sb;
 564         int err;
 565 
 566         sb = inode->i_sb;
 567         if (inode->i_size < EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) ||
 568             !(bh = ext2_bread (inode, 0, 0, &err))) {
 569                 ext2_warning (inode->i_sb, "empty_dir",
 570                               "bad directory (dir %lu)", inode->i_ino);
 571                 return 1;
 572         }
 573         de = (struct ext2_dir_entry *) bh->b_data;
 574         de1 = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
 575         if (de->inode != inode->i_ino || !de1->inode || 
 576             strcmp (".", de->name) || strcmp ("..", de1->name)) {
 577                 ext2_warning (inode->i_sb, "empty_dir",
 578                               "bad directory (dir %lu)", inode->i_ino);
 579                 return 1;
 580         }
 581         offset = de->rec_len + de1->rec_len;
 582         de = (struct ext2_dir_entry *) ((char *) de1 + de1->rec_len);
 583         while (offset < inode->i_size ) {
 584                 if ((void *) de >= (void *) (bh->b_data + sb->s_blocksize)) {
 585                         brelse (bh);
 586                         bh = ext2_bread (inode, offset >> EXT2_BLOCK_SIZE_BITS(sb), 1, &err);
 587                         if (!bh) {
 588                                 offset += sb->s_blocksize;
 589                                 continue;
 590                         }
 591                         de = (struct ext2_dir_entry *) bh->b_data;
 592                 }
 593                 if (!ext2_check_dir_entry ("empty_dir", inode, de, bh,
 594                                            offset)) {
 595                         brelse (bh);
 596                         return 1;
 597                 }
 598                 if (de->inode) {
 599                         brelse (bh);
 600                         return 0;
 601                 }
 602                 offset += de->rec_len;
 603                 de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
 604         }
 605         brelse (bh);
 606         return 1;
 607 }
 608 
 609 int ext2_rmdir (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         inode = NULL;
 620         bh = ext2_find_entry (dir, name, len, &de);
 621         retval = -ENOENT;
 622         if (!bh)
 623                 goto end_rmdir;
 624         retval = -EPERM;
 625         if (!(inode = iget (dir->i_sb, de->inode)))
 626                 goto end_rmdir;
 627         if (inode->i_dev != dir->i_dev)
 628                 goto end_rmdir;
 629         if (de->inode != inode->i_ino) {
 630                 iput(inode);
 631                 brelse(bh);
 632                 current->counter = 0;
 633                 schedule();
 634                 goto repeat;
 635         }
 636         if ((dir->i_mode & S_ISVTX) && !suser() &&
 637             current->euid != inode->i_uid &&
 638             current->euid != dir->i_uid)
 639                 goto end_rmdir;
 640         if (inode == dir)       /* we may not delete ".", but "../dir" is ok */
 641                 goto end_rmdir;
 642         if (!S_ISDIR(inode->i_mode)) {
 643                 retval = -ENOTDIR;
 644                 goto end_rmdir;
 645         }
 646         down(&inode->i_sem);
 647         if (!empty_dir (inode))
 648                 retval = -ENOTEMPTY;
 649         else if (de->inode != inode->i_ino)
 650                 retval = -ENOENT;
 651         else {
 652                 if (inode->i_count > 1) {
 653                 /*
 654                  * Are we deleting the last instance of a busy directory?
 655                  * Better clean up if so.
 656                  *
 657                  * Make directory empty (it will be truncated when finally
 658                  * dereferenced).  This also inhibits ext2_add_entry.
 659                  */
 660                         inode->i_size = 0;
 661                 }
 662                 retval = ext2_delete_entry (de, bh);
 663                 dir->i_version++;
 664         }
 665         up(&inode->i_sem);
 666         if (retval)
 667                 goto end_rmdir;
 668         mark_buffer_dirty(bh, 1);
 669         if (IS_SYNC(dir)) {
 670                 ll_rw_block (WRITE, 1, &bh);
 671                 wait_on_buffer (bh);
 672         }
 673 #ifndef DONT_USE_DCACHE
 674         ext2_dcache_remove(inode->i_dev, inode->i_ino, ".", 1);
 675         ext2_dcache_remove(inode->i_dev, inode->i_ino, "..", 2);
 676 #endif
 677         if (inode->i_nlink != 2)
 678                 ext2_warning (inode->i_sb, "ext2_rmdir",
 679                               "empty directory has nlink!=2 (%d)",
 680                               inode->i_nlink);
 681 #ifndef DONT_USE_DCACHE
 682         ext2_dcache_remove (dir->i_dev, dir->i_ino, de->name, de->name_len);
 683 #endif
 684         inode->i_nlink = 0;
 685         inode->i_dirt = 1;
 686         dir->i_nlink--;
 687         inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 688         dir->i_dirt = 1;
 689 end_rmdir:
 690         iput (dir);
 691         iput (inode);
 692         brelse (bh);
 693         return retval;
 694 }
 695 
 696 int ext2_unlink (struct inode * dir, const char * name, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 697 {
 698         int retval;
 699         struct inode * inode;
 700         struct buffer_head * bh;
 701         struct ext2_dir_entry * de;
 702 
 703 repeat:
 704         if (!dir)
 705                 return -ENOENT;
 706         retval = -ENOENT;
 707         inode = NULL;
 708         bh = ext2_find_entry (dir, name, len, &de);
 709         if (!bh)
 710                 goto end_unlink;
 711         if (!(inode = iget (dir->i_sb, de->inode)))
 712                 goto end_unlink;
 713         retval = -EPERM;
 714         if (S_ISDIR(inode->i_mode))
 715                 goto end_unlink;
 716         if (de->inode != inode->i_ino) {
 717                 iput(inode);
 718                 brelse(bh);
 719                 current->counter = 0;
 720                 schedule();
 721                 goto repeat;
 722         }
 723         if ((dir->i_mode & S_ISVTX) && !suser() &&
 724             current->euid != inode->i_uid &&
 725             current->euid != dir->i_uid)
 726                 goto end_unlink;
 727         if (!inode->i_nlink) {
 728                 ext2_warning (inode->i_sb, "ext2_unlink",
 729                               "Deleting nonexistent file (%lu), %d",
 730                               inode->i_ino, inode->i_nlink);
 731                 inode->i_nlink = 1;
 732         }
 733         retval = ext2_delete_entry (de, bh);
 734         if (retval)
 735                 goto end_unlink;
 736         dir->i_version++;
 737         mark_buffer_dirty(bh, 1);
 738         if (IS_SYNC(dir)) {
 739                 ll_rw_block (WRITE, 1, &bh);
 740                 wait_on_buffer (bh);
 741         }
 742 #ifndef DONT_USE_DCACHE
 743         ext2_dcache_remove (dir->i_dev, dir->i_ino, de->name, de->name_len);
 744 #endif
 745         dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 746         dir->i_dirt = 1;
 747         inode->i_nlink--;
 748         inode->i_dirt = 1;
 749         inode->i_ctime = dir->i_ctime;
 750         retval = 0;
 751 end_unlink:
 752         brelse (bh);
 753         iput (inode);
 754         iput (dir);
 755         return retval;
 756 }
 757 
 758 int ext2_symlink (struct inode * dir, const char * name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 759                   const char * symname)
 760 {
 761         struct ext2_dir_entry * de;
 762         struct inode * inode = NULL;
 763         struct buffer_head * bh = NULL, * name_block = NULL;
 764         char * link;
 765         int i, err;
 766         int l;
 767         char c;
 768 
 769         if (!(inode = ext2_new_inode (dir, S_IFLNK))) {
 770                 iput (dir);
 771                 return -ENOSPC;
 772         }
 773         inode->i_mode = S_IFLNK | S_IRWXUGO;
 774         inode->i_op = &ext2_symlink_inode_operations;
 775         for (l = 0; l < inode->i_sb->s_blocksize - 1 &&
 776              symname [l]; l++)
 777                 ;
 778         if (l >= EXT2_N_BLOCKS * sizeof (unsigned long)) {
 779 
 780                 ext2_debug ("l=%d, normal symlink\n", l);
 781 
 782                 name_block = ext2_bread (inode, 0, 1, &err);
 783                 if (!name_block) {
 784                         iput (dir);
 785                         inode->i_nlink--;
 786                         inode->i_dirt = 1;
 787                         iput (inode);
 788                         return err;
 789                 }
 790                 link = name_block->b_data;
 791         } else {
 792                 link = (char *) inode->u.ext2_i.i_data;
 793 
 794                 ext2_debug ("l=%d, fast symlink\n", l);
 795 
 796         }
 797         i = 0;
 798         while (i < inode->i_sb->s_blocksize - 1 && (c = *(symname++)))
 799                 link[i++] = c;
 800         link[i] = 0;
 801         if (name_block) {
 802                 mark_buffer_dirty(name_block, 1);
 803                 brelse (name_block);
 804         }
 805         inode->i_size = i;
 806         inode->i_dirt = 1;
 807         bh = ext2_find_entry (dir, name, len, &de);
 808         if (bh) {
 809                 inode->i_nlink--;
 810                 inode->i_dirt = 1;
 811                 iput (inode);
 812                 brelse (bh);
 813                 iput (dir);
 814                 return -EEXIST;
 815         }
 816         bh = ext2_add_entry (dir, name, len, &de, &err);
 817         if (!bh) {
 818                 inode->i_nlink--;
 819                 inode->i_dirt = 1;
 820                 iput (inode);
 821                 iput (dir);
 822                 return err;
 823         }
 824         de->inode = inode->i_ino;
 825         dir->i_version++;
 826 #ifndef DONT_USE_DCACHE
 827         ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
 828                          de->inode);
 829 #endif
 830         mark_buffer_dirty(bh, 1);
 831         if (IS_SYNC(dir)) {
 832                 ll_rw_block (WRITE, 1, &bh);
 833                 wait_on_buffer (bh);
 834         }
 835         brelse (bh);
 836         iput (dir);
 837         iput (inode);
 838         return 0;
 839 }
 840 
 841 int ext2_link (struct inode * oldinode, struct inode * dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 842                const char * name, int len)
 843 {
 844         struct ext2_dir_entry * de;
 845         struct buffer_head * bh;
 846         int err;
 847 
 848         if (S_ISDIR(oldinode->i_mode)) {
 849                 iput (oldinode);
 850                 iput (dir);
 851                 return -EPERM;
 852         }
 853         if (oldinode->i_nlink >= EXT2_LINK_MAX) {
 854                 iput (oldinode);
 855                 iput (dir);
 856                 return -EMLINK;
 857         }
 858         bh = ext2_find_entry (dir, name, len, &de);
 859         if (bh) {
 860                 brelse (bh);
 861                 iput (dir);
 862                 iput (oldinode);
 863                 return -EEXIST;
 864         }
 865         bh = ext2_add_entry (dir, name, len, &de, &err);
 866         if (!bh) {
 867                 iput (dir);
 868                 iput (oldinode);
 869                 return err;
 870         }
 871         de->inode = oldinode->i_ino;
 872         dir->i_version++;
 873 #ifndef DONT_USE_DCACHE
 874         ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
 875                          de->inode);
 876 #endif
 877         mark_buffer_dirty(bh, 1);
 878         if (IS_SYNC(dir)) {
 879                 ll_rw_block (WRITE, 1, &bh);
 880                 wait_on_buffer (bh);
 881         }
 882         brelse (bh);
 883         iput (dir);
 884         oldinode->i_nlink++;
 885         oldinode->i_ctime = CURRENT_TIME;
 886         oldinode->i_dirt = 1;
 887         iput (oldinode);
 888         return 0;
 889 }
 890 
 891 static int subdir (struct inode * new_inode, struct inode * old_inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 892 {
 893         int ino;
 894         int result;
 895 
 896         new_inode->i_count++;
 897         result = 0;
 898         for (;;) {
 899                 if (new_inode == old_inode) {
 900                         result = 1;
 901                         break;
 902                 }
 903                 if (new_inode->i_dev != old_inode->i_dev)
 904                         break;
 905                 ino = new_inode->i_ino;
 906                 if (ext2_lookup (new_inode, "..", 2, &new_inode))
 907                         break;
 908                 if (new_inode->i_ino == ino)
 909                         break;
 910         }
 911         iput (new_inode);
 912         return result;
 913 }
 914 
 915 #define PARENT_INO(buffer) \
 916         ((struct ext2_dir_entry *) ((char *) buffer + \
 917         ((struct ext2_dir_entry *) buffer)->rec_len))->inode
 918 
 919 #define PARENT_NAME(buffer) \
 920         ((struct ext2_dir_entry *) ((char *) buffer + \
 921         ((struct ext2_dir_entry *) buffer)->rec_len))->name
 922 
 923 /*
 924  * rename uses retrying to avoid race-conditions: at least they should be
 925  * minimal.
 926  * it tries to allocate all the blocks, then sanity-checks, and if the sanity-
 927  * checks fail, it tries to restart itself again. Very practical - no changes
 928  * are done until we know everything works ok.. and then all the changes can be
 929  * done in one fell swoop when we have claimed all the buffers needed.
 930  *
 931  * Anybody can rename anything with this: the permission checks are left to the
 932  * higher-level routines.
 933  */
 934 static int do_ext2_rename (struct inode * old_dir, const char * old_name,
     /* [previous][next][first][last][top][bottom][index][help] */
 935                            int old_len, struct inode * new_dir,
 936                            const char * new_name, int new_len)
 937 {
 938         struct inode * old_inode, * new_inode;
 939         struct buffer_head * old_bh, * new_bh, * dir_bh;
 940         struct ext2_dir_entry * old_de, * new_de;
 941         int retval;
 942 
 943         goto start_up;
 944 try_again:
 945         if (new_bh && new_de)
 946                 ext2_delete_entry(new_de, new_bh);
 947         brelse (old_bh);
 948         brelse (new_bh);
 949         brelse (dir_bh);
 950         iput (old_inode);
 951         iput (new_inode);
 952         current->counter = 0;
 953         schedule ();
 954 start_up:
 955         old_inode = new_inode = NULL;
 956         old_bh = new_bh = dir_bh = NULL;
 957         new_de = NULL;
 958         old_bh = ext2_find_entry (old_dir, old_name, old_len, &old_de);
 959         retval = -ENOENT;
 960         if (!old_bh)
 961                 goto end_rename;
 962         old_inode = __iget (old_dir->i_sb, old_de->inode, 0); /* don't cross mnt-points */
 963         if (!old_inode)
 964                 goto end_rename;
 965         retval = -EPERM;
 966         if ((old_dir->i_mode & S_ISVTX) && 
 967             current->euid != old_inode->i_uid &&
 968             current->euid != old_dir->i_uid && !suser())
 969                 goto end_rename;
 970         new_bh = ext2_find_entry (new_dir, new_name, new_len, &new_de);
 971         if (new_bh) {
 972                 new_inode = __iget (new_dir->i_sb, new_de->inode, 0); /* no mntp cross */
 973                 if (!new_inode) {
 974                         brelse (new_bh);
 975                         new_bh = NULL;
 976                 }
 977         }
 978         if (new_inode == old_inode) {
 979                 retval = 0;
 980                 goto end_rename;
 981         }
 982         if (new_inode && S_ISDIR(new_inode->i_mode)) {
 983                 retval = -EISDIR;
 984                 if (!S_ISDIR(old_inode->i_mode))
 985                         goto end_rename;
 986                 retval = -EINVAL;
 987                 if (subdir (new_dir, old_inode))
 988                         goto end_rename;
 989                 retval = -ENOTEMPTY;
 990                 if (!empty_dir (new_inode))
 991                         goto end_rename;
 992                 retval = -EBUSY;
 993                 if (new_inode->i_count > 1)
 994                         goto end_rename;
 995         }
 996         retval = -EPERM;
 997         if (new_inode && (new_dir->i_mode & S_ISVTX) &&
 998             current->euid != new_inode->i_uid &&
 999             current->euid != new_dir->i_uid && !suser())
1000                 goto end_rename;
1001         if (S_ISDIR(old_inode->i_mode)) {
1002                 retval = -ENOTDIR;
1003                 if (new_inode && !S_ISDIR(new_inode->i_mode))
1004                         goto end_rename;
1005                 retval = -EINVAL;
1006                 if (subdir (new_dir, old_inode))
1007                         goto end_rename;
1008                 dir_bh = ext2_bread (old_inode, 0, 0, &retval);
1009                 if (!dir_bh)
1010                         goto end_rename;
1011                 if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
1012                         goto end_rename;
1013                 retval = -EMLINK;
1014                 if (!new_inode && new_dir->i_nlink >= EXT2_LINK_MAX)
1015                         goto end_rename;
1016         }
1017         if (!new_bh)
1018                 new_bh = ext2_add_entry (new_dir, new_name, new_len, &new_de,
1019                                          &retval);
1020         if (!new_bh)
1021                 goto end_rename;
1022         /*
1023          * sanity checking before doing the rename - avoid races
1024          */
1025         if (new_inode && (new_de->inode != new_inode->i_ino))
1026                 goto try_again;
1027         if (new_de->inode && !new_inode)
1028                 goto try_again;
1029         if (old_de->inode != old_inode->i_ino)
1030                 goto try_again;
1031         /*
1032          * ok, that's it
1033          */
1034         new_de->inode = old_inode->i_ino;
1035 #ifndef DONT_USE_DCACHE
1036         ext2_dcache_remove (old_dir->i_dev, old_dir->i_ino, old_de->name,
1037                             old_de->name_len);
1038         ext2_dcache_add (new_dir->i_dev, new_dir->i_ino, new_de->name,
1039                          new_de->name_len, new_de->inode);
1040 #endif
1041         retval = ext2_delete_entry (old_de, old_bh);
1042         if (retval == -ENOENT)
1043                 goto try_again;
1044         if (retval)
1045                 goto end_rename;
1046         new_dir->i_version++;
1047         old_dir->i_version++;
1048         if (new_inode) {
1049                 new_inode->i_nlink--;
1050                 new_inode->i_ctime = CURRENT_TIME;
1051                 new_inode->i_dirt = 1;
1052         }
1053         old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
1054         old_dir->i_dirt = 1;
1055         if (dir_bh) {
1056                 PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
1057                 mark_buffer_dirty(dir_bh, 1);
1058                 old_dir->i_nlink--;
1059                 old_dir->i_dirt = 1;
1060                 if (new_inode) {
1061                         new_inode->i_nlink--;
1062                         new_inode->i_dirt = 1;
1063                 } else {
1064                         new_dir->i_nlink++;
1065                         new_dir->i_dirt = 1;
1066                 }
1067         }
1068         mark_buffer_dirty(old_bh,  1);
1069         if (IS_SYNC(old_dir)) {
1070                 ll_rw_block (WRITE, 1, &old_bh);
1071                 wait_on_buffer (old_bh);
1072         }
1073         mark_buffer_dirty(new_bh, 1);
1074         if (IS_SYNC(new_dir)) {
1075                 ll_rw_block (WRITE, 1, &new_bh);
1076                 wait_on_buffer (new_bh);
1077         }
1078         retval = 0;
1079 end_rename:
1080         brelse (dir_bh);
1081         brelse (old_bh);
1082         brelse (new_bh);
1083         iput (old_inode);
1084         iput (new_inode);
1085         iput (old_dir);
1086         iput (new_dir);
1087         return retval;
1088 }
1089 
1090 /*
1091  * Ok, rename also locks out other renames, as they can change the parent of
1092  * a directory, and we don't want any races. Other races are checked for by
1093  * "do_rename()", which restarts if there are inconsistencies.
1094  *
1095  * Note that there is no race between different filesystems: it's only within
1096  * the same device that races occur: many renames can happen at once, as long
1097  * as they are on different partitions.
1098  *
1099  * In the second extended file system, we use a lock flag stored in the memory
1100  * super-block.  This way, we really lock other renames only if they occur
1101  * on the same file system
1102  */
1103 int ext2_rename (struct inode * old_dir, const char * old_name, int old_len,
     /* [previous][next][first][last][top][bottom][index][help] */
1104                  struct inode * new_dir, const char * new_name, int new_len)
1105 {
1106         int result;
1107 
1108         while (old_dir->i_sb->u.ext2_sb.s_rename_lock)
1109                 sleep_on (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
1110         old_dir->i_sb->u.ext2_sb.s_rename_lock = 1;
1111         result = do_ext2_rename (old_dir, old_name, old_len, new_dir,
1112                                  new_name, new_len);
1113         old_dir->i_sb->u.ext2_sb.s_rename_lock = 0;
1114         wake_up (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
1115         return result;
1116 }

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