Whamcloud - gitweb
- landing of b_hd_cleanup_merge to HEAD.
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-pdirops-2.6.7.patch
@@ -6,11 +6,11 @@
  include/linux/ext3_fs_i.h |    6 
  6 files changed, 500 insertions(+), 109 deletions(-)
 
-Index: linux-2.4.20/fs/ext3/namei.c
+Index: linux-2.6.7/fs/ext3/namei.c
 ===================================================================
---- linux-2.4.20.orig/fs/ext3/namei.c  Wed Mar 17 15:37:09 2004
-+++ linux-2.4.20/fs/ext3/namei.c       Wed Mar 17 15:37:56 2004
-@@ -51,6 +51,9 @@
+--- linux-2.6.7.orig/fs/ext3/namei.c   2004-08-26 17:12:39.000000000 +0400
++++ linux-2.6.7/fs/ext3/namei.c        2004-09-07 17:32:13.000000000 +0400
+@@ -53,6 +53,9 @@
  {
        struct buffer_head *bh;
  
@@ -20,7 +20,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        *block = inode->i_size >> inode->i_sb->s_blocksize_bits;
  
        if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
-@@ -58,6 +61,8 @@
+@@ -60,6 +63,8 @@
                EXT3_I(inode)->i_disksize = inode->i_size;
                ext3_journal_get_write_access(handle,bh);
        }
@@ -29,7 +29,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        return bh;
  }
  
-@@ -134,6 +139,8 @@
+@@ -136,6 +141,8 @@
        struct buffer_head *bh;
        struct dx_entry *entries;
        struct dx_entry *at;
@@ -38,7 +38,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  };
  
  struct dx_map_entry
-@@ -142,6 +149,30 @@
+@@ -144,6 +151,30 @@
        u32 offs;
  };
  
@@ -69,7 +69,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  #ifdef CONFIG_EXT3_INDEX
  static inline unsigned dx_get_block (struct dx_entry *entry);
  static void dx_set_block (struct dx_entry *entry, unsigned value);
-@@ -153,7 +184,7 @@
+@@ -155,7 +186,7 @@
  static void dx_set_limit (struct dx_entry *entries, unsigned value);
  static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
  static unsigned dx_node_limit (struct inode *dir);
@@ -78,7 +78,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
                                 struct inode *dir,
                                 struct dx_hash_info *hinfo,
                                 struct dx_frame *frame,
-@@ -165,15 +196,18 @@
+@@ -167,15 +198,18 @@
  static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to,
                struct dx_map_entry *offsets, int count);
  static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size);
@@ -86,7 +86,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
 +static void dx_insert_block (struct inode *, struct dx_frame *, u32, u32, u32);
  static int ext3_htree_next_block(struct inode *dir, __u32 hash,
                                 struct dx_frame *frame,
-                                struct dx_frame *frames, int *err,
+                                struct dx_frame *frames, 
                                 __u32 *start_hash);
  static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
 -                     struct ext3_dir_entry_2 **res_dir, int *err);
@@ -99,7 +99,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  
  /*
   * Future: use high four bits of block for coalesce-on-delete flags
-@@ -306,6 +340,94 @@
+@@ -319,6 +353,94 @@
  #endif /* DX_DEBUG */
  
  /*
@@ -194,7 +194,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
   * Probe for a directory leaf block to search.
   *
   * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
-@@ -315,19 +437,20 @@
+@@ -328,19 +450,20 @@
   * back to userspace.
   */
  static struct dx_frame *
@@ -220,10 +220,10 @@ Index: linux-2.4.20/fs/ext3/namei.c
        if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
                goto fail;
        root = (struct dx_root *) bh->b_data;
-@@ -343,8 +466,8 @@
+@@ -356,8 +479,8 @@
        }
        hinfo->hash_version = root->info.hash_version;
-       hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed;
+       hinfo->seed = EXT3_SB(dir->i_sb)->s_hash_seed;
 -      if (dentry)
 -              ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
 +      if (name)
