From: nikita Date: Sun, 28 May 2006 20:48:55 +0000 (+0000) Subject: iam: fixes X-Git-Tag: v1_8_0_110~486^2~1747 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=3efe9d655f37ebc0104a41b7210ebe11109e369b;p=fs%2Flustre-release.git iam: fixes --- diff --git a/lustre/fld/fld_iam.c b/lustre/fld/fld_iam.c index b8a77dc..92c1fe8 100644 --- a/lustre/fld/fld_iam.c +++ b/lustre/fld/fld_iam.c @@ -142,8 +142,9 @@ int fld_iam_init(const struct lu_context *ctx, struct fld *fld) if (!IS_ERR(dt_obj)) { fld->fld_obj = dt_obj; if (dt_obj->do_index_ops != NULL) { - rc = dt_obj->do_index_ops->dio_init(ctx, dt_obj, - ic, &fld_param); + /* XXX nikita: disable for now */ + /* rc = dt_obj->do_index_ops->dio_init(ctx, dt_obj, + ic, &fld_param); */ fld_param.id_ops->id_keycmp = fld_keycmp; } else { CERROR("fld is not an index!\n"); @@ -162,7 +163,8 @@ void fld_iam_fini(const struct lu_context *ctx, struct fld *fld) { struct dt_object *dt_obj = fld->fld_obj; - dt_obj->do_index_ops->dio_fini(ctx, dt_obj); + /* XXX nikita: disable for now */ + /* dt_obj->do_index_ops->dio_fini(ctx, dt_obj); */ /*XXX Should put object here, lu_object_put(fld->fld_obj->do_lu); *but no ctxt in this func, FIX later*/ diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h index 7ee969d..21d8666 100644 --- a/lustre/include/dt_object.h +++ b/lustre/include/dt_object.h @@ -247,18 +247,12 @@ struct dt_index_operations { int (*dio_delete)(const struct lu_context *ctxt, struct dt_object *dt, const struct dt_rec *rec, const struct dt_key *key, struct thandle *handle); - /* * Features probing. Returns 1 if this index supports all features in * @feat, -ve on error, 0 otherwise. */ int (*dio_probe)(const struct lu_context *ctxt, struct dt_object *dt, const struct dt_index_features *feat); - - int (*dio_init)(const struct lu_context *ctxt, struct dt_object *obj, - void *container, void *param); - - int (*dio_fini)(const struct lu_context *ctxt, struct dt_object *obj); }; struct dt_device { diff --git a/lustre/kernel_patches/patches/ext3-iam-separate.patch b/lustre/kernel_patches/patches/ext3-iam-separate.patch index e3ab05f..3dc5649 100644 --- a/lustre/kernel_patches/patches/ext3-iam-separate.patch +++ b/lustre/kernel_patches/patches/ext3-iam-separate.patch @@ -14,8 +14,8 @@ Index: iam/fs/ext3/Makefile Index: iam/fs/ext3/iam.c =================================================================== --- iam.orig/fs/ext3/iam.c 2004-04-06 17:27:52.000000000 +0400 -+++ iam/fs/ext3/iam.c 2006-05-27 21:32:20.000000000 +0400 -@@ -0,0 +1,957 @@ ++++ iam/fs/ext3/iam.c 2006-05-29 00:31:12.000000000 +0400 +@@ -0,0 +1,990 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -362,9 +362,9 @@ Index: iam/fs/ext3/iam.c + return iam_leaf_ops(leaf)->at_end(leaf); +} + -+int iam_leaf_split(handle_t *handle, struct iam_leaf *l) ++void iam_leaf_split(struct iam_leaf *l, struct buffer_head *bh) +{ -+ return iam_leaf_ops(l)->split(handle, l); ++ iam_leaf_ops(l)->split(l, bh); +} + +static int iam_leaf_can_add(struct iam_leaf *l, @@ -411,7 +411,7 @@ Index: iam/fs/ext3/iam.c + + result = iam_it_get(it, k); + if (result == 0 && -+ (it_keycmp(it, k, iam_it_key_get(it, it_scratch_key(it, 0))) != 0)) ++ (it_keycmp(it, k, iam_it_key_get(it, it_scratch_key(it, 1))) != 0)) + /* + * Return -ENOENT if cursor is located above record with a key + * different from one specified. @@ -591,26 +591,30 @@ Index: iam/fs/ext3/iam.c +{ + int result; + struct iam_container *c; ++ struct iam_path *path; ++ struct iam_leaf *leaf; + + assert(it_state(it) == IAM_IT_ATTACHED && it->ii_flags&IAM_IT_MOVE); + -+ c = iam_it_container(it); -+ if (iam_leaf_at_end(&it->ii_path.ip_leaf)) { ++ c = iam_it_container(it); ++ path = &it->ii_path; ++ leaf = &path->ip_leaf; ++ ++ if (iam_leaf_at_end(leaf)) { + /* advance index portion of the path */ -+ result = 0; /* XXX not yet iam_index_next(&it->ii_path); */ -+ if (result == 0) { -+ result = 0; /* XXX not yet -+ * iam_read_leaf(&it->ii_path); */ ++ result = iam_index_next(c, path); ++ if (result == 1) { ++ result = iam_leaf_load(path); + if (result == 0) -+ iam_leaf_start(&it->ii_path.ip_leaf); -+ } else if (result > 0) ++ iam_leaf_start(leaf); ++ } else if (result == 0) + /* end of container reached */ + result = +1; + if (result < 0) + iam_it_put(it); + } else { + /* advance within leaf node */ -+ iam_leaf_next(&it->ii_path.ip_leaf); ++ iam_leaf_next(leaf); + result = 0; + } + assert(ergo(result >= 0, it_state(it) == IAM_IT_ATTACHED)); @@ -688,6 +692,35 @@ Index: iam/fs/ext3/iam.c + return err; +} + ++static int iam_new_leaf(handle_t *handle, struct iam_leaf *leaf) ++{ ++ int err; ++ int err2; ++ u32 blknr; /* XXX 32bit block size */ ++ struct buffer_head *new_leaf; ++ struct iam_container *c; ++ ++ c = iam_leaf_container(leaf); ++ err = ext3_journal_get_write_access(handle, leaf->il_bh); ++ if (err == 0) { ++ struct inode *obj; ++ ++ obj = c->ic_object; ++ new_leaf = ext3_append(handle, c->ic_object, &blknr, &err); ++ if (new_leaf != NULL) { ++ iam_leaf_ops(leaf)->init_new(c, new_leaf); ++ iam_leaf_ops(leaf)->split(leaf, new_leaf); ++ err = ext3_journal_dirty_metadata(handle, new_leaf); ++ err2 = ext3_journal_dirty_metadata(handle, leaf->il_bh); ++ err = err ? : err2; ++ if (err) ++ ext3_std_error(obj->i_sb, err); ++ brelse(new_leaf); ++ } ++ } ++ return err; ++} ++ +int iam_add_rec(handle_t *handle, struct iam_path *path, + struct iam_key *k, struct iam_rec *r) +{ @@ -698,7 +731,7 @@ Index: iam/fs/ext3/iam.c + } else { + err = split_index_node(handle, path); + if (err == 0) { -+ err = iam_leaf_split(handle, &path->ip_leaf); ++ err = iam_new_leaf(handle, &path->ip_leaf); + if (err == 0) + err = iam_leaf_rec_add(handle, path); + } @@ -976,8 +1009,8 @@ Index: iam/fs/ext3/iam.c Index: iam/fs/ext3/iam_lfix.c =================================================================== --- iam.orig/fs/ext3/iam_lfix.c 2004-04-06 17:27:52.000000000 +0400 -+++ iam/fs/ext3/iam_lfix.c 2006-05-27 21:26:51.000000000 +0400 -@@ -0,0 +1,313 @@ ++++ iam/fs/ext3/iam_lfix.c 2006-05-29 00:42:57.000000000 +0400 +@@ -0,0 +1,309 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -1009,6 +1042,8 @@ Index: iam/fs/ext3/iam_lfix.c + +#include +#include ++/* ext3_error() */ ++#include + +#include + @@ -1030,13 +1065,17 @@ Index: iam/fs/ext3/iam_lfix.c +static inline const struct iam_key * +iam_leaf_key_at(const struct iam_container *c, const struct iam_lentry *entry) +{ -+ const void *e = entry; -+ return e; ++ return (const struct iam_key *)entry; ++} ++ ++static struct iam_lentry *iam_entries(const struct buffer_head *bh) ++{ ++ return (void *)bh->b_data + sizeof(struct iam_leaf_head); +} + +static struct iam_lentry *iam_get_lentries(const struct iam_leaf *l) +{ -+ return (void *)l->il_bh->b_data + iam_leaf_descr(l)->id_node_gap; ++ return iam_entries(l->il_bh); +} + +static int lentry_count_get(const struct iam_leaf *leaf) @@ -1055,15 +1094,13 @@ Index: iam/fs/ext3/iam_lfix.c + *which are not stored explicitly + *it would be decrypt in the key buffer + */ -+struct iam_key* -+iam_lfix_key(struct iam_leaf *l, struct iam_key *key) ++struct iam_key *iam_lfix_key(struct iam_leaf *l, struct iam_key *key) +{ + void *ie = l->il_at; + return (struct iam_key*)ie; +} + -+static void -+iam_lfix_start(struct iam_leaf *l) ++static void iam_lfix_start(struct iam_leaf *l) +{ + l->il_at = iam_get_lentries(l); +} @@ -1082,15 +1119,26 @@ Index: iam/fs/ext3/iam_lfix.c + +static int iam_lfix_init(struct iam_leaf *l) +{ ++ int result; + struct iam_leaf_head *ill; + + assert(l->il_bh != NULL); + + ill = (struct iam_leaf_head*)l->il_bh->b_data; -+ assert(ill->ill_magic == IAM_LEAF_HEADER_MAGIC); -+ -+ l->il_at = l->il_entries = iam_get_lentries(l); -+ return 0; ++ if (ill->ill_magic == le16_to_cpu(IAM_LEAF_HEADER_MAGIC)) { ++ l->il_at = l->il_entries = iam_get_lentries(l); ++ result = 0; ++ } else { ++ struct inode *obj; ++ ++ obj = iam_leaf_container(l)->ic_object; ++ ext3_error(obj->i_sb, __FUNCTION__, ++ "Wrong magic in node %llu (#%lu): %#x != %#x\n", ++ l->il_bh->b_blocknr, obj->i_ino, ++ ill->ill_magic, le16_to_cpu(IAM_LEAF_HEADER_MAGIC)); ++ result = -EIO; ++ } ++ return result; +} + +static void iam_lfix_fini(struct iam_leaf *l) @@ -1099,8 +1147,7 @@ Index: iam/fs/ext3/iam_lfix.c + return; +} + -+static struct iam_lentry * -+iam_lfix_get_end(const struct iam_leaf *l) ++static struct iam_lentry *iam_lfix_get_end(const struct iam_leaf *l) +{ + int count = lentry_count_get(l); + struct iam_lentry *ile = iam_lfix_shift(l, l->il_entries, count); @@ -1108,22 +1155,19 @@ Index: iam/fs/ext3/iam_lfix.c + return ile; +} + -+struct iam_rec* -+iam_lfix_rec(struct iam_leaf *l) ++struct iam_rec *iam_lfix_rec(struct iam_leaf *l) +{ + void *e = l->il_at; + return e + iam_leaf_descr(l)->id_key_size; +} + -+static void -+iam_lfix_next(struct iam_leaf *l) ++static void iam_lfix_next(struct iam_leaf *l) +{ + assert(!iam_leaf_at_end(l)); + l->il_at = iam_lfix_shift(l, l->il_at, 1); +} + -+static int -+iam_lfix_lookup(struct iam_leaf *l, struct iam_key *k) ++static int iam_lfix_lookup(struct iam_leaf *l, struct iam_key *k) +{ + struct iam_lentry *p, *q, *m; + struct iam_container *c; @@ -1217,8 +1261,52 @@ Index: iam/fs/ext3/iam_lfix.c + return (folio->il_at == ile); +} + ++static void iam_lfix_init_new(struct iam_container *c, struct buffer_head *bh) ++{ ++ struct iam_leaf_head *hdr; ++ ++ hdr = (struct iam_leaf_head*)bh->b_data; ++ hdr->ill_magic = cpu_to_le16(IAM_LEAF_HEADER_MAGIC); ++ hdr->ill_count = cpu_to_le16(0); ++} ++ ++static void iam_lfix_split(struct iam_leaf *l, struct buffer_head *bh) ++{ ++ struct iam_path *path; ++ struct iam_leaf_head *hdr; ++ const struct iam_key *pivot; ++ ++ unsigned count; ++ unsigned split; ++ ++ void *start; ++ void *finis; ++ ++ path = iam_leaf_path(l); ++ ++ hdr = (void *)bh->b_data; ++ ++ count = lentry_count_get(l); ++ split = count / 2; ++ ++ start = iam_lfix_shift(l, iam_get_lentries(l), split); ++ finis = iam_lfix_shift(l, iam_get_lentries(l), count); ++ ++ pivot = iam_leaf_key_at(iam_leaf_container(l), start); ++ ++ memmove(iam_entries(bh), start, finis - start); ++ hdr->ill_count = count - split; ++ lentry_count_set(l, split); ++ /* ++ * Insert pointer to the new node (together with the smallest key in ++ * the node) into index node. ++ */ ++ iam_insert_key(path, path->ip_frame, pivot, bh->b_blocknr); ++} ++ +struct iam_leaf_operations iam_lfix_leaf_ops = { + .init = iam_lfix_init, ++ .init_new = iam_lfix_init_new, + .fini = iam_lfix_fini, + .start = iam_lfix_start, + .next = iam_lfix_next, @@ -1228,73 +1316,14 @@ Index: iam/fs/ext3/iam_lfix.c + .at_end = iam_lfix_at_end, + .rec_add = iam_lfix_rec_add, + .rec_del = iam_lfix_rec_del, -+ .can_add = iam_lfix_can_add ++ .can_add = iam_lfix_can_add, ++ .split = iam_lfix_split +}; +EXPORT_SYMBOL(iam_lfix_leaf_ops); -+ -+static int split_leaf_node(handle_t *handle, struct iam_path *path) -+{ -+#if 0 -+ struct inode *dir = iam_path_obj(path); -+ unsigned continued = 0; -+ struct buffer_head *bh2; -+ u32 newblock, hash_split; -+ char *data2; -+ unsigned split; -+ int err; -+ -+ bh2 = ext3_append (handle, dir, &newblock, &err); -+ if (!(bh2)) -+ return -ENOSPC; -+ -+ err = iam_leaf_load(path); -+ if (err) -+ goto errout; -+ -+ BUFFER_TRACE(path->ip_leaf.il_bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, path->ip_leaf.il_bh); -+ if (err) { -+ journal_error: -+ iam_leaf_fini(path); -+ brelse(bh2); -+ ext3_std_error(dir->i_sb, err); -+ err = -EIO; -+ goto errout; -+ } -+ data2 = bh2->b_data; -+ split = dx_get_count((struct iam_entry*)iam_leaf_entries(path))/2; -+ hash_split = *(__u32*)iam_leaf_key_at(path, -+ iam_lfix_shift(path, iam_leaf_entries(path), -+ split)); -+ if (iam_keycmp(path->ip_container, iam_leaf_key_at(path, -+ iam_lfix_shift(path, iam_leaf_entries(path), split)), -+ iam_leaf_key_at(path, -+ iam_lfix_shift(path, iam_leaf_entries(path), split -1))) == 0) -+ continued = 1; -+ -+ memcpy(iam_lfix_shift(path, (struct iam_lentry *)data2, 1), -+ iam_lfix_shift(path, iam_leaf_entries(path), split), -+ split * iam_lfix_entry_size(path)); -+ -+ /* Which block gets the new entry? */ -+ dx_insert_block(path, path->ip_frame, hash_split + continued, newblock); -+ err = ext3_journal_dirty_metadata (handle, bh2); -+ if (err) -+ goto journal_error; -+ err = ext3_journal_dirty_metadata (handle, path->ip_leaf.il_bh); -+ if (err) -+ goto journal_error; -+errout: -+ brelse (bh2); -+ return err; -+#endif -+ return 0; -+} -+ Index: iam/fs/ext3/namei.c =================================================================== --- iam.orig/fs/ext3/namei.c 2006-05-27 19:58:44.000000000 +0400 -+++ iam/fs/ext3/namei.c 2006-05-27 21:30:42.000000000 +0400 ++++ iam/fs/ext3/namei.c 2006-05-29 00:40:31.000000000 +0400 @@ -24,81 +24,6 @@ * Theodore Ts'o, 2002 */ @@ -1402,7 +1431,17 @@ Index: iam/fs/ext3/namei.c { struct buffer_head *bh; -@@ -141,9 +66,6 @@ static struct buffer_head *ext3_append(h +@@ -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; +- ext3_journal_get_write_access(handle,bh); ++ *err = ext3_journal_get_write_access(handle, bh); ++ if (err != 0) { ++ brelse(bh); ++ bh = NULL; ++ } + } return bh; } @@ -1412,7 +1451,7 @@ Index: iam/fs/ext3/namei.c #ifndef swap #define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0) -@@ -162,10 +84,6 @@ struct fake_dirent { +@@ -162,10 +88,6 @@ struct fake_dirent { u8 file_type; }; @@ -1423,7 +1462,7 @@ Index: iam/fs/ext3/namei.c /* * dx_root_info is laid out so that if it should somehow get overlaid by a -@@ -203,242 +121,10 @@ struct dx_map_entry +@@ -203,245 +125,10 @@ struct dx_map_entry }; @@ -1663,10 +1702,13 @@ Index: iam/fs/ext3/namei.c -static inline struct iam_key *dx_get_key(struct iam_path *p, - struct iam_entry *entry, - struct iam_key *key); - static void dx_set_key(struct iam_path *p, struct iam_entry *entry, - struct iam_key *key); - static unsigned dx_get_count(struct iam_entry *entries); -@@ -457,80 +143,29 @@ static void dx_sort_map(struct dx_map_en +-static void dx_set_key(struct iam_path *p, struct iam_entry *entry, +- struct iam_key *key); +-static unsigned dx_get_count(struct iam_entry *entries); + 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,80 +144,29 @@ 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); @@ -1730,17 +1772,17 @@ Index: iam/fs/ext3/namei.c -} - -static inline unsigned dx_get_block(struct iam_path *p, struct iam_entry *entry) -+static inline struct iam_key *iam_get_key(struct iam_path *p, -+ struct iam_entry *entry, -+ struct iam_key *key) - { +-{ - return le32_to_cpu(*(u32 *)entry_off(entry, path_descr(p)->id_key_size)) - & 0x00ffffff; -} - -static inline void dx_set_block(struct iam_path *p, - struct iam_entry *entry, unsigned value) --{ ++static inline struct iam_key *iam_get_key(struct iam_path *p, ++ struct iam_entry *entry, ++ struct iam_key *key) + { - *(u32*)entry_off(entry, - path_descr(p)->id_key_size) = cpu_to_le32(value); -} @@ -1754,7 +1796,7 @@ Index: iam/fs/ext3/namei.c return key; } -@@ -540,68 +175,70 @@ static inline struct iam_key *iam_key_at +@@ -540,68 +176,70 @@ static inline struct iam_key *iam_key_at return (struct iam_key *)entry; } @@ -1867,7 +1909,7 @@ Index: iam/fs/ext3/namei.c static int dx_node_check(struct iam_path *p, struct iam_frame *f) { struct iam_entry *e; -@@ -614,10 +251,10 @@ static int dx_node_check(struct iam_path +@@ -614,10 +252,10 @@ static int dx_node_check(struct iam_path count = dx_get_count(e); e = iam_entry_shift(p, e, 1); for (i = 0; i < count - 1; ++i, e = iam_entry_shift(p, e, 1)) { @@ -1881,7 +1923,7 @@ Index: iam/fs/ext3/namei.c return 0; } return 1; -@@ -636,13 +273,17 @@ static int htree_node_check(struct iam_p +@@ -636,13 +274,17 @@ static int htree_node_check(struct iam_p data = frame->bh->b_data; entries = dx_node_get_entries(path, frame); @@ -1901,7 +1943,7 @@ Index: iam/fs/ext3/namei.c if (root->info.hash_version > DX_HASH_MAX) { ext3_warning(sb, __FUNCTION__, "Unrecognised inode hash code %d", -@@ -669,15 +310,16 @@ static int htree_node_check(struct iam_p +@@ -669,15 +311,16 @@ static int htree_node_check(struct iam_p root->info.info_length)); assert(dx_get_limit(entries) == dx_root_limit(path)); @@ -1925,7 +1967,7 @@ Index: iam/fs/ext3/namei.c assert(dx_get_limit(entries) == dx_node_limit(path)); } frame->entries = frame->at = entries; -@@ -697,8 +339,8 @@ static int htree_node_init(struct iam_co +@@ -697,8 +340,8 @@ static int htree_node_init(struct iam_co return 0; } @@ -1936,7 +1978,7 @@ Index: iam/fs/ext3/namei.c { int result = 0; -@@ -708,8 +350,8 @@ static int htree_node_read(struct iam_co +@@ -708,8 +351,8 @@ static int htree_node_read(struct iam_co return result; } @@ -1947,7 +1989,7 @@ Index: iam/fs/ext3/namei.c { __u32 p1 = le32_to_cpu(*(__u32 *)k1); __u32 p2 = le32_to_cpu(*(__u32 *)k2); -@@ -800,7 +442,7 @@ struct stats dx_show_entries(struct dx_h +@@ -800,7 +443,7 @@ struct stats dx_show_entries(struct dx_h } #endif /* DX_DEBUG */ @@ -1956,7 +1998,7 @@ Index: iam/fs/ext3/namei.c { u32 ptr; int err = 0; -@@ -810,11 +452,11 @@ static int dx_lookup(struct iam_path *pa +@@ -810,11 +453,11 @@ static int dx_lookup(struct iam_path *pa struct iam_frame *frame; struct iam_container *c; @@ -1970,7 +2012,7 @@ Index: iam/fs/ext3/namei.c i <= path->ip_indirect; ptr = dx_get_block(path, frame->at), ++frame, ++i) { struct iam_entry *entries; -@@ -823,10 +465,11 @@ static int dx_lookup(struct iam_path *pa +@@ -823,10 +466,11 @@ static int dx_lookup(struct iam_path *pa struct iam_entry *m; unsigned count; @@ -1984,7 +2026,7 @@ Index: iam/fs/ext3/namei.c if (err != 0) break; -@@ -841,8 +484,8 @@ static int dx_lookup(struct iam_path *pa +@@ -841,8 +485,8 @@ static int dx_lookup(struct iam_path *pa m = iam_entry_shift(path, p, iam_entry_diff(path, q, p) / 2); dxtrace(printk(".")); @@ -1995,7 +2037,7 @@ Index: iam/fs/ext3/namei.c q = iam_entry_shift(path, m, -1); else p = iam_entry_shift(path, m, +1); -@@ -857,12 +500,12 @@ static int dx_lookup(struct iam_path *pa +@@ -857,12 +501,12 @@ static int dx_lookup(struct iam_path *pa while (n--) { dxtrace(printk(",")); at = iam_entry_shift(path, at, +1); @@ -2011,7 +2053,7 @@ Index: iam/fs/ext3/namei.c path->ip_key_target)); } at = iam_entry_shift(path, at, -1); -@@ -891,508 +534,20 @@ static int dx_probe(struct dentry *dentr +@@ -891,508 +535,20 @@ static int dx_probe(struct dentry *dentr struct dx_hash_info *hinfo, struct iam_path *path) { int err; @@ -2526,27 +2568,64 @@ 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 * should be necessary. Whether or not the search is necessary is -@@ -1409,8 +564,8 @@ EXPORT_SYMBOL(iam_update); +@@ -1409,16 +565,15 @@ EXPORT_SYMBOL(iam_update); * If start_hash is non-null, it will be filled in with the starting * hash of the next page. */ -static int ext3_htree_next_block(struct inode *dir, __u32 hash, - struct iam_path *path, __u32 *start_hash) -+int ext3_htree_next_block(struct inode *dir, __u32 hash, -+ struct iam_path *path, __u32 *start_hash) ++static int ext3_htree_advance(struct inode *dir, __u32 hash, ++ struct iam_path *path, __u32 *start_hash, ++ int compat) { struct iam_frame *p; struct buffer_head *bh; -@@ -1445,7 +600,7 @@ static int ext3_htree_next_block(struct - * desired contiuation hash. If it doesn't, return since - * there's no point to read in the successive index pages. - */ + int err, num_frames = 0; + __u32 bhash; + +- assert(dx_index_is_compat(path)); +- + p = path->ip_frame; + /* + * Find the next leaf page by incrementing the frame pointer. +@@ -1438,28 +593,34 @@ static int ext3_htree_next_block(struct + --p; + } + +- /* +- * 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 +- * desired contiuation hash. If it doesn't, return since +- * there's no point to read in the successive index pages. +- */ - dx_get_key(path, p->at, (struct iam_key *)&bhash); -+ iam_get_key(path, p->at, (struct iam_key *)&bhash); - if (start_hash) - *start_hash = bhash; - if ((hash & 1) == 0) { -@@ -1457,9 +612,10 @@ static int ext3_htree_next_block(struct +- if (start_hash) +- *start_hash = bhash; +- if ((hash & 1) == 0) { +- if ((bhash & ~1) != hash) +- return 0; ++ if (compat) { ++ /* ++ * Htree hash magic. ++ */ ++ /* ++ * 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 ++ * desired contiuation hash. If it doesn't, return since ++ * there's no point to read in the successive index pages. ++ */ ++ iam_get_key(path, p->at, (struct iam_key *)&bhash); ++ if (start_hash) ++ *start_hash = bhash; ++ if ((hash & 1) == 0) { ++ if ((bhash & ~1) != hash) ++ return 0; ++ } + } + /* + * If the hash is HASH_NB_ALWAYS, we always go to the next * block so no check is necessary */ while (num_frames--) { @@ -2560,18 +2639,61 @@ Index: iam/fs/ext3/namei.c if (err != 0) return err; /* Failure */ ++p; -@@ -1662,8 +818,8 @@ static void dx_sort_map (struct dx_map_e +@@ -1471,6 +632,16 @@ static int ext3_htree_next_block(struct + return 1; + } + ++int iam_index_next(struct iam_container *c, struct iam_path *path) ++{ ++ return ext3_htree_advance(c->ic_object, 0, path, NULL, 0); ++} ++ ++int ext3_htree_next_block(struct inode *dir, __u32 hash, ++ struct iam_path *path, __u32 *start_hash) ++{ ++ return ext3_htree_advance(dir, hash, path, start_hash, 1); ++} + + /* + * p is at least 6 bytes before the end of page +@@ -1662,21 +833,30 @@ static void dx_sort_map (struct dx_map_e } while(more); } -static void dx_insert_block(struct iam_path *path, - struct iam_frame *frame, u32 hash, u32 block) -+void dx_insert_block(struct iam_path *path, struct iam_frame *frame, -+ u32 hash, u32 block) ++void iam_insert_key(struct iam_path *path, struct iam_frame *frame, ++ const struct iam_key *key, iam_ptr_t ptr) { struct iam_entry *entries = frame->entries; - struct iam_entry *old = frame->at, *new = iam_entry_shift(path, old, +1); -@@ -1897,14 +1053,15 @@ static struct buffer_head * ext3_dx_find +- struct iam_entry *old = frame->at, *new = iam_entry_shift(path, old, +1); ++ struct iam_entry *new = iam_entry_shift(path, frame->at, +1); + int count = dx_get_count(entries); + + assert(count < dx_get_limit(entries)); +- assert(old < iam_entry_shift(path, entries, count)); ++ assert(frame->at < iam_entry_shift(path, entries, count)); ++ + memmove(iam_entry_shift(path, new, 1), new, + (char *)iam_entry_shift(path, entries, count) - (char *)new); +- dx_set_key(path, new, (struct iam_key *)&hash); +- dx_set_block(path, new, block); ++ dx_set_key(path, new, key); ++ dx_set_block(path, new, ptr); + dx_set_count(entries, count + 1); + } ++ ++void dx_insert_block(struct iam_path *path, struct iam_frame *frame, ++ u32 hash, u32 block) ++{ ++ assert(dx_index_is_compat(path)); ++ iam_insert_key(path, frame, (struct iam_key *)&hash, block); ++} ++ + #endif + + +@@ -1897,14 +1077,15 @@ static struct buffer_head * ext3_dx_find if (*err != 0) return NULL; } else { @@ -2590,7 +2712,7 @@ Index: iam/fs/ext3/namei.c if (*err != 0) goto errout; de = (struct ext3_dir_entry_2 *) bh->b_data; -@@ -2067,7 +1224,7 @@ static struct ext3_dir_entry_2 *do_split +@@ -2067,7 +1248,7 @@ static struct ext3_dir_entry_2 *do_split struct buffer_head **bh,struct iam_frame *frame, struct dx_hash_info *hinfo, int *error) { @@ -2599,7 +2721,7 @@ Index: iam/fs/ext3/namei.c unsigned blocksize = dir->i_sb->s_blocksize; unsigned count, continued; struct buffer_head *bh2; -@@ -2392,15 +1549,15 @@ static int ext3_add_entry (handle_t *han +@@ -2392,15 +1573,15 @@ static int ext3_add_entry (handle_t *han } #ifdef CONFIG_EXT3_INDEX @@ -2618,7 +2740,7 @@ Index: iam/fs/ext3/namei.c int nr_splet; int i, err; -@@ -2442,7 +1599,8 @@ static int split_index_node(handle_t *ha +@@ -2442,7 +1623,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] || @@ -2628,7 +2750,7 @@ Index: iam/fs/ext3/namei.c goto cleanup; BUFFER_TRACE(frame->bh, "get_write_access"); err = ext3_journal_get_write_access(handle, frame->bh); -@@ -2516,9 +1674,9 @@ static int split_index_node(handle_t *ha +@@ -2516,9 +1698,9 @@ static int split_index_node(handle_t *ha unsigned count1 = count/2, count2 = count - count1; unsigned hash2; @@ -2641,7 +2763,7 @@ Index: iam/fs/ext3/namei.c dxtrace(printk("Split index %i/%i\n", count1, count2)); -@@ -2578,7 +1736,7 @@ static int ext3_dx_add_entry(handle_t *h +@@ -2578,7 +1760,7 @@ static int ext3_dx_add_entry(handle_t *h size_t isize; iam_path_compat_init(&cpath, dir); @@ -2650,7 +2772,7 @@ Index: iam/fs/ext3/namei.c err = dx_probe(dentry, NULL, &hinfo, path); if (err != 0) -@@ -2588,8 +1746,9 @@ static int ext3_dx_add_entry(handle_t *h +@@ -2588,8 +1770,9 @@ static int ext3_dx_add_entry(handle_t *h /* XXX nikita: global serialization! */ isize = dir->i_size; @@ -2662,7 +2784,7 @@ Index: iam/fs/ext3/namei.c if (err != 0) goto cleanup; -@@ -2724,12 +1883,12 @@ static struct inode * ext3_new_inode_wan +@@ -2724,12 +1907,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 @@ -2680,8 +2802,8 @@ Index: iam/fs/ext3/namei.c Index: iam/include/linux/lustre_iam.h =================================================================== --- iam.orig/include/linux/lustre_iam.h 2006-05-27 19:58:44.000000000 +0400 -+++ iam/include/linux/lustre_iam.h 2006-05-27 21:33:22.000000000 +0400 -@@ -1,3 +1,39 @@ ++++ iam/include/linux/lustre_iam.h 2006-05-29 00:40:51.000000000 +0400 +@@ -1,9 +1,61 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -2714,14 +2836,38 @@ Index: iam/include/linux/lustre_iam.h +#ifndef __LINUX_LUSTRE_IAM_H__ +#define __LINUX_LUSTRE_IAM_H__ + -+/* + /* +- * Maximal number of non-leaf levels in htree. In the stock ext3 this is 2. + * linux/include/linux/lustre_iam.h -+ */ + */ + + enum { ++ /* ++ * Maximal number of non-leaf levels in htree. In the stock ext3 this ++ * is 2. ++ */ + DX_MAX_TREE_HEIGHT = 5, +- DX_SCRATCH_KEYS = 2 ++ /* ++ * Scratch keys used by generic code for temporaries. ++ * ++ * Allocation: ++ * ++ * [0] reserved for assertions and as a staging area for ++ * record keys immediately used for key comparisons. ++ * ++ * [1] reserved for record key, stored during iteration over ++ * node records (see dx_node_check()). ++ * ++ * [2] reserved for leaf node operations. ++ * ++ * [3] reserved for index operations. ++ */ ++ DX_SCRATCH_KEYS = 4 + }; + /* - * Maximal number of non-leaf levels in htree. In the stock ext3 this is 2. - */ -@@ -30,6 +66,11 @@ struct iam_key; +@@ -30,6 +82,11 @@ struct iam_key; /* Incomplete type use to refer to the records stored in iam containers. */ struct iam_rec; @@ -2733,7 +2879,7 @@ Index: iam/include/linux/lustre_iam.h typedef __u64 iam_ptr_t; /* -@@ -41,45 +82,25 @@ struct iam_frame { +@@ -41,45 +98,25 @@ struct iam_frame { struct iam_entry *at; /* target entry, found by binary search */ }; @@ -2793,7 +2939,7 @@ Index: iam/include/linux/lustre_iam.h /* * Returns pointer (in the same sense as pointer in index entry) to * the root node. -@@ -102,8 +123,8 @@ struct iam_descr { +@@ -102,8 +139,8 @@ struct iam_descr { /* * Key comparison function. Returns -1, 0, +1. */ @@ -2804,7 +2950,7 @@ Index: iam/include/linux/lustre_iam.h /* * Create new container. * -@@ -111,25 +132,115 @@ struct iam_descr { +@@ -111,25 +148,120 @@ struct iam_descr { * contains single record with the smallest possible key. */ int (*id_create)(struct iam_container *c); @@ -2839,6 +2985,10 @@ Index: iam/include/linux/lustre_iam.h + */ + int (*init)(struct iam_leaf *p); + /* ++ * Format new node. ++ */ ++ void (*init_new)(struct iam_container *c, struct buffer_head *bh); ++ /* + * Release resources. + */ + void (*fini)(struct iam_leaf *l); @@ -2884,9 +3034,10 @@ Index: iam/include/linux/lustre_iam.h + */ + void (*rec_del)(struct iam_leaf *l); + /* -+ * split leaf node ++ * split leaf node, moving some entries into @bh (the latter currently ++ * is assumed to be empty). + */ -+ int (*split)(handle_t *h, struct iam_leaf *l); ++ void (*split)(struct iam_leaf *l, struct buffer_head *bh); +}; + +struct iam_path *iam_leaf_path(const struct iam_leaf *leaf); @@ -2939,7 +3090,7 @@ Index: iam/include/linux/lustre_iam.h }; struct iam_container { -@@ -149,6 +260,17 @@ struct iam_container { +@@ -149,6 +281,17 @@ struct iam_container { }; /* @@ -2957,7 +3108,7 @@ Index: iam/include/linux/lustre_iam.h * Structure to keep track of a path drilled through htree. */ struct iam_path { -@@ -172,34 +294,232 @@ struct iam_path { +@@ -172,34 +315,232 @@ struct iam_path { /* * Leaf node: a child of ->ip_frame. */ @@ -3204,7 +3355,7 @@ Index: iam/include/linux/lustre_iam.h /* * Initialize container @c, acquires additional reference on @inode. */ -@@ -210,3 +530,152 @@ int iam_container_init(struct iam_contai +@@ -210,3 +551,155 @@ int iam_container_init(struct iam_contai */ void iam_container_fini(struct iam_container *c); @@ -3260,10 +3411,10 @@ Index: iam/include/linux/lustre_iam.h + cpu_to_le32(value); +} + -+static inline void dx_set_key(struct iam_path *p, -+ struct iam_entry *entry, struct iam_key *key) ++static inline void dx_set_key(struct iam_path *p, struct iam_entry *entry, ++ const struct iam_key *key) +{ -+ memcpy(entry, key, iam_path_descr(p)->id_key_size); ++ iam_keycpy(p->ip_container, iam_entry_off(entry, 0), key); +} + +struct dx_countlimit { @@ -3339,12 +3490,15 @@ Index: iam/include/linux/lustre_iam.h +void iam_container_read_lock(struct iam_container *c); +void iam_container_read_unlock(struct iam_container *c); + -+int iam_index_next(struct iam_path *p); ++int iam_index_next(struct iam_container *c, struct iam_path *p); +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); + ++void iam_insert_key(struct iam_path *path, struct iam_frame *frame, ++ const struct iam_key *key, iam_ptr_t ptr); ++ +int iam_leaf_at_end(const struct iam_leaf *l); +void iam_leaf_next(struct iam_leaf *folio); +