From ab7ac3117478f9943bc683e48d384150d2449a7c Mon Sep 17 00:00:00 2001 From: nikita Date: Mon, 2 Oct 2006 20:36:09 +0000 Subject: [PATCH] fix iam defects that caused 11011/mdsrate failures: - 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. --- .../kernel_patches/patches/ext3-iam-separate.patch | 460 ++++++++++++--------- lustre/kernel_patches/patches/ext3-iam-uapi.patch | 22 +- .../patches/ext3-orphans-delay.patch | 4 +- 3 files changed, 267 insertions(+), 219 deletions(-) diff --git a/lustre/kernel_patches/patches/ext3-iam-separate.patch b/lustre/kernel_patches/patches/ext3-iam-separate.patch index cd7cbdf..b43450f 100644 --- a/lustre/kernel_patches/patches/ext3-iam-separate.patch +++ b/lustre/kernel_patches/patches/ext3-iam-separate.patch @@ -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); diff --git a/lustre/kernel_patches/patches/ext3-iam-uapi.patch b/lustre/kernel_patches/patches/ext3-iam-uapi.patch index ca94256..229a92c 100644 --- a/lustre/kernel_patches/patches/ext3-iam-uapi.patch +++ b/lustre/kernel_patches/patches/ext3-iam-uapi.patch @@ -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 #include @@ -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 #include @@ -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__ diff --git a/lustre/kernel_patches/patches/ext3-orphans-delay.patch b/lustre/kernel_patches/patches/ext3-orphans-delay.patch index 8348f9e..dde3a15 100644 --- a/lustre/kernel_patches/patches/ext3-orphans-delay.patch +++ b/lustre/kernel_patches/patches/ext3-orphans-delay.patch @@ -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. -- 1.8.3.1