@@ -231,7 +231,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        hash = hinfo->hash;
  
        if (root->info.unused_flags & 1) {
-@@ -356,7 +479,19 @@
+@@ -369,7 +492,19 @@
                goto fail;
        }
  
@@ -251,7 +251,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
                ext3_warning(dir->i_sb, __FUNCTION__,
                             "Unimplemented inode hash depth: %#06x",
                             root->info.indirect_levels);
-@@ -364,56 +499,46 @@
+@@ -377,56 +512,46 @@
                *err = ERR_BAD_DX_DIR;
                goto fail;
        }
@@ -338,7 +338,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  fail2:
        while (frame >= frame_in) {
                brelse(frame->bh);
-@@ -427,8 +552,7 @@
+@@ -440,8 +565,7 @@
  {
        if (frames[0].bh == NULL)
                return;
@@ -348,7 +348,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
                brelse(frames[1].bh);
        brelse(frames[0].bh);
  }
-@@ -470,8 +594,10 @@
+@@ -482,8 +606,10 @@
         * nodes need to be read.
         */
        while (1) {
@@ -360,17 +360,17 @@ Index: linux-2.4.20/fs/ext3/namei.c
                if (p == frames)
                        return 0;
                num_frames++;
-@@ -497,13 +623,17 @@
+@@ -509,13 +635,17 @@
         * block so no check is necessary
         */
        while (num_frames--) {
 -              if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
--                                    0, err)))
+-                                    0, &err)))
 +              u32 idx;
 +              
 +              idx = p->leaf = dx_get_block(p->at);
-+              if (!(bh = ext3_bread(NULL, dir, idx, 0, err)))
-                       return -1; /* Failure */
++              if (!(bh = ext3_bread(NULL, dir, idx, 0, &err)))
+                       return err; /* Failure */
                p++;
                brelse (p->bh);
                p->bh = bh;
@@ -380,8 +380,8 @@ Index: linux-2.4.20/fs/ext3/namei.c
        }
        return 1;
  }
-@@ -543,7 +673,7 @@
-       dir = dir_file->f_dentry->d_inode;
+@@ -602,7 +732,7 @@
+       }
        hinfo.hash = start_hash;
        hinfo.minor_hash = 0;
 -      frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
@@ -389,7 +389,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        if (!frame)
                return err;
  
-@@ -625,7 +755,8 @@
+@@ -674,7 +804,8 @@
                        count++;
                }
                /* XXX: do we need to check rec_len == 0 case? -Chris */
@@ -399,7 +399,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        }
        return count;
  }
-@@ -658,7 +789,8 @@
+@@ -707,7 +838,8 @@
        } while(more);
  }
  
@@ -409,7 +409,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  {
        struct dx_entry *entries = frame->entries;
        struct dx_entry *old = frame->at, *new = old + 1;
-@@ -670,6 +802,7 @@
+@@ -719,6 +851,7 @@
        dx_set_hash(new, hash);
        dx_set_block(new, block);
        dx_set_count(entries, count + 1);
@@ -417,9 +417,9 @@ Index: linux-2.4.20/fs/ext3/namei.c
  }
  #endif
  
-@@ -752,7 +885,8 @@
-       
+@@ -799,7 +932,8 @@
+  * to brelse() it when appropriate.
+  */
  static struct buffer_head * ext3_find_entry (struct dentry *dentry,
 -                                      struct ext3_dir_entry_2 ** res_dir)
 +                                      struct ext3_dir_entry_2 ** res_dir,
