Whamcloud - gitweb
iam: 1. more correctness checks, 2. fixes to readdir locking.
authornikita <nikita>
Mon, 20 Nov 2006 23:16:22 +0000 (23:16 +0000)
committernikita <nikita>
Mon, 20 Nov 2006 23:16:22 +0000 (23:16 +0000)
ldiskfs/kernel_patches/patches/ext3-check-jbd-errors-2.6.9.patch
ldiskfs/kernel_patches/patches/ext3-sector_t-overflow-2.6.9-rhel4.patch
lustre/kernel_patches/patches/ext3-check-jbd-errors-2.6.9.patch
lustre/kernel_patches/patches/ext3-iam-separate.patch
lustre/kernel_patches/patches/ext3-pdirops-2.6.9.patch
lustre/kernel_patches/patches/ext3-sector_t-overflow-2.6.9-rhel4.patch

index f6904f2..2b32b3e 100644 (file)
@@ -1,78 +1,7 @@
-Index: linux-2.6.9-full/include/linux/ext3_fs.h
+Index: iam/fs/ext3/inode.c
 ===================================================================
---- linux-2.6.9-full.orig/include/linux/ext3_fs.h      2006-08-09 17:56:39.000000000 +0400
-+++ linux-2.6.9-full/include/linux/ext3_fs.h   2006-08-22 12:36:22.000000000 +0400
-@@ -826,6 +826,7 @@ extern void ext3_put_super (struct super
- extern void ext3_write_super (struct super_block *);
- extern void ext3_write_super_lockfs (struct super_block *);
- extern void ext3_unlockfs (struct super_block *);
-+extern void ext3_commit_super (struct super_block *, struct ext3_super_block *, int);
- extern int ext3_remount (struct super_block *, int *, char *);
- extern int ext3_statfs (struct super_block *, struct kstatfs *);
-Index: linux-2.6.9-full/fs/ext3/super.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/super.c      2006-08-09 17:56:40.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/super.c   2006-08-09 17:56:40.000000000 +0400
-@@ -43,7 +43,7 @@ static int ext3_load_journal(struct supe
-                            unsigned long journal_devnum);
- static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
-                              int);
--static void ext3_commit_super (struct super_block * sb,
-+void ext3_commit_super (struct super_block * sb,
-                              struct ext3_super_block * es,
-                              int sync);
- static void ext3_mark_recovery_complete(struct super_block * sb,
-@@ -1991,7 +1991,7 @@ static int ext3_create_journal(struct su
-       return 0;
- }
--static void ext3_commit_super (struct super_block * sb,
-+void ext3_commit_super (struct super_block * sb,
-                              struct ext3_super_block * es,
-                              int sync)
- {
-Index: linux-2.6.9-full/fs/ext3/namei.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/namei.c      2006-08-09 17:56:40.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/namei.c   2006-08-09 17:56:40.000000000 +0400
-@@ -1599,7 +1599,7 @@ static int ext3_delete_entry (handle_t *
-                             struct buffer_head * bh)
- {
-       struct ext3_dir_entry_2 * de, * pde;
--      int i;
-+      int i, err;
-       i = 0;
-       pde = NULL;
-@@ -1609,7 +1609,9 @@ static int ext3_delete_entry (handle_t *
-                       return -EIO;
-               if (de == de_del)  {
-                       BUFFER_TRACE(bh, "get_write_access");
--                      ext3_journal_get_write_access(handle, bh);
-+                      err = ext3_journal_get_write_access(handle, bh);
-+                      if (err)
-+                              return err;
-                       if (pde)
-                               pde->rec_len =
-                                       cpu_to_le16(le16_to_cpu(pde->rec_len) +
-Index: linux-2.6.9-full/fs/ext3/xattr.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/xattr.c      2006-06-01 14:58:48.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/xattr.c   2006-08-09 17:56:40.000000000 +0400
-@@ -132,7 +132,7 @@ ext3_xattr_handler(int name_index)
- {
-       struct xattr_handler *handler = NULL;
--      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX)
-+      if (name_index > 0 && name_index < EXT3_XATTR_INDEX_MAX)
-               handler = ext3_xattr_handler_map[name_index];
-       return handler;
- }
-Index: linux-2.6.9-full/fs/ext3/inode.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/inode.c      2006-06-02 23:37:38.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/inode.c   2006-08-22 12:34:28.000000000 +0400
+--- iam.orig/fs/ext3/inode.c
++++ iam/fs/ext3/inode.c
 @@ -1513,9 +1513,14 @@ out_stop:
                        if (end > inode->i_size) {
                                ei->i_disksize = end;
@@ -111,3 +40,74 @@ Index: linux-2.6.9-full/fs/ext3/inode.c
                }
        }
  
+Index: iam/fs/ext3/namei.c
+===================================================================
+--- iam.orig/fs/ext3/namei.c
++++ iam/fs/ext3/namei.c
+@@ -2473,7 +2473,7 @@ static int ext3_delete_entry (handle_t *
+                             struct buffer_head * bh)
+ {
+       struct ext3_dir_entry_2 * de, * pde;
+-      int i;
++      int i, err;
+       i = 0;
+       pde = NULL;
+@@ -2483,7 +2483,9 @@ static int ext3_delete_entry (handle_t *
+                       return -EIO;
+               if (de == de_del)  {
+                       BUFFER_TRACE(bh, "get_write_access");
+-                      ext3_journal_get_write_access(handle, bh);
++                      err = ext3_journal_get_write_access(handle, bh);
++                      if (err)
++                              return err;
+                       if (pde)
+                               pde->rec_len =
+                                       cpu_to_le16(le16_to_cpu(pde->rec_len) +
+Index: iam/fs/ext3/super.c
+===================================================================
+--- iam.orig/fs/ext3/super.c
++++ iam/fs/ext3/super.c
+@@ -42,7 +42,7 @@
+ static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
+ static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
+                              int);
+-static void ext3_commit_super (struct super_block * sb,
++void ext3_commit_super (struct super_block * sb,
+                              struct ext3_super_block * es,
+                              int sync);
+ static void ext3_mark_recovery_complete(struct super_block * sb,
+@@ -1987,7 +1987,7 @@ static int ext3_create_journal(struct su
+       return 0;
+ }
+-static void ext3_commit_super (struct super_block * sb,
++void ext3_commit_super (struct super_block * sb,
+                              struct ext3_super_block * es,
+                              int sync)
+ {
+Index: iam/fs/ext3/xattr.c
+===================================================================
+--- iam.orig/fs/ext3/xattr.c
++++ iam/fs/ext3/xattr.c
+@@ -132,7 +132,7 @@ ext3_xattr_handler(int name_index)
+ {
+       struct xattr_handler *handler = NULL;
+-      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX)
++      if (name_index > 0 && name_index < EXT3_XATTR_INDEX_MAX)
+               handler = ext3_xattr_handler_map[name_index];
+       return handler;
+ }
+Index: iam/include/linux/ext3_fs.h
+===================================================================
+--- iam.orig/include/linux/ext3_fs.h
++++ iam/include/linux/ext3_fs.h
+@@ -839,6 +839,7 @@ extern void ext3_put_super (struct super
+ extern void ext3_write_super (struct super_block *);
+ extern void ext3_write_super_lockfs (struct super_block *);
+ extern void ext3_unlockfs (struct super_block *);
++extern void ext3_commit_super (struct super_block *, struct ext3_super_block *, int);
+ extern int ext3_remount (struct super_block *, int *, char *);
+ extern int ext3_statfs (struct super_block *, struct kstatfs *);
index 9bfdf80..c8024c7 100644 (file)
@@ -14,16 +14,11 @@ Verified this patch on a 32 bit platform without CONFIG_LBD defined
 Signed-off-by: Mingming Cao<cmm@us.ibm.com>
 Acked-by: Andreas Dilger <adilger@clusterfs.com>
 Signed-off-by: Andrew Morton <akpm@osdl.org>
----
-
- fs/ext3/resize.c |   10 ++++++++++
- fs/ext3/super.c  |   10 ++++++++++
- 2 files changed, 20 insertions(+)
-
-diff -puN fs/ext3/resize.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem fs/ext3/resize.c
---- devel/fs/ext3/resize.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem        2006-05-22 14:09:53.000000000 -0700
-+++ devel-akpm/fs/ext3/resize.c        2006-05-22 14:10:56.000000000 -0700
-@@ -926,6 +926,16 @@ int ext3_group_extend(struct super_block
+Index: iam/fs/ext3/resize.c
+===================================================================
+--- iam.orig/fs/ext3/resize.c
++++ iam/fs/ext3/resize.c
+@@ -914,6 +914,16 @@ int ext3_group_extend(struct super_block
        if (n_blocks_count == 0 || n_blocks_count == o_blocks_count)
                return 0;
  
@@ -40,10 +35,11 @@ diff -puN fs/ext3/resize.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem
        if (n_blocks_count < o_blocks_count) {
                ext3_warning(sb, __FUNCTION__,
                             "can't shrink FS - resize aborted");
-diff -puN fs/ext3/super.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem fs/ext3/super.c
---- devel/fs/ext3/super.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem 2006-05-22 14:09:53.000000000 -0700
-+++ devel-akpm/fs/ext3/super.c 2006-05-22 14:11:10.000000000 -0700
-@@ -1565,6 +1565,17 @@ static int ext3_fill_super (struct super
+Index: iam/fs/ext3/super.c
+===================================================================
+--- iam.orig/fs/ext3/super.c
++++ iam/fs/ext3/super.c
+@@ -1530,6 +1530,17 @@ static int ext3_fill_super (struct super
                goto failed_mount;
        }
  
@@ -61,4 +57,3 @@ diff -puN fs/ext3/super.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem f
        sbi->s_groups_count = (le32_to_cpu(es->s_blocks_count) -
                               le32_to_cpu(es->s_first_data_block) +
                               EXT3_BLOCKS_PER_GROUP(sb) - 1) /
-_
index f6904f2..2b32b3e 100644 (file)
@@ -1,78 +1,7 @@
-Index: linux-2.6.9-full/include/linux/ext3_fs.h
+Index: iam/fs/ext3/inode.c
 ===================================================================
---- linux-2.6.9-full.orig/include/linux/ext3_fs.h      2006-08-09 17:56:39.000000000 +0400
-+++ linux-2.6.9-full/include/linux/ext3_fs.h   2006-08-22 12:36:22.000000000 +0400
-@@ -826,6 +826,7 @@ extern void ext3_put_super (struct super
- extern void ext3_write_super (struct super_block *);
- extern void ext3_write_super_lockfs (struct super_block *);
- extern void ext3_unlockfs (struct super_block *);
-+extern void ext3_commit_super (struct super_block *, struct ext3_super_block *, int);
- extern int ext3_remount (struct super_block *, int *, char *);
- extern int ext3_statfs (struct super_block *, struct kstatfs *);
-Index: linux-2.6.9-full/fs/ext3/super.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/super.c      2006-08-09 17:56:40.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/super.c   2006-08-09 17:56:40.000000000 +0400
-@@ -43,7 +43,7 @@ static int ext3_load_journal(struct supe
-                            unsigned long journal_devnum);
- static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
-                              int);
--static void ext3_commit_super (struct super_block * sb,
-+void ext3_commit_super (struct super_block * sb,
-                              struct ext3_super_block * es,
-                              int sync);
- static void ext3_mark_recovery_complete(struct super_block * sb,
-@@ -1991,7 +1991,7 @@ static int ext3_create_journal(struct su
-       return 0;
- }
--static void ext3_commit_super (struct super_block * sb,
-+void ext3_commit_super (struct super_block * sb,
-                              struct ext3_super_block * es,
-                              int sync)
- {
-Index: linux-2.6.9-full/fs/ext3/namei.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/namei.c      2006-08-09 17:56:40.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/namei.c   2006-08-09 17:56:40.000000000 +0400
-@@ -1599,7 +1599,7 @@ static int ext3_delete_entry (handle_t *
-                             struct buffer_head * bh)
- {
-       struct ext3_dir_entry_2 * de, * pde;
--      int i;
-+      int i, err;
-       i = 0;
-       pde = NULL;
-@@ -1609,7 +1609,9 @@ static int ext3_delete_entry (handle_t *
-                       return -EIO;
-               if (de == de_del)  {
-                       BUFFER_TRACE(bh, "get_write_access");
--                      ext3_journal_get_write_access(handle, bh);
-+                      err = ext3_journal_get_write_access(handle, bh);
-+                      if (err)
-+                              return err;
-                       if (pde)
-                               pde->rec_len =
-                                       cpu_to_le16(le16_to_cpu(pde->rec_len) +
-Index: linux-2.6.9-full/fs/ext3/xattr.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/xattr.c      2006-06-01 14:58:48.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/xattr.c   2006-08-09 17:56:40.000000000 +0400
-@@ -132,7 +132,7 @@ ext3_xattr_handler(int name_index)
- {
-       struct xattr_handler *handler = NULL;
--      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX)
-+      if (name_index > 0 && name_index < EXT3_XATTR_INDEX_MAX)
-               handler = ext3_xattr_handler_map[name_index];
-       return handler;
- }
-Index: linux-2.6.9-full/fs/ext3/inode.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/inode.c      2006-06-02 23:37:38.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/inode.c   2006-08-22 12:34:28.000000000 +0400
+--- iam.orig/fs/ext3/inode.c
++++ iam/fs/ext3/inode.c
 @@ -1513,9 +1513,14 @@ out_stop:
                        if (end > inode->i_size) {
                                ei->i_disksize = end;
@@ -111,3 +40,74 @@ Index: linux-2.6.9-full/fs/ext3/inode.c
                }
        }
  
+Index: iam/fs/ext3/namei.c
+===================================================================
+--- iam.orig/fs/ext3/namei.c
++++ iam/fs/ext3/namei.c
+@@ -2473,7 +2473,7 @@ static int ext3_delete_entry (handle_t *
+                             struct buffer_head * bh)
+ {
+       struct ext3_dir_entry_2 * de, * pde;
+-      int i;
++      int i, err;
+       i = 0;
+       pde = NULL;
+@@ -2483,7 +2483,9 @@ static int ext3_delete_entry (handle_t *
+                       return -EIO;
+               if (de == de_del)  {
+                       BUFFER_TRACE(bh, "get_write_access");
+-                      ext3_journal_get_write_access(handle, bh);
++                      err = ext3_journal_get_write_access(handle, bh);
++                      if (err)
++                              return err;
+                       if (pde)
+                               pde->rec_len =
+                                       cpu_to_le16(le16_to_cpu(pde->rec_len) +
+Index: iam/fs/ext3/super.c
+===================================================================
+--- iam.orig/fs/ext3/super.c
++++ iam/fs/ext3/super.c
+@@ -42,7 +42,7 @@
+ static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
+ static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
+                              int);
+-static void ext3_commit_super (struct super_block * sb,
++void ext3_commit_super (struct super_block * sb,
+                              struct ext3_super_block * es,
+                              int sync);
+ static void ext3_mark_recovery_complete(struct super_block * sb,
+@@ -1987,7 +1987,7 @@ static int ext3_create_journal(struct su
+       return 0;
+ }
+-static void ext3_commit_super (struct super_block * sb,
++void ext3_commit_super (struct super_block * sb,
+                              struct ext3_super_block * es,
+                              int sync)
+ {
+Index: iam/fs/ext3/xattr.c
+===================================================================
+--- iam.orig/fs/ext3/xattr.c
++++ iam/fs/ext3/xattr.c
+@@ -132,7 +132,7 @@ ext3_xattr_handler(int name_index)
+ {
+       struct xattr_handler *handler = NULL;
+-      if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX)
++      if (name_index > 0 && name_index < EXT3_XATTR_INDEX_MAX)
+               handler = ext3_xattr_handler_map[name_index];
+       return handler;
+ }
+Index: iam/include/linux/ext3_fs.h
+===================================================================
+--- iam.orig/include/linux/ext3_fs.h
++++ iam/include/linux/ext3_fs.h
+@@ -839,6 +839,7 @@ extern void ext3_put_super (struct super
+ extern void ext3_write_super (struct super_block *);
+ extern void ext3_write_super_lockfs (struct super_block *);
+ extern void ext3_unlockfs (struct super_block *);
++extern void ext3_commit_super (struct super_block *, struct ext3_super_block *, int);
+ extern int ext3_remount (struct super_block *, int *, char *);
+ extern int ext3_statfs (struct super_block *, struct kstatfs *);
index 6db2c28..5934e16 100644 (file)
@@ -15,7 +15,7 @@ Index: iam/fs/ext3/iam.c
 ===================================================================
 --- iam.orig/fs/ext3/iam.c
 +++ iam/fs/ext3/iam.c
-@@ -0,0 +1,1432 @@
+@@ -0,0 +1,1445 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
 + *
@@ -222,11 +222,10 @@ Index: iam/fs/ext3/iam.c
 +
 +static void iam_leaf_fini(struct iam_leaf *leaf);
 +
-+void iam_path_fini(struct iam_path *path)
++void iam_path_release(struct iam_path *path)
 +{
 +      int i;
 +
-+      iam_leaf_fini(&path->ip_leaf);
 +      for (i = 0; i < ARRAY_SIZE(path->ip_frames); i++) {
 +              if (path->ip_frames[i].bh != NULL) {
 +                      brelse(path->ip_frames[i].bh);
@@ -235,6 +234,12 @@ Index: iam/fs/ext3/iam.c
 +      }
 +}
 +
++void iam_path_fini(struct iam_path *path)
++{
++      iam_leaf_fini(&path->ip_leaf);
++        iam_path_release(path);
++}
++
 +void iam_path_compat_init(struct iam_path_compat *path, struct inode *inode)
 +{
 +      int i;
@@ -857,6 +862,8 @@ Index: iam/fs/ext3/iam.c
 +}
 +EXPORT_SYMBOL(iam_it_put);
 +
++static struct iam_ikey *iam_it_ikey_get(const struct iam_iterator *it,
++                                        struct iam_ikey *ikey);
 +/*
 + * Move iterator one record right.
 + *
@@ -875,6 +882,7 @@ Index: iam/fs/ext3/iam.c
 +        struct iam_path      *path;
 +        struct iam_leaf      *leaf;
 +        struct inode         *obj;
++        do_corr(struct iam_ikey *ik_orig);
 +
 +        /* assert_corr(it->ii_flags&IAM_IT_MOVE); */
 +        assert_corr(it_state(it) == IAM_IT_ATTACHED ||
@@ -884,7 +892,10 @@ Index: iam/fs/ext3/iam.c
 +        leaf = &path->ip_leaf;
 +        obj  = iam_path_obj(path);
 +
++        assert_corr(iam_leaf_is_locked(leaf));
++
 +        result = 0;
++        do_corr(ik_orig = iam_it_ikey_get(it, iam_path_ikey(path, 2)));
 +        if (it_before(it)) {
 +                assert_corr(!iam_leaf_at_end(leaf));
 +                it->ii_state = IAM_IT_ATTACHED;
@@ -899,6 +910,7 @@ Index: iam/fs/ext3/iam.c
 +                        do_corr(schedule());
 +                        /* advance index portion of the path */
 +                        result = iam_index_next(iam_it_container(it), path);
++                        assert_corr(iam_leaf_is_locked(leaf));
 +                        if (result == 1) {
 +                                struct dynlock_handle *lh;
 +                                lh = dx_lock_htree(obj, path->ip_frame->leaf,
@@ -922,6 +934,7 @@ Index: iam/fs/ext3/iam.c
 +        }
 +        assert_corr(ergo(result == 0, it_state(it) == IAM_IT_ATTACHED));
 +        assert_corr(ergo(result >  0, it_state(it) == IAM_IT_DETACHED));
++        assert_corr(ergo(result == 0, it_ikeycmp(it, ik_orig) >= 0));
 +        return result;
 +}
 +EXPORT_SYMBOL(iam_it_next);
@@ -1347,7 +1360,7 @@ Index: iam/fs/ext3/iam.c
 + * Search container @c for record with key @k. If record is found, its data
 + * are moved into @r.
 + *
-+ * Return values: +ve: found, 0: not-found, -ve: error
++ * Return values: 0: found, -ENOENT: not-found, -ve: error
 + */
 +int iam_lookup(struct iam_container *c, const struct iam_key *k,
 +               struct iam_rec *r, struct iam_path_descr *pd)
index 6a7c496..8c55d7b 100644 (file)
@@ -101,7 +101,7 @@ Index: iam/fs/ext3/namei.c
                        BREAKPOINT();
        return 0;
                }
-@@ -241,12 +280,236 @@ struct stats dx_show_entries(struct dx_h
+@@ -241,12 +280,241 @@ struct stats dx_show_entries(struct dx_h
  }
  #endif /* DX_DEBUG */
  
@@ -302,9 +302,9 @@ Index: iam/fs/ext3/namei.c
 +       */
 +      result = 0;
 +      for (scan = path->ip_frames; scan < bottom; ++scan) {
-+              if (search) {
-+                      struct iam_entry *pos;
++              struct iam_entry *pos;
 +
++              if (search) {
 +                      if (dx_check_fast(path, scan) == 0)
 +                              continue;
 +
@@ -314,9 +314,14 @@ Index: iam/fs/ext3/namei.c
 +                              break;
 +                      }
 +                      scan->at = pos;
-+              } else if (scan->leaf != dx_get_block(path, scan->at)) {
-+                      result = -EAGAIN;
-+                      break;
++              } else {
++                      pos = iam_entry_shift(path, scan->entries,
++                                            dx_get_count(scan->entries) - 1);
++                      if (scan->at > pos ||
++                          scan->leaf != dx_get_block(path, scan->at)) {
++                              result = -EAGAIN;
++                              break;
++                      }
 +              }
 +      }
 +
@@ -340,7 +345,7 @@ Index: iam/fs/ext3/namei.c
  
        struct iam_descr *param;
        struct iam_frame *frame;
-@@ -255,20 +518,19 @@ int dx_lookup(struct iam_path *path)
+@@ -255,20 +523,19 @@ int dx_lookup(struct iam_path *path)
        param = iam_path_descr(path);
        c = path->ip_container;
        
@@ -371,7 +376,7 @@ Index: iam/fs/ext3/namei.c
                if (err != 0)
                        break;
  
-@@ -283,53 +545,83 @@ int dx_lookup(struct iam_path *path)
+@@ -283,53 +550,83 @@ int dx_lookup(struct iam_path *path)
                        break;
  
                assert_inv(dx_node_check(path, frame));
@@ -493,7 +498,7 @@ Index: iam/fs/ext3/namei.c
  /*
   * Probe for a directory leaf block to search.
   *
-@@ -339,7 +631,7 @@ int dx_lookup(struct iam_path *path)
+@@ -339,7 +636,7 @@ int dx_lookup(struct iam_path *path)
   * check for this error code, and make sure it never gets reflected
   * back to userspace.
   */
@@ -502,7 +507,7 @@ Index: iam/fs/ext3/namei.c
                    struct dx_hash_info *hinfo, struct iam_path *path)
  {
        int err;
-@@ -347,7 +639,7 @@ static int dx_probe(struct dentry *dentr
+@@ -347,7 +644,7 @@ static int dx_probe(struct dentry *dentr
        
        assert_corr(path->ip_data != NULL);
        ipc = container_of(path->ip_data, struct iam_path_compat, ipc_descr);
@@ -511,7 +516,7 @@ Index: iam/fs/ext3/namei.c
        ipc->ipc_hinfo = hinfo;
  
        assert_corr(dx_index_is_compat(path));
-@@ -356,6 +648,7 @@ static int dx_probe(struct dentry *dentr
+@@ -356,6 +653,7 @@ static int dx_probe(struct dentry *dentr
        return err;
  }
  
@@ -519,22 +524,25 @@ Index: iam/fs/ext3/namei.c
  /*
   * This function increments the frame pointer to search the next leaf
   * block, and reads in the necessary intervening nodes if the search
-@@ -391,10 +684,13 @@ static int ext3_htree_advance(struct ino
+@@ -391,10 +689,16 @@ static int ext3_htree_advance(struct ino
         * nodes need to be read.
         */
        while (1) {
 +              do_corr(schedule());
++              dx_lock_bh(p->bh);
                p->at = iam_entry_shift(path, p->at, +1);
                if (p->at < iam_entry_shift(path, p->entries,
 -                                         dx_get_count(p->entries)))
 +                                          dx_get_count(p->entries))) {
 +                      p->leaf = dx_get_block(path, p->at);
++                      dx_unlock_bh(p->bh);
                        break;
 +              }
++              dx_unlock_bh(p->bh);
                if (p == path->ip_frames)
                        return 0;
                num_frames++;
-@@ -409,7 +705,7 @@ static int ext3_htree_advance(struct ino
+@@ -409,7 +713,7 @@ static int ext3_htree_advance(struct ino
         * If the hash is 1, then continue only if the next page has a
         * continuation hash of any value.  This is used for readdir
         * handling.  Otherwise, check to see if the hash matches the
@@ -543,14 +551,16 @@ Index: iam/fs/ext3/namei.c
         * there's no point to read in the successive index pages.
         */
                iam_get_ikey(path, p->at, (struct iam_ikey *)&bhash);
-@@ -425,25 +721,91 @@ static int ext3_htree_advance(struct ino
+@@ -425,25 +729,126 @@ static int ext3_htree_advance(struct ino
         * block so no check is necessary
         */
        while (num_frames--) {
 +              iam_ptr_t idx;
 +
 +              do_corr(schedule());
++              dx_lock_bh(p->bh);
 +              idx = p->leaf = dx_get_block(path, p->at);
++              dx_unlock_bh(p->bh);
                err = iam_path_descr(path)->id_ops->
 -                      id_node_read(path->ip_container,
 -                                                   (iam_ptr_t)dx_get_block(path, p->at),
@@ -561,11 +571,16 @@ Index: iam/fs/ext3/namei.c
                ++p;
 -              brelse (p->bh);
 +              brelse(p->bh);
++              assert_corr(p->bh != bh);
                p->bh = bh;
                p->entries = dx_node_get_entries(path, p);
                p->at = iam_entry_shift(path, p->entries, !compat);
++              assert_corr(p->curidx != idx);
 +              p->curidx = idx;
++              dx_lock_bh(p->bh);
++              assert_corr(p->leaf != dx_get_block(path, p->at));
 +              p->leaf = dx_get_block(path, p->at);
++              dx_unlock_bh(p->bh);
                assert_inv(dx_node_check(path, p));
 +              assert(dx_bug11027_check(path, p));
        }
@@ -576,17 +591,13 @@ Index: iam/fs/ext3/namei.c
 +{
 +      struct iam_frame *f;
 +
-+      for (f = path->ip_frame; f >= path->ip_frames; --f) {
++      for (f = path->ip_frame; f >= path->ip_frames; --f, ++lh) {
 +              do_corr(schedule());
-+              *lh = dx_lock_htree(iam_path_obj(path), f->curidx, DLT_WRITE);
++              *lh = dx_lock_htree(iam_path_obj(path), f->curidx, DLT_READ);
 +              if (*lh == NULL)
 +                      return -ENOMEM;
-+              lh++;
-+              if (f->at < iam_entry_shift(path, f->entries,
-+                                          dx_get_count(f->entries) - 1))
-+                      return 1;
 +      }
-+      return 0; /* end of index... */
++      return 0;
 +}
 +
 +static int iam_index_advance(struct iam_path *path)
@@ -616,31 +627,63 @@ Index: iam/fs/ext3/namei.c
 +      while (1) {
 +              result = iam_index_lock(path, lh);
 +              do_corr(schedule());
-+              if (result <= 0) /* error, or end of index... */
++              if (result < 0)
 +                      break;
-+
++              
 +              result = dx_check_full_path(path, 0);
 +              if (result == 0 && cursor == path->ip_frame->leaf) {
 +                      result = iam_index_advance(path);
++
++                      assert_corr(result == 0 ||
++                                  cursor != path->ip_frame->leaf);
 +                      break;
 +              }
-+              dx_unlock_array(object, lh);
-+              iam_path_fini(path);
-+              do_corr(schedule());
-+              result = dx_lookup(path);
-+              while (path->ip_frame->leaf != cursor) {
++              do {
++                      dx_unlock_array(object, lh);
++
++                      iam_path_release(path);
 +                      do_corr(schedule());
-+                      result = iam_index_advance(path);
-+                      if (result <= 0)
++
++                      result = dx_lookup(path);
++                      if (result < 0)
 +                              break;
-+              }
++
++                      while (path->ip_frame->leaf != cursor) {
++                              do_corr(schedule());
++
++                              result = iam_index_lock(path, lh);
++                              do_corr(schedule());
++                              if (result < 0)
++                                      break;
++
++                              result = dx_check_full_path(path, 0);
++                              if (result != 0)
++                                      break;
++
++                              result = iam_index_advance(path);
++                              if (result == 0) {
++                                      ext3_error(object->i_sb, __FUNCTION__,
++                                                 "cannot find cursor: %u\n",
++                                                 cursor);
++                                      result = -EIO;
++                              }
++                              if (result < 0)
++                                      break;
++                              result = dx_check_full_path(path, 0);
++                              if (result != 0)
++                                      break;
++                              dx_unlock_array(object, lh);
++                      }
++              } while (result == -EAGAIN);
++              if (result < 0)
++                      break;
 +      }
 +      dx_unlock_array(object, lh);
 +      return result;
  }
  
  int ext3_htree_next_block(struct inode *dir, __u32 hash,
-@@ -649,14 +1011,26 @@ void iam_insert_key(struct iam_path *pat
+@@ -649,14 +1054,26 @@ void iam_insert_key(struct iam_path *pat
        struct iam_entry *new = iam_entry_shift(path, frame->at, +1);
        int count = dx_get_count(entries);
  
@@ -667,7 +710,7 @@ Index: iam/fs/ext3/namei.c
  }
  
  void dx_insert_block(struct iam_path *path, struct iam_frame *frame,
-@@ -882,7 +1256,7 @@ static struct buffer_head * ext3_dx_find
+@@ -882,7 +1299,7 @@ static struct buffer_head * ext3_dx_find
        sb = dir->i_sb;
        /* NFS may look up ".." - look at dx_root directory block */
        if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){
@@ -676,7 +719,7 @@ Index: iam/fs/ext3/namei.c
                if (*err != 0)
                        return NULL;
        } else {
-@@ -1114,7 +1488,7 @@ struct ext3_dir_entry_2 *move_entries(st
+@@ -1114,7 +1531,7 @@ struct ext3_dir_entry_2 *move_entries(st
        hash2 = map[split].hash;
        continued = hash2 == map[split - 1].hash;
        dxtrace(printk("Split block %i at %x, %i/%i\n",
@@ -685,7 +728,7 @@ Index: iam/fs/ext3/namei.c
  
        /* Fancy dance to stay within two buffers */
        de2 = dx_move_dirents(data1, data2, map + split, count - split);
-@@ -1484,16 +1858,38 @@ static int shift_entries(struct iam_path
+@@ -1484,16 +1901,38 @@ static int shift_entries(struct iam_path
               (char *) iam_entry_shift(path, entries, count1),
               count2 * iam_entry_size(path));
  
@@ -727,7 +770,7 @@ Index: iam/fs/ext3/namei.c
  {
  
        struct iam_entry *entries;   /* old block contents */
-@@ -1501,6 +1897,8 @@ int split_index_node(handle_t *handle, s
+@@ -1501,6 +1940,8 @@ int split_index_node(handle_t *handle, s
        struct iam_frame *frame, *safe;
        struct buffer_head *bh_new[DX_MAX_TREE_HEIGHT] = {0};
        u32 newblock[DX_MAX_TREE_HEIGHT] = {0};
@@ -736,7 +779,7 @@ Index: iam/fs/ext3/namei.c
        struct inode *dir = iam_path_obj(path);
        struct iam_descr *descr;
        int nr_splet;
-@@ -1523,12 +1921,14 @@ int split_index_node(handle_t *handle, s
+@@ -1523,12 +1964,14 @@ int split_index_node(handle_t *handle, s
         *   - first allocate all necessary blocks
         *
         *   - insert pointers into them atomically.
@@ -755,7 +798,7 @@ Index: iam/fs/ext3/namei.c
        dxtrace(printk("using %u of %u node entries\n",
                       dx_get_count(entries), dx_get_limit(entries)));
  
-@@ -1536,6 +1936,7 @@ int split_index_node(handle_t *handle, s
+@@ -1536,6 +1979,7 @@ int split_index_node(handle_t *handle, s
        for (nr_splet = 0; frame >= path->ip_frames &&
             dx_get_count(frame->entries) == dx_get_limit(frame->entries);
             --frame, ++nr_splet) {
@@ -763,7 +806,7 @@ Index: iam/fs/ext3/namei.c
                if (nr_splet == DX_MAX_TREE_HEIGHT) {
                        ext3_warning(dir->i_sb, __FUNCTION__,
                                     "Directory index full!\n");
-@@ -1545,14 +1946,53 @@ int split_index_node(handle_t *handle, s
+@@ -1545,14 +1989,53 @@ int split_index_node(handle_t *handle, s
        }
  
        safe = frame;
@@ -818,7 +861,7 @@ Index: iam/fs/ext3/namei.c
                BUFFER_TRACE(frame->bh, "get_write_access");
                err = ext3_journal_get_write_access(handle, frame->bh);
                if (err)
-@@ -1560,6 +2000,7 @@ int split_index_node(handle_t *handle, s
+@@ -1560,6 +2043,7 @@ int split_index_node(handle_t *handle, s
        }
        /* Add "safe" node to transaction too */
        if (safe + 1 != path->ip_frames) {
@@ -826,7 +869,7 @@ Index: iam/fs/ext3/namei.c
                err = ext3_journal_get_write_access(handle, safe->bh);
                if (err)
                        goto journal_error;
-@@ -1596,16 +2037,21 @@ int split_index_node(handle_t *handle, s
+@@ -1596,16 +2080,21 @@ int split_index_node(handle_t *handle, s
  
                        assert_corr(i == 0);
  
@@ -848,7 +891,7 @@ Index: iam/fs/ext3/namei.c
                        /* Shift frames in the path */
                        memmove(frames + 2, frames + 1,
                                (sizeof path->ip_frames) - 2 * sizeof frames[0]);
-@@ -1613,18 +2059,22 @@ int split_index_node(handle_t *handle, s
+@@ -1613,18 +2102,22 @@ int split_index_node(handle_t *handle, s
                        frames[1].at = iam_entry_shift(path, entries2, idx);
                        frames[1].entries = entries = entries2;
                        frames[1].bh = bh2;
@@ -871,7 +914,7 @@ Index: iam/fs/ext3/namei.c
                        count = shift_entries(path, frame, count,
                                              entries, entries2, newblock[i]);
                        /* Which index block gets the new entry? */
-@@ -1634,33 +2084,44 @@ int split_index_node(handle_t *handle, s
+@@ -1634,33 +2127,44 @@ int split_index_node(handle_t *handle, s
                                frame->at = iam_entry_shift(path, entries2,
                                                            idx - count + d);
                                frame->entries = entries = entries2;
@@ -917,7 +960,7 @@ Index: iam/fs/ext3/namei.c
        if (nr_splet > 0) {
                /*
                 * Log ->i_size modification.
-@@ -1674,6 +2135,12 @@ journal_error:
+@@ -1674,6 +2178,12 @@ journal_error:
        ext3_std_error(dir->i_sb, err);
  
  cleanup:
@@ -930,7 +973,7 @@ Index: iam/fs/ext3/namei.c
        for (i = 0; i < ARRAY_SIZE(bh_new); ++i) {
                if (bh_new[i] != NULL)
                        brelse(bh_new[i]);
-@@ -1695,18 +2162,18 @@ static int ext3_dx_add_entry(handle_t *h
+@@ -1695,18 +2205,18 @@ static int ext3_dx_add_entry(handle_t *h
        struct buffer_head * bh = NULL;
        struct inode *dir = dentry->d_parent->d_inode;
        struct ext3_dir_entry_2 *de;
@@ -951,7 +994,7 @@ Index: iam/fs/ext3/namei.c
        isize = dir->i_size;
  
        err = param->id_ops->id_node_read(path->ip_container,
-@@ -1726,7 +2193,7 @@ static int ext3_dx_add_entry(handle_t *h
+@@ -1726,7 +2236,7 @@ static int ext3_dx_add_entry(handle_t *h
                goto cleanup;
        }
        
@@ -960,7 +1003,7 @@ Index: iam/fs/ext3/namei.c
        if (err)
                goto cleanup;   
  
-@@ -1736,12 +2203,14 @@ static int ext3_dx_add_entry(handle_t *h
+@@ -1736,12 +2246,14 @@ static int ext3_dx_add_entry(handle_t *h
                goto cleanup;
  
        assert_inv(dx_node_check(path, frame));
@@ -1131,7 +1174,15 @@ Index: iam/include/linux/lustre_iam.h
        struct iam_path_descr ipc_descr;
          struct dx_hash_info   ipc_hinfo_area;
  };
-@@ -848,7 +867,36 @@ static inline struct iam_ikey *iam_path_
+@@ -554,6 +573,7 @@ struct iam_iterator {
+ void iam_path_init(struct iam_path *path, struct iam_container *c,
+                  struct iam_path_descr *pd);
+ void iam_path_fini(struct iam_path *path);
++void iam_path_release(struct iam_path *path);
+ void iam_path_compat_init(struct iam_path_compat *path, struct inode *inode);
+ void iam_path_compat_fini(struct iam_path_compat *path);
+@@ -848,7 +868,36 @@ static inline struct iam_ikey *iam_path_
        return path->ip_data->ipd_key_scratch[nr];
  }
  
@@ -1169,7 +1220,7 @@ Index: iam/include/linux/lustre_iam.h
  void dx_insert_block(struct iam_path *path, struct iam_frame *frame,
                     u32 hash, u32 block);
  int dx_index_is_compat(struct iam_path *path);
-@@ -858,7 +906,8 @@ int ext3_htree_next_block(struct inode *
+@@ -858,7 +907,8 @@ int ext3_htree_next_block(struct inode *
  
  struct buffer_head *ext3_append(handle_t *handle, struct inode *inode,
                                u32 *block, int *err);
@@ -1179,7 +1230,7 @@ Index: iam/include/linux/lustre_iam.h
  struct ext3_dir_entry_2 *split_entry(struct inode *dir,
                                     struct ext3_dir_entry_2 *de,
                                     unsigned long ino, mode_t mode,
-@@ -874,6 +923,10 @@ struct ext3_dir_entry_2 *move_entries(st
+@@ -874,6 +924,10 @@ struct ext3_dir_entry_2 *move_entries(st
  
  extern struct iam_descr iam_htree_compat_param;
  
@@ -1190,7 +1241,7 @@ Index: iam/include/linux/lustre_iam.h
  /*
   * external
   */
-@@ -889,7 +942,7 @@ int iam_read_leaf(struct iam_path *p);
+@@ -889,7 +943,7 @@ int iam_read_leaf(struct iam_path *p);
  int iam_node_read(struct iam_container *c, iam_ptr_t ptr,
                  handle_t *handle, struct buffer_head **bh);
  
index 9bfdf80..c8024c7 100644 (file)
@@ -14,16 +14,11 @@ Verified this patch on a 32 bit platform without CONFIG_LBD defined
 Signed-off-by: Mingming Cao<cmm@us.ibm.com>
 Acked-by: Andreas Dilger <adilger@clusterfs.com>
 Signed-off-by: Andrew Morton <akpm@osdl.org>
----
-
- fs/ext3/resize.c |   10 ++++++++++
- fs/ext3/super.c  |   10 ++++++++++
- 2 files changed, 20 insertions(+)
-
-diff -puN fs/ext3/resize.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem fs/ext3/resize.c
---- devel/fs/ext3/resize.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem        2006-05-22 14:09:53.000000000 -0700
-+++ devel-akpm/fs/ext3/resize.c        2006-05-22 14:10:56.000000000 -0700
-@@ -926,6 +926,16 @@ int ext3_group_extend(struct super_block
+Index: iam/fs/ext3/resize.c
+===================================================================
+--- iam.orig/fs/ext3/resize.c
++++ iam/fs/ext3/resize.c
+@@ -914,6 +914,16 @@ int ext3_group_extend(struct super_block
        if (n_blocks_count == 0 || n_blocks_count == o_blocks_count)
                return 0;
  
@@ -40,10 +35,11 @@ diff -puN fs/ext3/resize.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem
        if (n_blocks_count < o_blocks_count) {
                ext3_warning(sb, __FUNCTION__,
                             "can't shrink FS - resize aborted");
-diff -puN fs/ext3/super.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem fs/ext3/super.c
---- devel/fs/ext3/super.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem 2006-05-22 14:09:53.000000000 -0700
-+++ devel-akpm/fs/ext3/super.c 2006-05-22 14:11:10.000000000 -0700
-@@ -1565,6 +1565,17 @@ static int ext3_fill_super (struct super
+Index: iam/fs/ext3/super.c
+===================================================================
+--- iam.orig/fs/ext3/super.c
++++ iam/fs/ext3/super.c
+@@ -1530,6 +1530,17 @@ static int ext3_fill_super (struct super
                goto failed_mount;
        }
  
@@ -61,4 +57,3 @@ diff -puN fs/ext3/super.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem f
        sbi->s_groups_count = (le32_to_cpu(es->s_blocks_count) -
                               le32_to_cpu(es->s_first_data_block) +
                               EXT3_BLOCKS_PER_GROUP(sb) - 1) /
-_