Whamcloud - gitweb
fix iam defects that caused 11011/mdsrate failures:
authornikita <nikita>
Mon, 2 Oct 2006 20:36:09 +0000 (20:36 +0000)
committernikita <nikita>
Mon, 2 Oct 2006 20:36:09 +0000 (20:36 +0000)
 - defect: split_index_node(): update ->at in new root node.

 - defect: split_index_node(): index node split: new node should contain
 header.

 - defect: split_index_node(): take dx_countlimit into account when setting frame->at of newly split node.

 - defect: shift_entries(): adjust entry count in the new node.

lustre/kernel_patches/patches/ext3-iam-separate.patch
lustre/kernel_patches/patches/ext3-iam-uapi.patch
lustre/kernel_patches/patches/ext3-orphans-delay.patch

index cd7cbdf..b43450f 100644 (file)
@@ -1,8 +1,8 @@
-Index: linux-stage/fs/ext3/Makefile
+Index: iam/fs/ext3/Makefile
 ===================================================================
---- linux-stage.orig/fs/ext3/Makefile  2006-09-27 15:48:48.000000000 +0800
-+++ linux-stage/fs/ext3/Makefile       2006-09-27 15:49:15.000000000 +0800
-@@ -6,7 +6,7 @@
+--- iam.orig/fs/ext3/Makefile  2006-09-28 22:11:14.000000000 +0400
++++ iam/fs/ext3/Makefile       2006-10-03 00:15:55.000000000 +0400
+@@ -6,7 +6,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o
  
  ext3-y        := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
           ioctl.o namei.o super.o symlink.o hash.o resize.o \
@@ -11,11 +11,11 @@ Index: linux-stage/fs/ext3/Makefile
  
  ext3-$(CONFIG_EXT3_FS_XATTR)   += xattr.o xattr_user.o xattr_trusted.o
  ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
-Index: linux-stage/fs/ext3/iam.c
+Index: iam/fs/ext3/iam.c
 ===================================================================
---- linux-stage.orig/fs/ext3/iam.c     2006-05-31 09:15:07.000000000 +0800
-+++ linux-stage/fs/ext3/iam.c  2006-09-27 15:49:15.000000000 +0800
-@@ -0,0 +1,1325 @@
+--- iam.orig/fs/ext3/iam.c     2004-04-06 17:27:52.000000000 +0400
++++ iam/fs/ext3/iam.c  2006-10-02 19:59:04.000000000 +0400
+@@ -0,0 +1,1326 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
 + *