@@ -427,7 +427,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  {
        struct super_block * sb;
        struct buffer_head * bh_use[NAMEI_RA_SIZE];
-@@ -768,6 +902,7 @@
+@@ -815,6 +949,7 @@
        int namelen;
        const u8 *name;
        unsigned blocksize;
@@ -435,7 +435,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  
        *res_dir = NULL;
        sb = dir->i_sb;
-@@ -776,9 +911,10 @@
+@@ -823,9 +958,10 @@
        name = dentry->d_name.name;
        if (namelen > EXT3_NAME_LEN)
                return NULL;
@@ -447,7 +447,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
                /*
                 * On success, or if the error was file not found,
                 * return.  Otherwise, fall back to doing a search the
-@@ -787,8 +923,14 @@
+@@ -834,8 +970,14 @@
                if (bh || (err != ERR_BAD_DX_DIR))
                        return bh;
                dxtrace(printk("ext3_find_entry: dx failed, falling back\n"));
@@ -462,7 +462,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
        start = EXT3_I(dir)->i_dir_start_lookup;
        if (start >= nblocks)
-@@ -860,12 +1002,17 @@
+@@ -908,12 +1050,17 @@
        /* Clean up the read-ahead blocks */
        for (; ra_ptr < ra_max; ra_ptr++)
                brelse (bh_use[ra_ptr]);
@@ -481,9 +481,9 @@ Index: linux-2.4.20/fs/ext3/namei.c
  {
        struct super_block * sb;
        struct dx_hash_info     hinfo;
-@@ -880,11 +1027,22 @@
+@@ -928,11 +1075,22 @@
        struct inode *dir = dentry->d_parent->d_inode;
-       
        sb = dir->i_sb;
 -      if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
 +repeat:
@@ -506,7 +506,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
                if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
                        goto errout;
                de = (struct ext3_dir_entry_2 *) bh->b_data;
-@@ -918,6 +1076,8 @@
+@@ -967,6 +1125,8 @@
        *err = -ENOENT;
  errout:
        dxtrace(printk("%s not found\n", name));
@@ -515,17 +515,14 @@ Index: linux-2.4.20/fs/ext3/namei.c
        dx_release (frames);
        return NULL;
  }
-@@ -928,6 +1088,7 @@
+@@ -977,14 +1137,16 @@
        struct inode * inode;
        struct ext3_dir_entry_2 * de;
        struct buffer_head * bh;
-+    void *lock = NULL;
++      void *lock = NULL;
  
        if (dentry->d_name.len > EXT3_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
-@@ -935,10 +1096,11 @@
-       if (ext3_check_for_iopen(dir, dentry))
-               return NULL;
  
 -      bh = ext3_find_entry(dentry, &de);
 +      bh = ext3_find_entry(dentry, &de, 0, &lock);
@@ -536,7 +533,28 @@ Index: linux-2.4.20/fs/ext3/namei.c
                brelse (bh);
                inode = iget(dir->i_sb, ino);
  
-@@ -975,7 +1137,8 @@
+@@ -1006,17 +1168,19 @@
+       struct dentry dotdot;
+       struct ext3_dir_entry_2 * de;
+       struct buffer_head *bh;
++      void *lock = NULL;
+       dotdot.d_name.name = "..";
+       dotdot.d_name.len = 2;
+       dotdot.d_parent = child; /* confusing, isn't it! */
+-      bh = ext3_find_entry(&dotdot, &de);
++      bh = ext3_find_entry(&dotdot, &de, 0, &lock);
+       inode = NULL;
+       if (!bh)
+               return ERR_PTR(-ENOENT);
+       ino = le32_to_cpu(de->inode);
+       brelse(bh);
++      ext3_unlock_htree(child->d_inode, lock);
+       inode = iget(child->d_inode->i_sb, ino);
+       if (!inode)
+@@ -1055,7 +1219,8 @@
        unsigned rec_len = 0;
  
        while (count--) {
@@ -545,8 +563,8 @@ Index: linux-2.4.20/fs/ext3/namei.c
 +                      (struct ext3_dir_entry_2 *) (from + map->offs);
                rec_len = EXT3_DIR_REC_LEN(de->name_len);
                memcpy (to, de, rec_len);
-               ((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
-@@ -988,7 +1151,8 @@
+               ((struct ext3_dir_entry_2 *) to)->rec_len =
+@@ -1069,7 +1234,8 @@
  
  static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
  {
@@ -556,7 +574,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        unsigned rec_len = 0;
  
        prev = to = de;
-@@ -1010,7 +1174,8 @@
+@@ -1091,7 +1257,8 @@
  
  static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
                        struct buffer_head **bh,struct dx_frame *frame,
@@ -566,7 +584,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  {
        unsigned blocksize = dir->i_sb->s_blocksize;
        unsigned count, continued;
-@@ -1057,23 +1222,30 @@
+@@ -1138,23 +1305,30 @@
        hash2 = map[split].hash;
        continued = hash2 == map[split - 1].hash;
        dxtrace(printk("Split block %i at %x, %i/%i\n",
@@ -603,7 +621,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        err = ext3_journal_dirty_metadata (handle, bh2);
        if (err)
                goto journal_error;
-@@ -1147,7 +1319,8 @@
+@@ -1228,7 +1402,8 @@
        nlen = EXT3_DIR_REC_LEN(de->name_len);
        rlen = le16_to_cpu(de->rec_len);
        if (de->inode) {
@@ -613,34 +631,24 @@ Index: linux-2.4.20/fs/ext3/namei.c
                de1->rec_len = cpu_to_le16(rlen - nlen);
                de->rec_len = cpu_to_le16(nlen);
                de = de1;
-@@ -1205,7 +1378,8 @@
-       unsigned        blocksize;
+@@ -1287,6 +1462,7 @@
        struct dx_hash_info hinfo;
        u32             block;
--              
+       struct fake_dirent *fde;
 +      void            *lock, *new_lock;
-+
        blocksize =  dir->i_sb->s_blocksize;
        dxtrace(printk("Creating index\n"));
-       retval = ext3_journal_get_write_access(handle, bh);
-@@ -1216,7 +1390,6 @@
-       }
-       root = (struct dx_root *) bh->b_data;
-               
--      EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
-       bh2 = ext3_append (handle, dir, &block, &retval);
-       if (!(bh2)) {
-               brelse(bh);
-@@ -1224,6 +1397,8 @@
-       }
+@@ -1306,6 +1482,8 @@
+       EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
        data1 = bh2->b_data;
  
 +      lock = ext3_lock_htree(dir, block, 1);
 +
        /* The 0th block becomes the root, move the dirents out */
-       de = (struct ext3_dir_entry_2 *) &root->dotdot;
-       de = (struct ext3_dir_entry_2 *) ((char *)de + de->rec_len);
-@@ -1253,13 +1428,25 @@
+       fde = &root->dotdot;
+       de = (struct ext3_dir_entry_2 *)((char *)fde + le16_to_cpu(fde->rec_len));
+@@ -1335,13 +1513,25 @@
        frame->entries = entries;
        frame->at = entries;
        frame->bh = bh;
@@ -669,7 +677,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  }
  #endif
  
-@@ -1288,11 +1475,13 @@
+@@ -1370,11 +1560,13 @@
        unsigned blocksize;
        unsigned nlen, rlen;
        u32 block, blocks;
@@ -683,7 +691,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  #ifdef CONFIG_EXT3_INDEX
        if (is_dx(dir)) {
                retval = ext3_dx_add_entry(handle, dentry, inode);
-@@ -1303,36 +1492,53 @@
+@@ -1385,36 +1577,53 @@
                ext3_mark_inode_dirty(handle, dir);
        }
  #endif
@@ -746,7 +754,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
                             struct inode *inode)
  {
-@@ -1344,15 +1550,28 @@
+@@ -1426,15 +1635,28 @@
        struct super_block * sb = dir->i_sb;
        struct ext3_dir_entry_2 *de;
        int err;
@@ -780,7 +788,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
  
        BUFFER_TRACE(bh, "get_write_access");
        err = ext3_journal_get_write_access(handle, bh);
-@@ -1365,6 +1584,35 @@
+@@ -1447,6 +1669,35 @@
                goto cleanup;
        }
  
@@ -816,7 +824,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        /* Block full, should compress but for now just split */
        dxtrace(printk("using %u of %u node entries\n",
                       dx_get_count(entries), dx_get_limit(entries)));
-@@ -1376,7 +1624,8 @@
+@@ -1458,7 +1709,8 @@
                struct dx_entry *entries2;
                struct dx_node *node2;
                struct buffer_head *bh2;
@@ -826,7 +834,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
                if (levels && (dx_get_count(frames->entries) ==
                               dx_get_limit(frames->entries))) {
                        ext3_warning(sb, __FUNCTION__,
-@@ -1387,6 +1636,7 @@
+@@ -1469,6 +1721,7 @@
                bh2 = ext3_append (handle, dir, &newblock, &err);
                if (!(bh2))
                        goto cleanup;
@@ -834,12 +842,14 @@ Index: linux-2.4.20/fs/ext3/namei.c
                node2 = (struct dx_node *)(bh2->b_data);
                entries2 = node2->entries;
                node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
-@@ -1398,27 +1648,73 @@
+@@ -1480,27 +1733,73 @@
                if (levels) {
                        unsigned icount1 = icount/2, icount2 = icount - icount1;
                        unsigned hash2 = dx_get_hash(entries + icount1);
+-                      dxtrace(printk("Split index %i/%i\n", icount1, icount2));
 +                      void *ri_lock;
-+
+-                      BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
 +                      /* we have to protect root htree index against
 +                       * another dx_add_entry() which would want to
 +                       * split it too -bzzz */
@@ -851,17 +861,14 @@ Index: linux-2.4.20/fs/ext3/namei.c
 +                      frames->at = dx_find_position(frames->entries, hinfo.hash);
 +                      dx_unlock_bh(frame->bh);
 +                      
-                       dxtrace(printk("Split index %i/%i\n", icount1, icount2));
--                              
--                      BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
++                      dxtrace(printk("Split index %i/%i\n", icount1, icount2));
 +      
 +                      BUFFER_TRACE(frame->bh, "get_write_access");
                        err = ext3_journal_get_write_access(handle,
                                                             frames[0].bh);
                        if (err)
                                goto journal_error;
--                              
-+                      
 +                      /* copy index into new one */
                        memcpy ((char *) entries2, (char *) (entries + icount1),
                                icount2 * sizeof(struct dx_entry));
@@ -914,7 +921,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
                        dxtrace(dx_show_index ("node", frames[1].entries));
                        dxtrace(dx_show_index ("node",
                               ((struct dx_node *) bh2->b_data)->entries));
-@@ -1427,38 +1723,61 @@
+@@ -1509,38 +1808,61 @@
                                goto journal_error;
                        brelse (bh2);
                } else {
@@ -969,7 +976,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
 +      
        bh = 0;
        goto cleanup;
-       
  journal_error:
        ext3_std_error(dir->i_sb, err);
  cleanup:
@@ -977,16 +984,16 @@ Index: linux-2.4.20/fs/ext3/namei.c
        if (bh)
                brelse(bh);
        dx_release(frames);
-@@ -1902,6 +2221,7 @@
+@@ -1981,6 +2303,7 @@
        struct buffer_head * bh;
        struct ext3_dir_entry_2 * de;
        handle_t *handle;
 +      void *lock;
  
-       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
-       if (IS_ERR(handle)) {
-@@ -1909,7 +2229,7 @@
-       }
+       /* Initialize quotas before so that eventual writes go in
+        * separate transaction */
+@@ -1990,7 +2313,7 @@
+               return PTR_ERR(handle);
  
        retval = -ENOENT;
 -      bh = ext3_find_entry (dentry, &de);
@@ -994,8 +1001,8 @@ Index: linux-2.4.20/fs/ext3/namei.c
        if (!bh)
                goto end_rmdir;
  
-@@ -1920,14 +2240,19 @@
-       DQUOT_INIT(inode);
+@@ -2000,14 +2323,19 @@
+       inode = dentry->d_inode;
  
        retval = -EIO;
 -      if (le32_to_cpu(de->inode) != inode->i_ino)
@@ -1016,15 +1023,15 @@ Index: linux-2.4.20/fs/ext3/namei.c
        if (retval)
                goto end_rmdir;
        if (inode->i_nlink != 2)
-@@ -1956,6 +2281,7 @@
+@@ -2040,6 +2368,7 @@
        struct buffer_head * bh;
        struct ext3_dir_entry_2 * de;
        handle_t *handle;
 +      void *lock;
  
-       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
-       if (IS_ERR(handle)) {
-@@ -1966,7 +2292,7 @@
+       /* Initialize quotas before so that eventual writes go
+        * in separate transaction */
+@@ -2052,15 +2381,17 @@
                handle->h_sync = 1;
  
        retval = -ENOENT;
@@ -1033,8 +1040,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        if (!bh)
                goto end_unlink;
  
-@@ -1974,8 +2300,10 @@
-       DQUOT_INIT(inode);
+       inode = dentry->d_inode;
  
        retval = -EIO;
 -      if (le32_to_cpu(de->inode) != inode->i_ino)
@@ -1042,10 +1048,10 @@ Index: linux-2.4.20/fs/ext3/namei.c
 +              ext3_unlock_htree(dir, lock);
                goto end_unlink;
 +      }
-       
        if (!inode->i_nlink) {
                ext3_warning (inode->i_sb, "ext3_unlink",
-@@ -1984,6 +2312,7 @@
+@@ -2069,6 +2400,7 @@
                inode->i_nlink = 1;
        }
        retval = ext3_delete_entry(handle, dir, de, bh);
@@ -1053,7 +1059,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        if (retval)
                goto end_unlink;
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-@@ -2121,6 +2450,7 @@
+@@ -2182,6 +2514,7 @@
        struct buffer_head * old_bh, * new_bh, * dir_bh;
        struct ext3_dir_entry_2 * old_de, * new_de;
        int retval;
@@ -1061,8 +1067,8 @@ Index: linux-2.4.20/fs/ext3/namei.c
  
        old_bh = new_bh = dir_bh = NULL;
  
-@@ -2133,7 +2463,10 @@
-       if (IS_SYNC(old_dir) || IS_SYNC(new_dir))
+@@ -2197,7 +2530,10 @@
+       if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
                handle->h_sync = 1;
  
 -      old_bh = ext3_find_entry (old_dentry, &old_de);
@@ -1073,7 +1079,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        /*
         *  Check for inode number is _not_ due to possible IO errors.
         *  We might rmdir the source, keep it as pwd of some process
-@@ -2146,7 +2479,7 @@
+@@ -2210,7 +2546,7 @@
                goto end_rename;
  
        new_inode = new_dentry->d_inode;
@@ -1082,16 +1088,16 @@ Index: linux-2.4.20/fs/ext3/namei.c
        if (new_bh) {
                if (!new_inode) {
                        brelse (new_bh);
-@@ -2209,7 +2542,7 @@
+@@ -2274,7 +2610,7 @@
                struct buffer_head *old_bh2;
                struct ext3_dir_entry_2 *old_de2;
-               
 -              old_bh2 = ext3_find_entry(old_dentry, &old_de2);
 +              old_bh2 = ext3_find_entry(old_dentry, &old_de2, 1, &lock3 /* FIXME */);
                if (old_bh2) {
                        retval = ext3_delete_entry(handle, old_dir,
                                                   old_de2, old_bh2);
-@@ -2252,6 +2585,14 @@
+@@ -2317,6 +2653,14 @@
        retval = 0;
  
  end_rename:
@@ -1106,7 +1112,7 @@ Index: linux-2.4.20/fs/ext3/namei.c
        brelse (dir_bh);
        brelse (old_bh);
        brelse (new_bh);
-@@ -2260,6 +2601,29 @@
+@@ -2325,6 +2669,29 @@
  }
  
  /*
@@ -1136,96 +1142,53 @@ Index: linux-2.4.20/fs/ext3/namei.c
   * directories can handle most operations...
   */
  struct inode_operations ext3_dir_inode_operations = {
-Index: linux-2.4.20/fs/ext3/super.c
+Index: linux-2.6.7/fs/ext3/super.c
 ===================================================================
---- linux-2.4.20.orig/fs/ext3/super.c  Wed Mar 17 15:37:09 2004
-+++ linux-2.4.20/fs/ext3/super.c       Wed Mar 17 15:37:10 2004
-@@ -796,6 +796,8 @@
-                               return 0;
-                       }
-               }
-+              else if (!strcmp (this_char, "pdirops"))
-+                      set_opt (sbi->s_mount_opt, PDIROPS);
-               else if (!strcmp (this_char, "grpid") ||
-                        !strcmp (this_char, "bsdgroups"))
-                       set_opt (*mount_options, GRPID);
-@@ -822,6 +824,9 @@
-                       if (want_numeric(value, "sb", sb_block))
-                               return 0;
-               }
-+              else if (!strcmp (this_char, "pdirops")) {
-+                      set_opt (sbi->s_mount_opt, PDIROPS);
-+              }
- #ifdef CONFIG_JBD_DEBUG
-               else if (!strcmp (this_char, "ro-after")) {
-                       unsigned long v;
-@@ -985,6 +990,10 @@
-               ext3_check_inodes_bitmap (sb);
-       }
+--- linux-2.6.7.orig/fs/ext3/super.c   2004-09-07 14:12:13.000000000 +0400
++++ linux-2.6.7/fs/ext3/super.c        2004-09-07 17:17:37.000000000 +0400
+@@ -453,6 +453,9 @@
+       ei->i_default_acl = EXT3_ACL_NOT_CACHED;
  #endif
-+#ifdef S_PDIROPS
-+      if (test_opt (sb, PDIROPS))
-+              sb->s_flags |= S_PDIROPS;
-+#endif
-       setup_ro_after(sb);
-       return res;
+       ei->vfs_inode.i_version = 1;
++      dynlock_init(&ei->i_htree_lock);
++      sema_init(&ei->i_rename_sem, 1);
++      sema_init(&ei->i_append_sem, 1);
+       return &ei->vfs_inode;
  }
-@@ -1484,6 +1493,11 @@
-               test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
-               "writeback");
  
-+      if (test_opt(sb, PDIROPS)) {
-+              printk (KERN_INFO "EXT3-fs: mounted filesystem with parallel dirops\n");
-+              sb->s_flags |= S_PDIROPS;
-+      }
-+              
-       return sb;
+@@ -586,7 +589,7 @@
+       Opt_commit, Opt_journal_update, Opt_journal_inum,
+       Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
+       Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
+-      Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0,
++      Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_pdirops,
+       Opt_ignore, Opt_err,
+ };
  
- failed_mount3:
-Index: linux-2.4.20/fs/ext3/inode.c
-===================================================================
---- linux-2.4.20.orig/fs/ext3/inode.c  Wed Mar 17 15:37:09 2004
-+++ linux-2.4.20/fs/ext3/inode.c       Wed Mar 17 15:37:10 2004
-@@ -2435,6 +2435,9 @@
-       } else if (S_ISDIR(inode->i_mode)) {
-               inode->i_op = &ext3_dir_inode_operations;
-               inode->i_fop = &ext3_dir_operations;
-+              dynlock_init(&EXT3_I(inode)->i_htree_lock);
-+              sema_init(&EXT3_I(inode)->i_rename_sem, 1);
-+              sema_init(&EXT3_I(inode)->i_append_sem, 1);
-       } else if (S_ISLNK(inode->i_mode)) {
-               if (ext3_inode_is_fast_symlink(inode))
-                       inode->i_op = &ext3_fast_symlink_inode_operations;
-Index: linux-2.4.20/fs/ext3/ialloc.c
-===================================================================
---- linux-2.4.20.orig/fs/ext3/ialloc.c Wed Mar 17 15:37:09 2004
-+++ linux-2.4.20/fs/ext3/ialloc.c      Wed Mar 17 15:37:10 2004
-@@ -601,6 +601,9 @@
-               return ERR_PTR(-EDQUOT);
-       }
-       ext3_debug ("allocating inode %lu\n", inode->i_ino);
-+      dynlock_init(&EXT3_I(inode)->i_htree_lock);
-+      sema_init(&EXT3_I(inode)->i_rename_sem, 1);
-+      sema_init(&EXT3_I(inode)->i_append_sem, 1);
-       return inode;
- fail:
-Index: linux-2.4.20/include/linux/ext3_fs.h
+@@ -632,6 +635,7 @@
+       {Opt_ignore, "noquota"},
+       {Opt_ignore, "quota"},
+       {Opt_ignore, "usrquota"},
++      {Opt_pdirops, "pdirops"},
+       {Opt_err, NULL}
+ };
+Index: linux-2.6.7/include/linux/ext3_fs.h
 ===================================================================
---- linux-2.4.20.orig/include/linux/ext3_fs.h  Wed Mar 17 15:37:09 2004
-+++ linux-2.4.20/include/linux/ext3_fs.h       Wed Mar 17 15:37:10 2004
+--- linux-2.6.7.orig/include/linux/ext3_fs.h   2003-09-19 18:01:10.000000000 +0400
++++ linux-2.6.7/include/linux/ext3_fs.h        2004-09-07 17:17:37.000000000 +0400
 @@ -306,6 +306,7 @@
  /*
   * Mount flags
   */
 +#define EXT3_MOUNT_PDIROPS            0x800000/* Parallel dir operations */
  #define EXT3_MOUNT_CHECK              0x0001  /* Do mount-time checks */
+ #define EXT3_MOUNT_OLDALLOC           0x0002  /* Don't use the new Orlov allocator */
  #define EXT3_MOUNT_GRPID              0x0004  /* Create files with directory's group */
- #define EXT3_MOUNT_DEBUG              0x0008  /* Some debugging messages */
-Index: linux-2.4.20/include/linux/ext3_fs_i.h
+Index: linux-2.6.7/include/linux/ext3_fs_i.h
 ===================================================================
---- linux-2.4.20.orig/include/linux/ext3_fs_i.h        Thu Nov 22 11:46:19 2001
-+++ linux-2.4.20/include/linux/ext3_fs_i.h     Wed Mar 17 15:37:10 2004
+--- linux-2.6.7.orig/include/linux/ext3_fs_i.h 2003-12-30 08:32:44.000000000 +0300
++++ linux-2.6.7/include/linux/ext3_fs_i.h      2004-09-07 17:17:37.000000000 +0400
 @@ -17,6 +17,7 @@
  #define _LINUX_EXT3_FS_I
  
@@ -1234,15 +1197,15 @@ Index: linux-2.4.20/include/linux/ext3_fs_i.h
  
  /*
   * second extended file system inode data in memory
-@@ -73,6 +74,11 @@
-        * by other means, so we have truncate_sem.
+@@ -108,6 +109,11 @@
         */
-       struct rw_semaphore truncate_sem;
-+
-+      /* following fields for parallel directory operations -bzzz */
-+      struct dynlock i_htree_lock;
-+      struct semaphore i_append_sem;
-+      struct semaphore i_rename_sem;
+       struct semaphore truncate_sem;
+       struct inode vfs_inode;
++ 
++      /* following fields for parallel directory operations -bzzz */
++      struct dynlock i_htree_lock;
++      struct semaphore i_append_sem;
++      struct semaphore i_rename_sem;
  };
  
  #endif        /* _LINUX_EXT3_FS_I */