@@ -1033,6 +1033,7 @@ Index: linux-stage/fs/ext3/iam.c
 +        if (err == 0) {
 +                if (!iam_leaf_can_add(leaf, k, r)) {
 +                        err = split_index_node(handle, path);
++                        assert(iam_path_check(path));
 +                        if (err == 0) {
 +                                err = iam_new_leaf(handle, leaf);
 +                                /*
@@ -1341,10 +1342,10 @@ Index: linux-stage/fs/ext3/iam.c
 +}
 +EXPORT_SYMBOL(iam_delete);
 +
-Index: linux-stage/fs/ext3/iam_htree.c
+Index: iam/fs/ext3/iam_htree.c
 ===================================================================
---- linux-stage.orig/fs/ext3/iam_htree.c       2006-05-31 09:15:07.000000000 +0800
-+++ linux-stage/fs/ext3/iam_htree.c    2006-09-27 15:49:15.000000000 +0800
+--- iam.orig/fs/ext3/iam_htree.c       2004-04-06 17:27:52.000000000 +0400
++++ iam/fs/ext3/iam_htree.c    2006-09-28 22:11:15.000000000 +0400
 @@ -0,0 +1,665 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -2011,11 +2012,11 @@ Index: linux-stage/fs/ext3/iam_htree.c
 +{
 +        iam_format_register(&iam_htree_format);
 +}
-Index: linux-stage/fs/ext3/iam_lfix.c
+Index: iam/fs/ext3/iam_lfix.c
 ===================================================================
---- linux-stage.orig/fs/ext3/iam_lfix.c        2006-05-31 09:15:07.000000000 +0800
-+++ linux-stage/fs/ext3/iam_lfix.c     2006-09-27 15:49:15.000000000 +0800
-@@ -0,0 +1,670 @@
+--- iam.orig/fs/ext3/iam_lfix.c        2004-04-06 17:27:52.000000000 +0400
++++ iam/fs/ext3/iam_lfix.c     2006-10-02 16:34:29.000000000 +0400
+@@ -0,0 +1,673 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
 + *
@@ -2519,7 +2520,10 @@ Index: linux-stage/fs/ext3/iam_lfix.c
 +        root = (void *)frame->bh->b_data;
 +        assert(le64_to_cpu(root->ilr_magic) == IAM_LFIX_ROOT_MAGIC);
 +        root->ilr_indirect_levels ++;
-+        return iam_entry_shift(path, entries, 1);
++        frame->at = entries = iam_entry_shift(path, entries, 1);
++        memset(iam_ikey_at(path, entries), 0,
++               iam_path_descr(path)->id_ikey_size);
++        return entries;
 +}
 +
 +static int iam_lfix_node_check(struct iam_path *path, struct iam_frame *frame)
@@ -2686,11 +2690,11 @@ Index: linux-stage/fs/ext3/iam_lfix.c
 +                char rec[RECSIZE];
 +        } ll_entry[LFIX_LEAF_RECNO];
 +};
-Index: linux-stage/fs/ext3/iam_lvar.c
+Index: iam/fs/ext3/iam_lvar.c
 ===================================================================
---- linux-stage.orig/fs/ext3/iam_lvar.c        2006-05-31 09:15:07.000000000 +0800
-+++ linux-stage/fs/ext3/iam_lvar.c     2006-09-27 15:51:04.000000000 +0800
-@@ -0,0 +1,897 @@
+--- iam.orig/fs/ext3/iam_lvar.c        2004-04-06 17:27:52.000000000 +0400
++++ iam/fs/ext3/iam_lvar.c     2006-10-02 16:33:55.000000000 +0400
+@@ -0,0 +1,900 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
 + *
@@ -3098,9 +3102,9 @@ Index: linux-stage/fs/ext3/iam_lvar.c
 +{
 +        lvar_hash_t hash;
 +        const char *name;
-+        
++
 +        name = kchar(k);
-+       
++
 +        hash = get_hash(iam_leaf_container(l), name, strlen(name));
 +        return e_cmp(l, n_cur(l), hash);
 +}
@@ -3332,7 +3336,10 @@ Index: linux-stage/fs/ext3/iam_lvar.c
 +        root = (void *)frame->bh->b_data;
 +        assert(le64_to_cpu(root->vr_magic) == IAM_LVAR_ROOT_MAGIC);
 +        root->vr_indirect_levels ++;
-+        return iam_entry_shift(path, entries, 1);
++        frame->at = entries = iam_entry_shift(path, entries, 1);
++        memset(iam_ikey_at(path, entries), 0,
++               iam_path_descr(path)->id_ikey_size);
++        return entries;
 +}
 +
 +static int lvar_node_check(struct iam_path *path, struct iam_frame *frame)
@@ -3588,10 +3595,10 @@ Index: linux-stage/fs/ext3/iam_lvar.c
 +        iam_format_register(&lvar_format);
 +}
 +
-Index: linux-stage/fs/ext3/namei.c
+Index: iam/fs/ext3/namei.c
 ===================================================================
---- linux-stage.orig/fs/ext3/namei.c   2006-09-27 15:49:15.000000000 +0800
-+++ linux-stage/fs/ext3/namei.c        2006-09-27 15:49:15.000000000 +0800
+--- iam.orig/fs/ext3/namei.c   2006-09-28 22:11:15.000000000 +0400
++++ iam/fs/ext3/namei.c        2006-10-02 22:39:52.000000000 +0400
 @@ -24,81 +24,6 @@
   *    Theodore Ts'o, 2002
   */
@@ -3699,7 +3706,7 @@ Index: linux-stage/fs/ext3/namei.c
  {
        struct buffer_head *bh;
  
-@@ -136,14 +61,15 @@
+@@ -136,14 +61,15 @@ static struct buffer_head *ext3_append(h
        if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
                inode->i_size += inode->i_sb->s_blocksize;
                EXT3_I(inode)->i_disksize = inode->i_size;
@@ -3719,7 +3726,7 @@ Index: linux-stage/fs/ext3/namei.c
  
  #ifndef swap
  #define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
-@@ -155,293 +81,10 @@
+@@ -155,293 +81,10 @@ static struct buffer_head *ext3_append(h
  #define dxtrace(command)
  #endif
  
@@ -4013,7 +4020,7 @@ Index: linux-stage/fs/ext3/namei.c
  static unsigned dx_get_limit(struct iam_entry *entries);
  static void dx_set_count(struct iam_entry *entries, unsigned value);
  static void dx_set_limit(struct iam_entry *entries, unsigned value);
-@@ -457,264 +100,52 @@
+@@ -457,264 +100,53 @@ static void dx_sort_map(struct dx_map_en
  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);
@@ -4179,6 +4186,7 @@ Index: linux-stage/fs/ext3/namei.c
        e = dx_node_get_entries(p, f);
        count = dx_get_count(e);
        e = iam_entry_shift(p, e, 1);
++
 +      inode = iam_path_obj(p);
        for (i = 0; i < count - 1; ++i, e = iam_entry_shift(p, e, 1)) {
 -              keycpy(c, p->ip_key_scratch[0], p->ip_key_scratch[1]);
@@ -4295,10 +4303,14 @@ Index: linux-stage/fs/ext3/namei.c
  }
  
  /*
-@@ -800,598 +231,132 @@
- }
- #endif /* DX_DEBUG */
+@@ -796,602 +228,120 @@ struct stats dx_show_entries(struct dx_h
+       if (bcount)
+               printk("%snames %u, fullness %u (%u%%)\n", levels?"":"   ",
+                       names, space/bcount,(space/bcount)*100/blocksize);
+-      return (struct stats) { names, space, bcount};
+-}
+-#endif /* DX_DEBUG */
+-
 -static int dx_lookup(struct iam_path *path)
 -{
 -      u32 ptr;
@@ -4735,12 +4747,7 @@ Index: linux-stage/fs/ext3/namei.c
 -              .hinfo  = &hinfo
 -      };
 -      int err, i;
-+int dx_lookup(struct iam_path *path)
-+{
-+      u32 ptr;
-+      int err = 0;
-+      int i;
+-
 -      iam_path_init(path, c, &hc);
 -      for (i = 0; i < ARRAY_SIZE(path->ip_key_scratch); ++i)
 -              path->ip_key_scratch[i] =
@@ -4748,16 +4755,89 @@ Index: linux-stage/fs/ext3/namei.c
 -      err = dx_lookup(path);
 -      if (err)
 -              goto errout; 
+-
+-      err = iam_leaf_insert(handle, path, k, r);
+-      
+-      if (err != -ENOSPC) 
+-              goto errout;    
+-
+-      err = split_index_node(handle, path);
+-      if (err)
+-              goto errout;    
+-
+-      err = split_leaf_node(handle, path);
+-      if (err)
+-              goto errout;
+-      
+-      err = iam_leaf_insert(handle, path, k, r);
+-errout:
+-      iam_path_fini(path);
+-      return(err);
++      return (struct stats) { names, space, bcount};
+ }
++#endif /* DX_DEBUG */
+-EXPORT_SYMBOL(iam_insert);
+-static int iam_leaf_delete(handle_t *handle, struct iam_path *path, 
+-                         struct iam_key *k)
++int dx_lookup(struct iam_path *path)
+ {
+-      struct iam_leaf leaf;
+-      struct iam_leaf_entry *p, *q;
+-      int err, count;
+-
+-      err = iam_leaf_init(path, &leaf);
+-      if (err)
+-              goto errout;
+-      
+-      err = iam_leaf_lookup(path, &leaf, k);
+-      if (err)
+-              goto errout;
+-
+-      count = dx_get_count((struct iam_entry*)leaf.entries);
+-      /*delete the k to leaf entries*/
+-      p = iam_leaf_entry_shift(path, leaf.at, 1);
+-      q = iam_leaf_entry_shift(path, leaf.entries, count - 1);
+-      while (p < q) {
+-              memcpy(p, iam_leaf_entry_shift(path, p, 1), iam_leaf_entry_size(path));
+-              p = iam_leaf_entry_shift(path, p, 1);
+-      }
+-      dx_set_count((struct iam_entry*)leaf.entries, count - 1);
++      u32 ptr;
++      int err = 0;
++      int i;
+-      err = ext3_journal_dirty_metadata(handle, leaf.bh);
+-      if (err)
+-              ext3_std_error(path_obj(path)->i_sb, err);
+-errout:       
+-      iam_leaf_fini(&leaf);
+-      return err;
+-}
 +      struct iam_descr *param;
 +      struct iam_frame *frame;
 +      struct iam_container *c;
  
--      err = iam_leaf_insert(handle, path, k, r);
+-/*
+- * Delete existing record with key @k.
+- *
+- * Return values: 0: success, -ENOENT: not-found, -ve: other error.
+- *
+- * postcondition: ergo(result == 0 || result == -ENOENT,
+- *                                 !iam_lookup(c, k, *));
+- */
+-int iam_delete(handle_t *h, struct iam_container *c, struct iam_key *k)
+-{
+-      struct dx_hash_info     hinfo;
+-      struct iam_path_compat cpath;
+-      struct iam_path *path = &cpath.ipc_path;
+-      struct htree_cookie hc = {
+-              .hinfo  = &hinfo
+-      };
+-      int err, i;
 +      param = iam_path_descr(path);
 +      c = path->ip_container;
-       
--      if (err != -ENOSPC) 
--              goto errout;    
++      
 +      for (frame = path->ip_frames, i = 0,
 +                   ptr = param->id_ops->id_root_ptr(c);
 +           i <= path->ip_indirect;
@@ -4768,38 +4848,39 @@ Index: linux-stage/fs/ext3/namei.c
 +              struct iam_entry *m;
 +              unsigned count;
  
--      err = split_index_node(handle, path);
+-      iam_path_init(path, c, &hc);
+-      for (i = 0; i < ARRAY_SIZE(path->ip_key_scratch); ++i)
+-              path->ip_key_scratch[i] =
+-                      (struct iam_key *)&cpath.ipc_scrach[i];
+-      err = dx_lookup(path);
 -      if (err)
--              goto errout;    
+-              goto errout; 
 +              err = param->id_ops->id_node_read(c, (iam_ptr_t)ptr, NULL,
 +                                                &frame->bh);
 +              if (err != 0)
 +                      break;
  
--      err = split_leaf_node(handle, path);
--      if (err)
--              goto errout;
--      
--      err = iam_leaf_insert(handle, path, k, r);
+-      err = iam_leaf_delete(h, path, k);
 -errout:
 -      iam_path_fini(path);
--      return(err);
+-      return err;
 -}
 +              err = param->id_ops->id_node_check(path, frame);
 +              if (err != 0)
 +                      break;
  
--EXPORT_SYMBOL(iam_insert);
--static int iam_leaf_delete(handle_t *handle, struct iam_path *path, 
--                         struct iam_key *k)
--{
--      struct iam_leaf leaf;
--      struct iam_leaf_entry *p, *q;
--      int err, count;
+-EXPORT_SYMBOL(iam_delete);
 +              err = param->id_ops->id_node_load(path, frame);
 +              if (err != 0)
 +                      break;
  
+-static int iam_leaf_update(handle_t *handle, struct iam_path *path, 
+-                         struct iam_key *k, struct iam_rec *r)
+-{
+-      struct iam_leaf leaf;
+-      int err;
++              assert(dx_node_check(path, frame));
 -      err = iam_leaf_init(path, &leaf);
 -      if (err)
 -              goto errout;
@@ -4807,38 +4888,11 @@ Index: linux-stage/fs/ext3/namei.c
 -      err = iam_leaf_lookup(path, &leaf, k);
 -      if (err)
 -              goto errout;
-+              assert(dx_node_check(path, frame));
--      count = dx_get_count((struct iam_entry*)leaf.entries);
--      /*delete the k to leaf entries*/
--      p = iam_leaf_entry_shift(path, leaf.at, 1);
--      q = iam_leaf_entry_shift(path, leaf.entries, count - 1);
--      while (p < q) {
--              memcpy(p, iam_leaf_entry_shift(path, p, 1), iam_leaf_entry_size(path));
--              p = iam_leaf_entry_shift(path, p, 1);
--      }
--      dx_set_count((struct iam_entry*)leaf.entries, count - 1);
 +              entries = frame->entries;
 +              count = dx_get_count(entries);
 +              assert(count && count <= dx_get_limit(entries));
 +              p = iam_entry_shift(path, entries, 1);
 +              q = iam_entry_shift(path, entries, count - 1);
-+              /*
-+               * Sanity check: target key is larger or equal to the leftmost
-+               * key in the node.
-+               */
-+              if (!dx_index_is_compat(path) &&
-+                  iam_ikeycmp(c, iam_ikey_at(path, p),
-+                              path->ip_ikey_target) > 0) {
-+                      struct inode *obj;
-+
-+                      obj = c->ic_object;
-+                      ext3_error(obj->i_sb, __FUNCTION__,
-+                                 "corrupted search tree #%lu", obj->i_ino);
-+                      err = -EIO;
-+                      break;
-+                      
-+              }
 +              while (p <= q) {
 +                      m = iam_entry_shift(path,
 +                                         p, iam_entry_diff(path, q, p) / 2);
@@ -4850,16 +4904,18 @@ Index: linux-stage/fs/ext3/namei.c
 +                              p = iam_entry_shift(path, m, +1);
 +              }
  
+-      memcpy(iam_leaf_entry_at(path, leaf.at), r, path_descr(path)->id_rec_size);
+-      memcpy(iam_leaf_key_at(path, leaf.at), k, path_descr(path)->id_key_size);
++              frame->at = iam_entry_shift(path, p, -1);
++              if (1) { // linear search cross check
++                      unsigned n = count - 1;
++                      struct iam_entry *at;
 -      err = ext3_journal_dirty_metadata(handle, leaf.bh);
 -      if (err)
 -              ext3_std_error(path_obj(path)->i_sb, err);
 -errout:       
 -      iam_leaf_fini(&leaf);
-+              frame->at = iam_entry_shift(path, p, -1);
-+              if (1) { // linear search cross check
-+                      unsigned n = count - 1;
-+                      struct iam_entry *at;
-+
 +                      at = entries;
 +                      while (n--) {
 +                              dxtrace(printk(","));
@@ -4884,23 +4940,27 @@ Index: linux-stage/fs/ext3/namei.c
 +      path->ip_frame = --frame;
        return err;
  }
++
  /*
-- * Delete existing record with key @k.
+- * Replace existing record with key @k, or insert new one. New record data are
+- * in @r.
 - *
-- * Return values: 0: success, -ENOENT: not-found, -ve: other error.
+- * Return values: 0: success, -ve: error.
 + * Probe for a directory leaf block to search.
   *
-- * postcondition: ergo(result == 0 || result == -ENOENT,
-- *                                 !iam_lookup(c, k, *));
+- * postcondition: ergo(result == 0, iam_lookup(c, k, r2) > 0 &&
+- *                                  !memcmp(r, r2, c->ic_descr->id_rec_size));
 + * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
 + * error in the directory index, and the caller should fall back to
 + * searching the directory normally.  The callers of dx_probe **MUST**
 + * check for this error code, and make sure it never gets reflected
 + * back to userspace.
   */
--int iam_delete(handle_t *h, struct iam_container *c, struct iam_key *k)
--{
+-int iam_update(handle_t *h, struct iam_container *c,
+-             struct iam_key *k, struct iam_rec *r)
++static int dx_probe(struct dentry *dentry, struct inode *dir,
++                  struct dx_hash_info *hinfo, struct iam_path *path)
+ {
 -      struct dx_hash_info     hinfo;
 -      struct iam_path_compat cpath;
 -      struct iam_path *path = &cpath.ipc_path;
@@ -4908,7 +4968,7 @@ Index: linux-stage/fs/ext3/namei.c
 -              .hinfo  = &hinfo
 -      };
 -      int err, i;
--
+-      
 -      iam_path_init(path, c, &hc);
 -      for (i = 0; i < ARRAY_SIZE(path->ip_key_scratch); ++i)
 -              path->ip_key_scratch[i] =
@@ -4916,78 +4976,19 @@ Index: linux-stage/fs/ext3/namei.c
 -      err = dx_lookup(path);
 -      if (err)
 -              goto errout; 
--
--      err = iam_leaf_delete(h, path, k);
--errout:
--      iam_path_fini(path);
--      return err;
--}
--
--EXPORT_SYMBOL(iam_delete);
--
--static int iam_leaf_update(handle_t *handle, struct iam_path *path, 
--                         struct iam_key *k, struct iam_rec *r)
-+static int dx_probe(struct dentry *dentry, struct inode *dir,
-+                  struct dx_hash_info *hinfo, struct iam_path *path)
- {
--      struct iam_leaf leaf;
-       int err;
++      int err;
 +      struct iam_path_compat *ipc;
  
--      err = iam_leaf_init(path, &leaf);
--      if (err)
--              goto errout;
--      
--      err = iam_leaf_lookup(path, &leaf, k);
--      if (err)
--              goto errout;
--
--      memcpy(iam_leaf_entry_at(path, leaf.at), r, path_descr(path)->id_rec_size);
--      memcpy(iam_leaf_key_at(path, leaf.at), k, path_descr(path)->id_key_size);
+-      err = iam_leaf_update(h, path, k, r);
+-errout:
+-      iam_path_fini(path);
 +      assert(path->ip_data != NULL);
 +      ipc = container_of(path->ip_data, struct iam_path_compat, ipc_descr);
 +      ipc->ipc_dentry = dentry;
 +      ipc->ipc_hinfo = hinfo;
--      err = ext3_journal_dirty_metadata(handle, leaf.bh);
--      if (err)
--              ext3_std_error(path_obj(path)->i_sb, err);
--errout:       
--      iam_leaf_fini(&leaf);
--      return err;
--}
--/*
-- * Replace existing record with key @k, or insert new one. New record data are
-- * in @r.
-- *
-- * Return values: 0: success, -ve: error.
-- *
-- * postcondition: ergo(result == 0, iam_lookup(c, k, r2) > 0 &&
-- *                                  !memcmp(r, r2, c->ic_descr->id_rec_size));
-- */
--int iam_update(handle_t *h, struct iam_container *c,
--             struct iam_key *k, struct iam_rec *r)
--{
--      struct dx_hash_info     hinfo;
--      struct iam_path_compat cpath;
--      struct iam_path *path = &cpath.ipc_path;
--      struct htree_cookie hc = {
--              .hinfo  = &hinfo
--      };
--      int err, i;
--      
--      iam_path_init(path, c, &hc);
--      for (i = 0; i < ARRAY_SIZE(path->ip_key_scratch); ++i)
--              path->ip_key_scratch[i] =
--                      (struct iam_key *)&cpath.ipc_scrach[i];
++
 +      assert(dx_index_is_compat(path));
-       err = dx_lookup(path);
--      if (err)
--              goto errout; 
--
--      err = iam_leaf_update(h, path, k, r);
--errout:
--      iam_path_fini(path);
++      err = dx_lookup(path);
 +      assert(err != 0 || path->ip_frames[path->ip_indirect].bh != NULL);
        return err;
  }
@@ -4997,7 +4998,7 @@ Index: linux-stage/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
-@@ -1409,16 +374,15 @@
+@@ -1409,16 +359,15 @@ EXPORT_SYMBOL(iam_update);
   * If start_hash is non-null, it will be filled in with the starting
   * hash of the next page.
   */
@@ -5017,7 +5018,7 @@ Index: linux-stage/fs/ext3/namei.c
        p = path->ip_frame;
        /*
         * Find the next leaf page by incrementing the frame pointer.
-@@ -1438,28 +402,34 @@
+@@ -1438,28 +387,34 @@ static int ext3_htree_next_block(struct 
                --p;
        }
  
@@ -5068,7 +5069,7 @@ Index: linux-stage/fs/ext3/namei.c
                if (err != 0)
                        return err; /* Failure */
                ++p;
-@@ -1471,6 +441,16 @@
+@@ -1471,6 +426,16 @@ static int ext3_htree_next_block(struct 
        return 1;
  }
  
@@ -5085,7 +5086,7 @@ Index: linux-stage/fs/ext3/namei.c
  
  /*
   * p is at least 6 bytes before the end of page
-@@ -1662,21 +642,30 @@
+@@ -1662,21 +627,30 @@ static void dx_sort_map (struct dx_map_e
        } while(more);
  }
  
@@ -5122,7 +5123,7 @@ Index: linux-stage/fs/ext3/namei.c
  #endif
  
  
-@@ -1897,14 +886,15 @@
+@@ -1897,14 +871,15 @@ static struct buffer_head * ext3_dx_find
                if (*err != 0)
                        return NULL;
        } else {
@@ -5141,7 +5142,7 @@ Index: linux-stage/fs/ext3/namei.c
                if (*err != 0)
                        goto errout;
                de = (struct ext3_dir_entry_2 *) bh->b_data;
-@@ -2093,22 +1083,69 @@
+@@ -2093,22 +1068,69 @@ static struct ext3_dir_entry_2* dx_pack_
        return prev;
  }
  
@@ -5218,7 +5219,7 @@ Index: linux-stage/fs/ext3/namei.c
        int     err;
  
        bh2 = ext3_append (handle, dir, &newblock, error);
-@@ -2133,35 +1170,9 @@
+@@ -2133,35 +1155,9 @@ static struct ext3_dir_entry_2 *do_split
        if (err)
                goto journal_error;
  
@@ -5256,7 +5257,7 @@ Index: linux-stage/fs/ext3/namei.c
        err = ext3_journal_dirty_metadata (handle, bh2);
        if (err)
                goto journal_error;
-@@ -2175,6 +1186,67 @@
+@@ -2175,6 +1171,67 @@ errout:
  }
  #endif
  
@@ -5324,7 +5325,7 @@ Index: linux-stage/fs/ext3/namei.c
  
  /*
   * Add a new entry into a directory (leaf) block.  If de is non-NULL,
-@@ -2194,34 +1266,16 @@
+@@ -2194,34 +1251,16 @@ static int add_dirent_to_buf(handle_t *h
        struct inode    *dir = dentry->d_parent->d_inode;
        const char      *name = dentry->d_name.name;
        int             namelen = dentry->d_name.len;
@@ -5366,7 +5367,7 @@ Index: linux-stage/fs/ext3/namei.c
        }
        BUFFER_TRACE(bh, "get_write_access");
        err = ext3_journal_get_write_access(handle, bh);
-@@ -2232,22 +1286,9 @@
+@@ -2232,22 +1271,9 @@ static int add_dirent_to_buf(handle_t *h
        }
  
        /* By now the buffer is marked for journaling */
@@ -5392,9 +5393,42 @@ Index: linux-stage/fs/ext3/namei.c
        /*
         * XXX shouldn't update any times until successful
         * completion of syscall, but too many callers depend
-@@ -2424,18 +1465,25 @@
+@@ -2423,19 +1449,58 @@ static int ext3_add_entry (handle_t *han
+       return add_dirent_to_buf(handle, dentry, inode, de, bh);
  }
  
++static int shift_entries(struct iam_path *path,
++                       struct iam_frame *frame, unsigned count,
++                       struct iam_entry *entries, struct iam_entry *entries2,
++                       u32 newblock)
++{
++      unsigned count1;
++      unsigned count2;
++      int delta;
++
++      struct iam_frame *parent = frame - 1;
++      struct iam_ikey *pivot = iam_path_ikey(path, 3);
++
++      delta = dx_index_is_compat(path) ? 0 : +1;
++
++      count1 = count/2 + delta;
++      count2 = count - count1;
++      iam_get_ikey(path, iam_entry_shift(path, entries, count1), pivot);
++
++      dxtrace(printk("Split index %i/%i\n", count1, count2));
++
++      memcpy((char *) iam_entry_shift(path, entries2, delta),
++             (char *) iam_entry_shift(path, entries, count1),
++             count2 * iam_entry_size(path));
++
++      dx_set_count(entries, count1);
++      dx_set_count(entries2, count2 + delta);
++      dx_set_limit(entries2, dx_node_limit(path));
++
++      iam_insert_key(path, parent, pivot, newblock);
++      return count1;
++}
++
  #ifdef CONFIG_EXT3_INDEX
 -static int split_index_node(handle_t *handle, struct iam_path *path)
 -{ 
@@ -5421,7 +5455,7 @@ Index: linux-stage/fs/ext3/namei.c
        frame = path->ip_frame;
        entries = frame->entries;
  
-@@ -2474,7 +1522,8 @@
+@@ -2474,7 +1539,8 @@ static int split_index_node(handle_t *ha
        for (frame = safe + 1, i = 0; i < nr_splet; ++i, ++frame) {
                bh_new[i] = ext3_append (handle, dir, &newblock[i], &err);
                if (!bh_new[i] ||
@@ -5431,7 +5465,7 @@ Index: linux-stage/fs/ext3/namei.c
                        goto cleanup;
                BUFFER_TRACE(frame->bh, "get_write_access");
                err = ext3_journal_get_write_access(handle, frame->bh);
-@@ -2493,6 +1542,7 @@
+@@ -2493,6 +1559,7 @@ static int split_index_node(handle_t *ha
                unsigned count;
                int idx;
                struct buffer_head *bh2;
@@ -5439,7 +5473,7 @@ Index: linux-stage/fs/ext3/namei.c
  
                entries = frame->entries;
                count = dx_get_count(entries);
-@@ -2501,6 +1551,7 @@
+@@ -2501,6 +1568,7 @@ static int split_index_node(handle_t *ha
                bh2 = bh_new[i];
                entries2 = dx_get_entries(path, bh2->b_data, 0);
  
@@ -5447,7 +5481,7 @@ Index: linux-stage/fs/ext3/namei.c
                if (frame == path->ip_frames) {
                        /* splitting root node. Tricky point:
                         *
-@@ -2512,22 +1563,20 @@
+@@ -2512,22 +1580,20 @@ static int split_index_node(handle_t *ha
                         * capacity of the root node is smaller than that of
                         * non-root one.
                         */
@@ -5476,12 +5510,12 @@ Index: linux-stage/fs/ext3/namei.c
  
                        /* Shift frames in the path */
                        memmove(frames + 2, frames + 1,
-@@ -2537,20 +1586,21 @@
+@@ -2537,48 +1603,60 @@ static int split_index_node(handle_t *ha
                        frames[1].entries = entries = entries2;
                        frames[1].bh = bh2;
                        assert(dx_node_check(path, frame));
--                      ++ frame;
-+                      path->ip_frame = ++ frame;
++                      ++ path->ip_frame;
+                       ++ frame;
                        assert(dx_node_check(path, frame));
 -                      bh_new[i] = NULL; /* buffer head is "consumed" */
 +                      bh_new[0] = NULL; /* buffer head is "consumed" */
@@ -5490,26 +5524,40 @@ Index: linux-stage/fs/ext3/namei.c
                                goto journal_error;
                } else {
                        /* splitting non-root index node. */
-                       unsigned count1 = count/2, count2 = count - count1;
+-                      unsigned count1 = count/2, count2 = count - count1;
 -                      unsigned hash2;
-+                      struct iam_ikey *pivot = iam_path_ikey(path, 3);
-+                      struct iam_frame *parent = frame - 1;
+-
 -                      dx_get_key(path,
 -                                 iam_entry_shift(path, entries, count1),
 -                                 (struct iam_key *)&hash2);
-+                      iam_get_ikey(path,
-+                                   iam_entry_shift(path, entries, count1),
-+                                   pivot);
-                       dxtrace(printk("Split index %i/%i\n", count1, count2));
+-
+-                      dxtrace(printk("Split index %i/%i\n", count1, count2));
+-
+-                      memcpy ((char *) entries2,
+-                              (char *) iam_entry_shift(path, entries, count1),
+-                              count2 * iam_entry_size(path));
+-                      dx_set_count (entries, count1);
+-                      dx_set_count (entries2, count2);
+-                      dx_set_limit (entries2, dx_node_limit(path));
++                      struct iam_frame *parent = frame - 1;
  
-@@ -2569,16 +1619,36 @@
++                      count = shift_entries(path, frame, count,
++                                            entries, entries2, newblock[i]);
+                       /* Which index block gets the new entry? */
+-                      if (idx >= count1) {
++                      if (idx >= count) {
++                              int d = dx_index_is_compat(path) ? 0 : +1;
++
+                               frame->at = iam_entry_shift(path, entries2,
+-                                                          idx - count1);
++                                                          idx - count + d);
+                               frame->entries = entries = entries2;
                                swap(frame->bh, bh2);
                                bh_new[i] = bh2;
++                              parent->at = iam_entry_shift(path,
++                                                           parent->at, +1);
                        }
 -                      dx_insert_block(path, frame - 1, hash2, newblock[i]);
-+                      iam_insert_key(path, parent, pivot, newblock[i]);
                        assert(dx_node_check(path, frame));
 -                      assert(dx_node_check(path, frame - 1));
 +                      assert(dx_node_check(path, parent));
@@ -5543,7 +5591,7 @@ Index: linux-stage/fs/ext3/namei.c
        }
        goto cleanup;
  journal_error:
-@@ -2610,7 +1680,7 @@
+@@ -2610,7 +1688,7 @@ static int ext3_dx_add_entry(handle_t *h
        size_t isize;
  
        iam_path_compat_init(&cpath, dir);
@@ -5552,7 +5600,7 @@ Index: linux-stage/fs/ext3/namei.c
  
        err = dx_probe(dentry, NULL, &hinfo, path);
        if (err != 0)
-@@ -2620,8 +1690,9 @@
+@@ -2620,8 +1698,9 @@ static int ext3_dx_add_entry(handle_t *h
        /* XXX nikita: global serialization! */
        isize = dir->i_size;
  
@@ -5564,7 +5612,7 @@ Index: linux-stage/fs/ext3/namei.c
        if (err != 0)
                goto cleanup;
  
-@@ -2641,7 +1712,7 @@
+@@ -2641,7 +1720,7 @@ static int ext3_dx_add_entry(handle_t *h
                goto cleanup;   
  
        /*copy split inode too*/
@@ -5573,7 +5621,7 @@ Index: linux-stage/fs/ext3/namei.c
        if (!de)
                goto cleanup;
  
-@@ -2758,12 +1829,12 @@
+@@ -2758,12 +1837,12 @@ static struct inode * ext3_new_inode_wan
   * is so far negative - it has no inode.
   *
   * If the create succeeds, we fill in the inode information
@@ -5588,10 +5636,10 @@ Index: linux-stage/fs/ext3/namei.c
        struct inode * inode;
        int err, retries = 0;
  
-Index: linux-stage/include/linux/lustre_iam.h
+Index: iam/include/linux/lustre_iam.h
 ===================================================================
---- linux-stage.orig/include/linux/lustre_iam.h        2006-09-27 15:49:15.000000000 +0800
-+++ linux-stage/include/linux/lustre_iam.h     2006-09-27 15:49:15.000000000 +0800
+--- iam.orig/include/linux/lustre_iam.h        2006-09-28 22:11:15.000000000 +0400
++++ iam/include/linux/lustre_iam.h     2006-10-03 00:15:55.000000000 +0400
 @@ -1,9 +1,68 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -5663,7 +5711,7 @@ Index: linux-stage/include/linux/lustre_iam.h
  };
  
  /*
-@@ -30,6 +89,11 @@
+@@ -30,6 +89,11 @@ struct iam_key;
  /* Incomplete type use to refer to the records stored in iam containers. */
  struct iam_rec;
  
@@ -5675,7 +5723,7 @@ Index: linux-stage/include/linux/lustre_iam.h
  typedef __u64 iam_ptr_t;
  
  /*
-@@ -41,45 +105,25 @@
+@@ -41,45 +105,25 @@ struct iam_frame {
        struct iam_entry *at;      /* target entry, found by binary search */
  };
  
@@ -5735,7 +5783,7 @@ Index: linux-stage/include/linux/lustre_iam.h
        /*
         * Returns pointer (in the same sense as pointer in index entry) to
         * the root node.
-@@ -102,8 +146,8 @@
+@@ -102,8 +146,8 @@ struct iam_descr {
        /*
         * Key comparison function. Returns -1, 0, +1.
         */
@@ -5746,7 +5794,7 @@ Index: linux-stage/include/linux/lustre_iam.h
        /*
         * Create new container.
         *
-@@ -111,25 +155,113 @@
+@@ -111,25 +155,113 @@ struct iam_descr {
         * contains single record with the smallest possible key.
         */
        int (*id_create)(struct iam_container *c);
@@ -5879,7 +5927,7 @@ Index: linux-stage/include/linux/lustre_iam.h
  };
  
  struct iam_container {
-@@ -142,10 +274,17 @@
+@@ -142,10 +274,17 @@ struct iam_container {
         * container flavor.
         */
        struct iam_descr *ic_descr;
@@ -5899,7 +5947,7 @@ Index: linux-stage/include/linux/lustre_iam.h
  };
  
  /*
-@@ -172,36 +311,240 @@
+@@ -172,36 +311,240 @@ struct iam_path {
        /*
         * Leaf node: a child of ->ip_frame.
         */
@@ -6156,7 +6204,7 @@ Index: linux-stage/include/linux/lustre_iam.h
   */
  int iam_container_init(struct iam_container *c,
                       struct iam_descr *descr, struct inode *inode);
-@@ -210,3 +553,170 @@
+@@ -210,3 +553,170 @@ int iam_container_init(struct iam_contai
   */
  void iam_container_fini(struct iam_container *c);
  
index ca94256..229a92c 100644 (file)
@@ -1,7 +1,7 @@
 Index: iam/fs/ext3/Makefile
 ===================================================================
---- iam.orig/fs/ext3/Makefile  2006-09-28 22:11:15.000000000 +0400
-+++ iam/fs/ext3/Makefile       2006-09-28 22:11:15.000000000 +0400
+--- iam.orig/fs/ext3/Makefile  2006-10-03 00:15:55.000000000 +0400
++++ iam/fs/ext3/Makefile       2006-10-03 00:15:56.000000000 +0400
 @@ -6,7 +6,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o
  
  ext3-y        := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
@@ -13,8 +13,8 @@ Index: iam/fs/ext3/Makefile
  ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
 Index: iam/fs/ext3/dir.c
 ===================================================================
---- iam.orig/fs/ext3/dir.c     2006-09-28 22:10:32.000000000 +0400
-+++ iam/fs/ext3/dir.c  2006-09-28 22:11:15.000000000 +0400
+--- iam.orig/fs/ext3/dir.c     2006-10-03 00:15:55.000000000 +0400
++++ iam/fs/ext3/dir.c  2006-10-03 00:15:56.000000000 +0400
 @@ -28,6 +28,7 @@
  #include <linux/smp_lock.h>
  #include <linux/slab.h>
@@ -112,8 +112,8 @@ Index: iam/fs/ext3/dir.c
                    (filp->f_version != inode->i_version)) {
 Index: iam/fs/ext3/file.c
 ===================================================================
---- iam.orig/fs/ext3/file.c    2006-09-28 22:10:32.000000000 +0400
-+++ iam/fs/ext3/file.c 2006-09-28 22:11:15.000000000 +0400
+--- iam.orig/fs/ext3/file.c    2006-10-03 00:15:55.000000000 +0400
++++ iam/fs/ext3/file.c 2006-10-03 00:15:56.000000000 +0400
 @@ -23,6 +23,7 @@
  #include <linux/jbd.h>
  #include <linux/ext3_fs.h>
@@ -156,7 +156,7 @@ Index: iam/fs/ext3/file.c
 Index: iam/fs/ext3/iam-uapi.c
 ===================================================================
 --- iam.orig/fs/ext3/iam-uapi.c        2004-04-06 17:27:52.000000000 +0400
-+++ iam/fs/ext3/iam-uapi.c     2006-09-28 22:11:15.000000000 +0400
++++ iam/fs/ext3/iam-uapi.c     2006-10-03 00:15:56.000000000 +0400
 @@ -0,0 +1,368 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -528,8 +528,8 @@ Index: iam/fs/ext3/iam-uapi.c
 +}
 Index: iam/fs/ext3/ioctl.c
 ===================================================================
---- iam.orig/fs/ext3/ioctl.c   2006-09-28 22:11:14.000000000 +0400
-+++ iam/fs/ext3/ioctl.c        2006-09-28 22:11:15.000000000 +0400
+--- iam.orig/fs/ext3/ioctl.c   2006-10-03 00:15:55.000000000 +0400
++++ iam/fs/ext3/ioctl.c        2006-10-03 00:15:56.000000000 +0400
 @@ -250,6 +250,6 @@ flags_err:
  
  
@@ -540,8 +540,8 @@ Index: iam/fs/ext3/ioctl.c
  }
 Index: iam/include/linux/lustre_iam.h
 ===================================================================
---- iam.orig/include/linux/lustre_iam.h        2006-09-28 22:11:15.000000000 +0400
-+++ iam/include/linux/lustre_iam.h     2006-09-28 22:11:15.000000000 +0400
+--- iam.orig/include/linux/lustre_iam.h        2006-10-03 00:15:55.000000000 +0400
++++ iam/include/linux/lustre_iam.h     2006-10-03 00:15:56.000000000 +0400
 @@ -30,9 +30,6 @@
  #ifndef __LINUX_LUSTRE_IAM_H__
  #define __LINUX_LUSTRE_IAM_H__
index 8348f9e..dde3a15 100644 (file)
@@ -1,7 +1,7 @@
 Index: iam/fs/ext3/super.c
 ===================================================================
---- iam.orig/fs/ext3/super.c   2006-09-29 02:41:03.000000000 +0400
-+++ iam/fs/ext3/super.c        2006-09-29 02:41:03.000000000 +0400
+--- iam.orig/fs/ext3/super.c   2006-10-03 00:15:54.000000000 +0400
++++ iam/fs/ext3/super.c        2006-10-03 00:15:56.000000000 +0400
 @@ -1168,8 +1168,8 @@ static int ext3_check_descriptors (struc
   * e2fsck was run on this filesystem, and it must have already done the orphan
   * inode cleanup for us, so we can safely abort without any further action.