From fc46dede427fed2f9661136243c2d5ad415b8771 Mon Sep 17 00:00:00 2001 From: nikita Date: Tue, 3 Oct 2006 17:23:55 +0000 Subject: [PATCH] add support for tunable levels of debugging checks in iam code. Currently this can be adjusted through EXT3_{ASSERT,CORRECTNESS,INVARIANT} switches in lustre_iam.h, support for ./configure options in under way. --- .../kernel_patches/patches/ext3-iam-separate.patch | 645 +++++++++++---------- lustre/kernel_patches/patches/ext3-iam-uapi.patch | 162 ++++-- 2 files changed, 441 insertions(+), 366 deletions(-) diff --git a/lustre/kernel_patches/patches/ext3-iam-separate.patch b/lustre/kernel_patches/patches/ext3-iam-separate.patch index b43450f..04bbd7c 100644 --- a/lustre/kernel_patches/patches/ext3-iam-separate.patch +++ b/lustre/kernel_patches/patches/ext3-iam-separate.patch @@ -1,7 +1,7 @@ Index: iam/fs/ext3/Makefile =================================================================== --- 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 ++++ iam/fs/ext3/Makefile 2006-10-03 21:14:47.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 \ @@ -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-10-02 19:59:04.000000000 +0400 -@@ -0,0 +1,1326 @@ ++++ iam/fs/ext3/iam.c 2006-10-03 21:13:35.000000000 +0400 +@@ -0,0 +1,1335 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -357,6 +357,7 @@ Index: iam/fs/ext3/iam.c +static int iam_leaf_check(struct iam_leaf *leaf); +extern int dx_node_check(struct iam_path *p, struct iam_frame *f); + ++#if EXT3_INVARIANT +static int iam_path_check(struct iam_path *p) +{ + int i; @@ -382,6 +383,7 @@ Index: iam/fs/ext3/iam.c + } + return result; +} ++#endif + +static int iam_leaf_load(struct iam_path *path) +{ @@ -401,7 +403,7 @@ Index: iam/fs/ext3/iam.c + leaf->il_bh = bh; + leaf->il_path = path; + err = iam_leaf_ops(leaf)->init(leaf); -+ assert(ergo(err == 0, iam_leaf_check(leaf))); ++ assert_inv(ergo(err == 0, iam_leaf_check(leaf))); + } + return err; +} @@ -409,7 +411,7 @@ Index: iam/fs/ext3/iam.c +static void iam_leaf_fini(struct iam_leaf *leaf) +{ + if (leaf->il_path != NULL) { -+ assert(ergo(leaf->il_bh != NULL, iam_leaf_check(leaf))); ++ assert_inv(ergo(leaf->il_bh != NULL, iam_leaf_check(leaf))); + iam_leaf_ops(leaf)->fini(leaf); + if (leaf->il_bh) { + brelse(leaf->il_bh); @@ -631,7 +633,7 @@ Index: iam/fs/ext3/iam.c + */ +void iam_it_fini(struct iam_iterator *it) +{ -+ assert(it_state(it) == IAM_IT_DETACHED); ++ assert_corr(it_state(it) == IAM_IT_DETACHED); + iam_path_fini(&it->ii_path); +} +EXPORT_SYMBOL(iam_it_fini); @@ -651,10 +653,10 @@ Index: iam/fs/ext3/iam.c + leaf = &path->ip_leaf; + descr = iam_path_descr(path); + result = dx_lookup(path); -+ assert(iam_path_check(path)); ++ assert_inv(iam_path_check(path)); + if (result == 0) { + result = iam_leaf_load(path); -+ assert(ergo(result == 0, iam_leaf_check(leaf))); ++ assert_inv(ergo(result == 0, iam_leaf_check(leaf))); + if (result == 0) { + if (index) + result = iam_leaf_ops(leaf)-> @@ -673,7 +675,7 @@ Index: iam/fs/ext3/iam.c +static int __iam_it_get(struct iam_iterator *it, int index) +{ + int result; -+ assert(it_state(it) == IAM_IT_DETACHED); ++ assert_corr(it_state(it) == IAM_IT_DETACHED); + + iam_it_lock(it); + result = iam_path_lookup(&it->ii_path, index); @@ -700,7 +702,7 @@ Index: iam/fs/ext3/iam.c + /* + * See iam_it_get_exact() for explanation. + */ -+ assert(result != -ENOENT); ++ assert_corr(result != -ENOENT); + return result; +} + @@ -719,16 +721,16 @@ Index: iam/fs/ext3/iam.c +int iam_it_get(struct iam_iterator *it, const struct iam_key *k) +{ + int result; -+ assert(it_state(it) == IAM_IT_DETACHED); ++ assert_corr(it_state(it) == IAM_IT_DETACHED); + + it->ii_path.ip_ikey_target = NULL; + it->ii_path.ip_key_target = k; + + result = __iam_it_get(it, 0); + -+ assert(ergo(result > 0, it_keycmp(it, k) == 0)); -+ assert(ergo(result == 0 && it_state(it) == IAM_IT_ATTACHED, -+ it_keycmp(it, k) <= 0)); ++ assert_corr(ergo(result > 0, it_keycmp(it, k) == 0)); ++ assert_corr(ergo(result == 0 && it_state(it) == IAM_IT_ATTACHED, ++ it_keycmp(it, k) <= 0)); + return result; +} +EXPORT_SYMBOL(iam_it_get); @@ -738,7 +740,7 @@ Index: iam/fs/ext3/iam.c + */ +static int iam_it_iget(struct iam_iterator *it, const struct iam_ikey *k) +{ -+ assert(it_state(it) == IAM_IT_DETACHED); ++ assert_corr(it_state(it) == IAM_IT_DETACHED); + + it->ii_path.ip_ikey_target = k; + return __iam_it_get(it, 1); @@ -758,15 +760,16 @@ Index: iam/fs/ext3/iam.c +int iam_it_get_at(struct iam_iterator *it, const struct iam_key *k) +{ + int result; -+ assert(it_state(it) == IAM_IT_DETACHED && !(it->ii_flags&IAM_IT_WRITE)); ++ assert_corr(it_state(it) == IAM_IT_DETACHED && ++ !(it->ii_flags&IAM_IT_WRITE)); + result = iam_it_get(it, k); + if (result == 0) { + if (it_state(it) != IAM_IT_ATTACHED) { -+ assert(it_state(it) == IAM_IT_SKEWED); ++ assert_corr(it_state(it) == IAM_IT_SKEWED); + result = iam_it_next(it); + } + } -+ assert(ergo(result >= 0, it_state(it) == IAM_IT_ATTACHED)); ++ assert_corr(ergo(result >= 0, it_state(it) == IAM_IT_ATTACHED)); + return result; +} +EXPORT_SYMBOL(iam_it_get_at); @@ -789,10 +792,10 @@ Index: iam/fs/ext3/iam.c + /* + * XXX: duplicate lock. + */ -+ assert(it_state(dst) == it_state(src)); -+ assert(iam_it_container(dst) == iam_it_container(src)); -+ assert(dst->ii_flags = src->ii_flags); -+ assert(ergo(it_state(src) == IAM_IT_ATTACHED, ++ assert_corr(it_state(dst) == it_state(src)); ++ assert_corr(iam_it_container(dst) == iam_it_container(src)); ++ assert_corr(dst->ii_flags = src->ii_flags); ++ assert_corr(ergo(it_state(src) == IAM_IT_ATTACHED, + iam_it_rec_get(dst) == iam_it_rec_get(src) && + iam_it_key_get(dst) == iam_it_key_get(src))); + @@ -831,16 +834,16 @@ Index: iam/fs/ext3/iam.c + struct iam_path *path; + struct iam_leaf *leaf; + -+ assert(it->ii_flags&IAM_IT_MOVE); -+ assert(it_state(it) == IAM_IT_ATTACHED || -+ it_state(it) == IAM_IT_SKEWED); ++ assert_corr(it->ii_flags&IAM_IT_MOVE); ++ assert_corr(it_state(it) == IAM_IT_ATTACHED || ++ it_state(it) == IAM_IT_SKEWED); + + path = &it->ii_path; + leaf = &path->ip_leaf; + + result = 0; + if (it_before(it)) { -+ assert(!iam_leaf_at_end(leaf)); ++ assert_corr(!iam_leaf_at_end(leaf)); + it->ii_state = IAM_IT_ATTACHED; + } else { + if (!iam_leaf_at_end(leaf)) @@ -864,8 +867,8 @@ Index: iam/fs/ext3/iam.c + iam_it_put(it); + } + } -+ assert(ergo(result == 0, it_state(it) == IAM_IT_ATTACHED)); -+ assert(ergo(result > 0, it_state(it) == IAM_IT_DETACHED)); ++ assert_corr(ergo(result == 0, it_state(it) == IAM_IT_ATTACHED)); ++ assert_corr(ergo(result > 0, it_state(it) == IAM_IT_DETACHED)); + return result; +} +EXPORT_SYMBOL(iam_it_next); @@ -878,8 +881,8 @@ Index: iam/fs/ext3/iam.c + */ +struct iam_rec *iam_it_rec_get(const struct iam_iterator *it) +{ -+ assert(it_state(it) == IAM_IT_ATTACHED); -+ assert(it_at_rec(it)); ++ assert_corr(it_state(it) == IAM_IT_ATTACHED); ++ assert_corr(it_at_rec(it)); + return iam_leaf_rec(&it->ii_path.ip_leaf); +} +EXPORT_SYMBOL(iam_it_rec_get); @@ -907,8 +910,9 @@ Index: iam/fs/ext3/iam.c + struct iam_path *path; + struct buffer_head *bh; + -+ assert(it_state(it) == IAM_IT_ATTACHED && it->ii_flags&IAM_IT_WRITE); -+ assert(it_at_rec(it)); ++ assert_corr(it_state(it) == IAM_IT_ATTACHED && ++ it->ii_flags&IAM_IT_WRITE); ++ assert_corr(it_at_rec(it)); + + path = &it->ii_path; + bh = path->ip_leaf.il_bh; @@ -930,9 +934,9 @@ Index: iam/fs/ext3/iam.c +static struct iam_ikey *iam_it_ikey_get(const struct iam_iterator *it, + struct iam_ikey *ikey) +{ -+ assert(it_state(it) == IAM_IT_ATTACHED || -+ it_state(it) == IAM_IT_SKEWED); -+ assert(it_at_rec(it)); ++ assert_corr(it_state(it) == IAM_IT_ATTACHED || ++ it_state(it) == IAM_IT_SKEWED); ++ assert_corr(it_at_rec(it)); + return iam_leaf_ikey(&it->ii_path.ip_leaf, ikey); +} + @@ -944,9 +948,9 @@ Index: iam/fs/ext3/iam.c + */ +struct iam_key *iam_it_key_get(const struct iam_iterator *it) +{ -+ assert(it_state(it) == IAM_IT_ATTACHED || -+ it_state(it) == IAM_IT_SKEWED); -+ assert(it_at_rec(it)); ++ assert_corr(it_state(it) == IAM_IT_ATTACHED || ++ it_state(it) == IAM_IT_SKEWED); ++ assert_corr(it_at_rec(it)); + return iam_leaf_key(&it->ii_path.ip_leaf); +} +EXPORT_SYMBOL(iam_it_key_get); @@ -959,9 +963,9 @@ Index: iam/fs/ext3/iam.c + */ +int iam_it_key_size(const struct iam_iterator *it) +{ -+ assert(it_state(it) == IAM_IT_ATTACHED || -+ it_state(it) == IAM_IT_SKEWED); -+ assert(it_at_rec(it)); ++ assert_corr(it_state(it) == IAM_IT_ATTACHED || ++ it_state(it) == IAM_IT_SKEWED); ++ assert_corr(it_at_rec(it)); + return iam_leaf_key_size(&it->ii_path.ip_leaf); +} +EXPORT_SYMBOL(iam_it_key_size); @@ -1000,7 +1004,7 @@ Index: iam/fs/ext3/iam.c + struct iam_container *c; + struct inode *obj; + -+ assert(iam_leaf_check(leaf)); ++ assert_inv(iam_leaf_check(leaf)); + + c = iam_leaf_container(leaf); + @@ -1014,9 +1018,9 @@ Index: iam/fs/ext3/iam.c + if (err == 0) + err = ext3_mark_inode_dirty(handle, c->ic_object); + } -+ assert(iam_leaf_check(leaf)); -+ assert(iam_leaf_check(&iam_leaf_path(leaf)->ip_leaf)); -+ assert(iam_path_check(iam_leaf_path(leaf))); ++ assert_inv(iam_leaf_check(leaf)); ++ assert_inv(iam_leaf_check(&iam_leaf_path(leaf)->ip_leaf)); ++ assert_inv(iam_path_check(iam_leaf_path(leaf))); + return err; +} + @@ -1027,13 +1031,13 @@ Index: iam/fs/ext3/iam.c + struct iam_leaf *leaf; + + leaf = &path->ip_leaf; -+ assert(iam_leaf_check(leaf)); -+ assert(iam_path_check(path)); ++ assert_inv(iam_leaf_check(leaf)); ++ assert_inv(iam_path_check(path)); + err = iam_txn_add(handle, path, leaf->il_bh); + if (err == 0) { + if (!iam_leaf_can_add(leaf, k, r)) { + err = split_index_node(handle, path); -+ assert(iam_path_check(path)); ++ assert_inv(iam_path_check(path)); + if (err == 0) { + err = iam_new_leaf(handle, leaf); + /* @@ -1051,9 +1055,9 @@ Index: iam/fs/ext3/iam.c + err = iam_txn_dirty(handle, path, leaf->il_bh); + } + } -+ assert(iam_leaf_check(leaf)); -+ assert(iam_leaf_check(&path->ip_leaf)); -+ assert(iam_path_check(path)); ++ assert_inv(iam_leaf_check(leaf)); ++ assert_inv(iam_leaf_check(&path->ip_leaf)); ++ assert_inv(iam_path_check(path)); + return err; +} + @@ -1080,18 +1084,20 @@ Index: iam/fs/ext3/iam.c + + path = &it->ii_path; + -+ assert(it->ii_flags&IAM_IT_WRITE); -+ assert(it_state(it) == IAM_IT_ATTACHED || -+ it_state(it) == IAM_IT_SKEWED); -+ assert(ergo(it_state(it) == IAM_IT_ATTACHED, it_keycmp(it, k) <= 0)); -+ assert(ergo(it_before(it), it_keycmp(it, k) > 0)); ++ assert_corr(it->ii_flags&IAM_IT_WRITE); ++ assert_corr(it_state(it) == IAM_IT_ATTACHED || ++ it_state(it) == IAM_IT_SKEWED); ++ assert_corr(ergo(it_state(it) == IAM_IT_ATTACHED, ++ it_keycmp(it, k) <= 0)); ++ assert_corr(ergo(it_before(it), it_keycmp(it, k) > 0)); + result = iam_add_rec(h, path, k, r); + if (result == 0) + it->ii_state = IAM_IT_ATTACHED; -+ assert(ergo(result == 0, -+ it_state(it) == IAM_IT_ATTACHED && it_keycmp(it, k) == 0 && -+ !memcmp(iam_it_rec_get(it), r, -+ iam_it_container(it)->ic_descr->id_rec_size))); ++ assert_corr(ergo(result == 0, ++ it_state(it) == IAM_IT_ATTACHED && ++ it_keycmp(it, k) == 0 && ++ !memcmp(iam_it_rec_get(it), r, ++ iam_it_container(it)->ic_descr->id_rec_size))); + return result; +} +EXPORT_SYMBOL(iam_it_rec_insert); @@ -1111,14 +1117,15 @@ Index: iam/fs/ext3/iam.c + struct iam_leaf *leaf; + struct iam_path *path; + -+ assert(it_state(it) == IAM_IT_ATTACHED && it->ii_flags&IAM_IT_WRITE); -+ assert(it_at_rec(it)); ++ assert_corr(it_state(it) == IAM_IT_ATTACHED && ++ it->ii_flags&IAM_IT_WRITE); ++ assert_corr(it_at_rec(it)); + + path = &it->ii_path; + leaf = &path->ip_leaf; + -+ assert(iam_leaf_check(leaf)); -+ assert(iam_path_check(path)); ++ assert_inv(iam_leaf_check(leaf)); ++ assert_inv(iam_path_check(path)); + + result = iam_txn_add(h, path, leaf->il_bh); + /* @@ -1134,10 +1141,10 @@ Index: iam/fs/ext3/iam.c + result = 0; + } + } -+ assert(iam_leaf_check(leaf)); -+ assert(iam_path_check(path)); -+ assert(it_state(it) == IAM_IT_ATTACHED || -+ it_state(it) == IAM_IT_DETACHED); ++ assert_inv(iam_leaf_check(leaf)); ++ assert_inv(iam_path_check(path)); ++ assert_corr(it_state(it) == IAM_IT_ATTACHED || ++ it_state(it) == IAM_IT_DETACHED); + return result; +} +EXPORT_SYMBOL(iam_it_rec_delete); @@ -1153,9 +1160,10 @@ Index: iam/fs/ext3/iam.c +{ + iam_pos_t result; + -+ assert(it_state(it) == IAM_IT_ATTACHED); -+ assert(it_at_rec(it)); -+ assert(iam_it_container(it)->ic_descr->id_ikey_size <= sizeof result); ++ assert_corr(it_state(it) == IAM_IT_ATTACHED); ++ assert_corr(it_at_rec(it)); ++ assert_corr(iam_it_container(it)->ic_descr->id_ikey_size <= ++ sizeof result); + + result = 0; + return *(iam_pos_t *)iam_it_ikey_get(it, (void *)&result); @@ -1172,8 +1180,9 @@ Index: iam/fs/ext3/iam.c + */ +int iam_it_load(struct iam_iterator *it, iam_pos_t pos) +{ -+ assert(it_state(it) == IAM_IT_DETACHED && it->ii_flags&IAM_IT_MOVE); -+ assert(iam_it_container(it)->ic_descr->id_ikey_size <= sizeof pos); ++ assert_corr(it_state(it) == IAM_IT_DETACHED && ++ it->ii_flags&IAM_IT_MOVE); ++ assert_corr(iam_it_container(it)->ic_descr->id_ikey_size <= sizeof pos); + return iam_it_iget(it, (struct iam_ikey *)&pos); +} +EXPORT_SYMBOL(iam_it_load); @@ -1345,8 +1354,8 @@ Index: iam/fs/ext3/iam.c Index: iam/fs/ext3/iam_htree.c =================================================================== --- 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 @@ ++++ iam/fs/ext3/iam_htree.c 2006-10-03 21:14:41.000000000 +0400 +@@ -0,0 +1,668 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -1395,8 +1404,8 @@ Index: iam/fs/ext3/iam_htree.c + struct iam_path *path; + + path = iam_leaf_path(folio); -+ assert(dx_index_is_compat(path)); -+ assert(path->ip_data != NULL); ++ assert_corr(dx_index_is_compat(path)); ++ assert_corr(path->ip_data != NULL); + return container_of(path->ip_data, struct iam_path_compat, ipc_descr); +} + @@ -1412,9 +1421,9 @@ Index: iam/fs/ext3/iam_htree.c + struct dx_hash_info *hinfo; + + hinfo = getipc(folio)->ipc_hinfo; -+ assert(hinfo != NULL); ++ assert_corr(hinfo != NULL); + result = ext3fs_dirhash(name, namelen, hinfo); -+ assert(result == 0); ++ assert_corr(result == 0); + return hinfo->hash; +} + @@ -1474,7 +1483,7 @@ Index: iam/fs/ext3/iam_htree.c + free = le16_to_cpu(ent->rec_len); + if (ent_is_live(ent)) + free -= recsize(ent->name_len); -+ assert(free >= 0); ++ assert_corr(free >= 0); + return free; +} + @@ -1484,8 +1493,8 @@ Index: iam/fs/ext3/iam_htree.c + __u32 hash0; + __u32 hash1; + -+ assert(ent_is_live(e0)); -+ assert(ent_is_live(e1)); ++ assert_corr(ent_is_live(e0)); ++ assert_corr(ent_is_live(e1)); + + hash0 = gethash(folio, e0); + hash1 = gethash(folio, e1); @@ -1501,6 +1510,7 @@ Index: iam/fs/ext3/iam_htree.c + return 0; +} + ++#if EXT3_CORRECTNESS || EXT3_INVARIANT +static int iam_leaf_at_rec(const struct iam_leaf *folio) +{ + struct ext3_dir_entry_2 *ent; @@ -1509,6 +1519,7 @@ Index: iam/fs/ext3/iam_htree.c + return getstart(folio) <= ent && + ent < gettop(folio) && ent_is_live(ent); +} ++#endif + +/* + * Leaf operations. @@ -1518,7 +1529,7 @@ Index: iam/fs/ext3/iam_htree.c + struct iam_ikey *key) +{ + __u32 *hash; -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + + hash = (void *)key; + *hash = gethash(l, getent(l)); @@ -1527,14 +1538,14 @@ Index: iam/fs/ext3/iam_htree.c + +static struct iam_key *iam_htree_key(const struct iam_leaf *l) +{ -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + + return (struct iam_key *)&getent(l)->name; +} + +static int iam_htree_key_size(const struct iam_leaf *l) +{ -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + + return getent(l)->name_len; +} @@ -1546,7 +1557,7 @@ Index: iam/fs/ext3/iam_htree.c + +static int iam_htree_init(struct iam_leaf *l) +{ -+ assert(l->il_bh != NULL); ++ assert_corr(l->il_bh != NULL); + + l->il_at = l->il_entries = (void *)getstart(l); + return 0; @@ -1559,7 +1570,7 @@ Index: iam/fs/ext3/iam_htree.c + +struct iam_rec *iam_htree_rec(const struct iam_leaf *l) +{ -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + return (void *)&getent(l)->inode; +} + @@ -1568,7 +1579,7 @@ Index: iam/fs/ext3/iam_htree.c + struct ext3_dir_entry_2 *scan; + struct ext3_dir_entry_2 *found; + -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + found = NULL; + for (scan = getstart(l); scan < gettop(l); scan = entnext(scan)) { + if (scan != getent(l) && ent_is_live(scan) && @@ -1576,8 +1587,8 @@ Index: iam/fs/ext3/iam_htree.c + (found == NULL || entcmp(l, scan, found) < 0)) + found = scan; + } -+ assert(ergo(found != NULL, -+ gethash(l, getent(l)) <= gethash(l, found))); ++ assert_corr(ergo(found != NULL, ++ gethash(l, getent(l)) <= gethash(l, found))); + l->il_at = (void *)(found ? : gettop(l)); +} + @@ -1630,7 +1641,7 @@ Index: iam/fs/ext3/iam_htree.c + result = IAM_LOOKUP_BEFORE; + } else { + l->il_at = (void *)found; -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + } + return result; +} @@ -1643,7 +1654,7 @@ Index: iam/fs/ext3/iam_htree.c + +static void iam_htree_key_set(struct iam_leaf *l, const struct iam_key *k) +{ -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + assert(0); +} + @@ -1656,7 +1667,7 @@ Index: iam/fs/ext3/iam_htree.c + + name = (const char *)k; + -+ assert(ent_is_live(getent(l))); ++ assert_corr(ent_is_live(getent(l))); + + h0 = gethash(l, getent(l)); + h1 = hashname(l, name, strlen(name)); @@ -1682,7 +1693,7 @@ Index: iam/fs/ext3/iam_htree.c + __u32 *ino; + int namelen; + -+ assert(iam_leaf_can_add(leaf, k, r)); ++ assert_corr(iam_leaf_can_add(leaf, k, r)); + + dir = iam_leaf_container(leaf)->ic_object; + ino = (void *)r; @@ -1690,7 +1701,7 @@ Index: iam/fs/ext3/iam_htree.c + namelen = strlen(name); + + scan = find_insertion_point(dir, leaf->il_bh, name, namelen); -+ assert(!IS_ERR(scan)); ++ assert_corr(!IS_ERR(scan)); + scan = split_entry(dir, scan, *ino, EXT3_FT_UNKNOWN, name, namelen); + leaf->il_at = (void *)scan; +} @@ -1701,7 +1712,7 @@ Index: iam/fs/ext3/iam_htree.c + struct ext3_dir_entry_2 *scan; + struct ext3_dir_entry_2 *prev; + -+ assert(iam_leaf_at_rec(leaf)); ++ assert_corr(iam_leaf_at_rec(leaf)); + + orig = getent(leaf); + @@ -1712,12 +1723,12 @@ Index: iam/fs/ext3/iam_htree.c + prev = scan, scan = entnext(scan)) + ; + -+ assert(scan == orig); ++ assert_corr(scan == orig); + if (prev != NULL) { + prev->rec_len = cpu_to_le16(le16_to_cpu(prev->rec_len) + + le16_to_cpu(scan->rec_len)); + } else { -+ assert(scan == getstart(leaf)); ++ assert_corr(scan == getstart(leaf)); + scan->inode = 0; + } + iam_leaf_container(leaf)->ic_object->i_version ++; @@ -1766,7 +1777,7 @@ Index: iam/fs/ext3/iam_htree.c + /* + * insertion point moves into new leaf. + */ -+ assert(delim_hash >= old_hash); ++ assert_corr(delim_hash >= old_hash); + iam_htree_lookup(l, (void *)&old_hash); + } +} @@ -1855,7 +1866,7 @@ Index: iam/fs/ext3/iam_htree.c + int namelen; + + root = data; -+ assert(path->ip_data != NULL); ++ assert_corr(path->ip_data != NULL); + ipc = container_of(path->ip_data, struct iam_path_compat, + ipc_descr); + @@ -1864,9 +1875,9 @@ Index: iam/fs/ext3/iam_htree.c + return check; + path->ip_indirect = root->info.indirect_levels; + -+ assert((char *)entries == (((char *)&root->info) + -+ root->info.info_length)); -+ assert(dx_get_limit(entries) == dx_root_limit(path)); ++ assert_corr((char *)entries == (((char *)&root->info) + ++ root->info.info_length)); ++ assert_corr(dx_get_limit(entries) == dx_root_limit(path)); + + ipc->ipc_hinfo->hash_version = root->info.hash_version; + ipc->ipc_hinfo->seed = EXT3_SB(sb)->s_hash_seed; @@ -1886,8 +1897,9 @@ Index: iam/fs/ext3/iam_htree.c + } + } else { + /* non-root index */ -+ assert(entries == data + iam_path_descr(path)->id_node_gap); -+ assert(dx_get_limit(entries) == dx_node_limit(path)); ++ assert_corr(entries == ++ data + iam_path_descr(path)->id_node_gap); ++ assert_corr(dx_get_limit(entries) == dx_node_limit(path)); + } + frame->entries = frame->at = entries; + return 0; @@ -1898,7 +1910,7 @@ Index: iam/fs/ext3/iam_htree.c +{ + struct dx_node *node; + -+ assert(!root); ++ assert_corr(!root); + + node = (void *)bh->b_data; + node->fake.rec_len = cpu_to_le16(c->ic_object->i_sb->s_blocksize); @@ -1989,7 +2001,7 @@ Index: iam/fs/ext3/iam_htree.c + struct buffer_head *bh; + const struct dx_root *root; + -+ assert(c->ic_object != NULL); ++ assert_corr(c->ic_object != NULL); + + result = iam_node_read(c, iam_htree_root_ptr(c), NULL, &bh); + if (result == 0) { @@ -2015,8 +2027,8 @@ Index: iam/fs/ext3/iam_htree.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-10-02 16:34:29.000000000 +0400 -@@ -0,0 +1,673 @@ ++++ iam/fs/ext3/iam_lfix.c 2006-10-03 21:14:08.000000000 +0400 +@@ -0,0 +1,675 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -2125,31 +2137,33 @@ Index: iam/fs/ext3/iam_lfix.c + +static void lentry_count_set(struct iam_leaf *leaf, unsigned count) +{ -+ assert(0 <= count && count <= leaf_count_limit(leaf)); ++ assert_corr(0 <= count && count <= leaf_count_limit(leaf)); + iam_get_head(leaf)->ill_count = cpu_to_le16(count); +} + +static struct iam_lentry *iam_lfix_get_end(const struct iam_leaf *l); + ++#if EXT3_CORRECTNESS || EXT3_INVARIANT +static int iam_leaf_at_rec(const struct iam_leaf *folio) +{ + return + iam_get_lentries(folio) <= folio->il_at && + folio->il_at < iam_lfix_get_end(folio); +} ++#endif + +static struct iam_ikey *iam_lfix_ikey(const struct iam_leaf *l, + struct iam_ikey *key) +{ + void *ie = l->il_at; -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + return (struct iam_ikey*)ie; +} + +static struct iam_key *iam_lfix_key(const struct iam_leaf *l) +{ + void *ie = l->il_at; -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + return (struct iam_key*)ie; +} + @@ -2172,7 +2186,7 @@ Index: iam/fs/ext3/iam_lfix.c + + esize = iam_lfix_entry_size(l); + diff = (void *)e1 - (void *)e2; -+ assert(diff / esize * esize == diff); ++ assert_corr(diff / esize * esize == diff); + return diff / esize; +} + @@ -2182,7 +2196,7 @@ Index: iam/fs/ext3/iam_lfix.c + struct iam_leaf_head *ill; + int count; + -+ assert(l->il_bh != NULL); ++ assert_corr(l->il_bh != NULL); + + ill = iam_get_head(l); + count = le16_to_cpu(ill->ill_count); @@ -2222,13 +2236,13 @@ Index: iam/fs/ext3/iam_lfix.c +struct iam_rec *iam_lfix_rec(const struct iam_leaf *l) +{ + void *e = l->il_at; -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + return e + iam_leaf_descr(l)->id_key_size; +} + +static void iam_lfix_next(struct iam_leaf *l) +{ -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + l->il_at = iam_lfix_shift(l, l->il_at, 1); +} + @@ -2262,11 +2276,11 @@ Index: iam/fs/ext3/iam_lfix.c + */ + while (iam_lfix_shift(l, p, 1) != q) { + m = iam_lfix_shift(l, p, iam_lfix_diff(l, q, p) / 2); -+ assert(p < m && m < q); ++ assert_corr(p < m && m < q); + (lfix_keycmp(c, iam_leaf_key_at(m), k) <= 0 ? p : q) = m; + } -+ assert(lfix_keycmp(c, iam_leaf_key_at(p), k) <= 0 && -+ lfix_keycmp(c, k, iam_leaf_key_at(q)) < 0); ++ assert_corr(lfix_keycmp(c, iam_leaf_key_at(p), k) <= 0 && ++ lfix_keycmp(c, k, iam_leaf_key_at(q)) < 0); + /* + * skip over records with duplicate keys. + */ @@ -2279,7 +2293,7 @@ Index: iam/fs/ext3/iam_lfix.c + } + l->il_at = p; + } -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + + if (lfix_keycmp(c, iam_leaf_key_at(l->il_at), k) == 0) + result = IAM_LOOKUP_EXACT; @@ -2295,7 +2309,7 @@ Index: iam/fs/ext3/iam_lfix.c + +static void iam_lfix_key_set(struct iam_leaf *l, const struct iam_key *k) +{ -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + memcpy(iam_leaf_key_at(l->il_at), k, iam_leaf_descr(l)->id_key_size); +} + @@ -2306,7 +2320,7 @@ Index: iam/fs/ext3/iam_lfix.c + +static void iam_lfix_rec_set(struct iam_leaf *l, const struct iam_rec *r) +{ -+ assert(iam_leaf_at_rec(l)); ++ assert_corr(iam_leaf_at_rec(l)); + iam_reccpy(iam_leaf_path(l), iam_lfix_rec(l), r); +} + @@ -2319,7 +2333,7 @@ Index: iam/fs/ext3/iam_lfix.c + ptrdiff_t diff; + int count; + -+ assert(iam_leaf_can_add(leaf, k, r)); ++ assert_corr(iam_leaf_can_add(leaf, k, r)); + + count = lentry_count_get(leaf); + /* @@ -2340,17 +2354,17 @@ Index: iam/fs/ext3/iam_lfix.c + * Another exceptional case: insertion with the key + * less than least key in the leaf. + */ -+ assert(cur == leaf->il_entries); ++ assert_corr(cur == leaf->il_entries); + + start = leaf->il_at; + diff = (void *)end - (void *)start; -+ assert(diff >= 0); ++ assert_corr(diff >= 0); + memmove(iam_lfix_shift(leaf, start, 1), start, diff); + } + lentry_count_set(leaf, count + 1); + iam_lfix_key_set(leaf, k); + iam_lfix_rec_set(leaf, r); -+ assert(iam_leaf_at_rec(leaf)); ++ assert_corr(iam_leaf_at_rec(leaf)); +} + +static void iam_lfix_rec_del(struct iam_leaf *leaf, int shift) @@ -2359,7 +2373,7 @@ Index: iam/fs/ext3/iam_lfix.c + int count; + ptrdiff_t diff; + -+ assert(iam_leaf_at_rec(leaf)); ++ assert_corr(iam_leaf_at_rec(leaf)); + + count = lentry_count_get(leaf); + end = iam_lfix_get_end(leaf); @@ -2439,7 +2453,7 @@ Index: iam/fs/ext3/iam_lfix.c + /* + * init cannot fail, as node was just initialized. + */ -+ assert(result == 0); ++ assert_corr(result == 0); + l->il_at = iam_lfix_shift(l, iam_get_lentries(l), shift); + } + @@ -2515,10 +2529,10 @@ Index: iam/fs/ext3/iam_lfix.c + entries = frame->entries; + + dx_set_count(entries, 2); -+ assert(dx_get_limit(entries) == dx_root_limit(path)); ++ assert_corr(dx_get_limit(entries) == dx_root_limit(path)); + + root = (void *)frame->bh->b_data; -+ assert(le64_to_cpu(root->ilr_magic) == IAM_LFIX_ROOT_MAGIC); ++ assert_corr(le64_to_cpu(root->ilr_magic) == IAM_LFIX_ROOT_MAGIC); + root->ilr_indirect_levels ++; + frame->at = entries = iam_entry_shift(path, entries, 1); + memset(iam_ikey_at(path, entries), 0, @@ -2617,7 +2631,7 @@ Index: iam/fs/ext3/iam_lfix.c + struct buffer_head *bh; + const struct iam_lfix_root *root; + -+ assert(c->ic_object != NULL); ++ assert_corr(c->ic_object != NULL); + + result = iam_node_read(c, iam_lfix_root_ptr(c), NULL, &bh); + if (result == 0) { @@ -2693,8 +2707,8 @@ Index: iam/fs/ext3/iam_lfix.c Index: iam/fs/ext3/iam_lvar.c =================================================================== --- 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 @@ ++++ iam/fs/ext3/iam_lvar.c 2006-10-03 21:14:26.000000000 +0400 +@@ -0,0 +1,902 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -2916,7 +2930,7 @@ Index: iam/fs/ext3/iam_lvar.c + int used; + + used = h_used(hdr) + adj; -+ assert(sizeof *hdr <= used && used <= blocksize(leaf)); ++ assert_corr(sizeof *hdr <= used && used <= blocksize(leaf)); + hdr->vlh_used = cpu_to_le16(used); +} + @@ -2935,19 +2949,21 @@ Index: iam/fs/ext3/iam_lvar.c + return lentry_lvar(l->il_at); +} + ++#if EXT3_CORRECTNESS || EXT3_INVARIANT +static int n_at_rec(const struct iam_leaf *folio) +{ + return + n_start(folio) <= lentry_lvar(folio->il_at) && + lentry_lvar(folio->il_at) < n_end(folio); +} ++#endif + +static struct iam_ikey *lvar_ikey(const struct iam_leaf *l, + struct iam_ikey *key) +{ + lvar_hash_t *hash; + -+ assert(n_at_rec(l)); ++ assert_corr(n_at_rec(l)); + + hash = (void *)key; + *hash = e_hash(n_cur(l)); @@ -2975,7 +2991,7 @@ Index: iam/fs/ext3/iam_lvar.c + int used; + struct lvar_leaf_header *head; + -+ assert(l->il_bh != NULL); ++ assert_corr(l->il_bh != NULL); + + head = n_head(l); + used = h_used(head); @@ -3006,13 +3022,13 @@ Index: iam/fs/ext3/iam_lvar.c + +struct iam_rec *lvar_rec(const struct iam_leaf *l) +{ -+ assert(n_at_rec(l)); ++ assert_corr(n_at_rec(l)); + return e_rec(n_cur(l)); +} + +static void lvar_next(struct iam_leaf *l) +{ -+ assert(n_at_rec(l)); ++ assert_corr(n_at_rec(l)); + l->il_at = lvar_lentry(e_next(l, n_cur(l))); +} + @@ -3064,7 +3080,7 @@ Index: iam/fs/ext3/iam_lvar.c + } else { + leaf->il_at = lvar_lentry(found); + result = IAM_LOOKUP_OK; -+ assert(n_at_rec(leaf)); ++ assert_corr(n_at_rec(leaf)); + } + return result; +} @@ -3093,8 +3109,8 @@ Index: iam/fs/ext3/iam_lvar.c + +static void lvar_key_set(struct iam_leaf *l, const struct iam_key *k) +{ -+ assert(n_at_rec(l)); -+ assert(strlen(kchar(k)) == e_keysize(n_cur(l))); ++ assert_corr(n_at_rec(l)); ++ assert_corr(strlen(kchar(k)) == e_keysize(n_cur(l))); + memcpy(e_key(n_cur(l)), k, e_keysize(n_cur(l))); +} + @@ -3111,7 +3127,7 @@ Index: iam/fs/ext3/iam_lvar.c + +static void lvar_rec_set(struct iam_leaf *l, const struct iam_rec *r) +{ -+ assert(n_at_rec(l)); ++ assert_corr(n_at_rec(l)); + iam_reccpy(iam_leaf_path(l), e_rec(n_cur(l)), r); +} + @@ -3136,7 +3152,7 @@ Index: iam/fs/ext3/iam_lvar.c + void *start; + ptrdiff_t diff; + -+ assert(lvar_can_add(leaf, k, r)); ++ assert_corr(lvar_can_add(leaf, k, r)); + + key = kchar(k); + ksize = strlen(key); @@ -3151,11 +3167,11 @@ Index: iam/fs/ext3/iam_lvar.c + * Another exceptional case: insertion with the key + * less than least key in the leaf. + */ -+ assert(leaf->il_at == leaf->il_entries); ++ assert_corr(leaf->il_at == leaf->il_entries); + + start = leaf->il_at; + diff = PDIFF(end, start); -+ assert(diff >= 0); ++ assert_corr(diff >= 0); + memmove(start + shift, start, diff); + } + h_used_adj(leaf, n_head(leaf), shift); @@ -3164,7 +3180,7 @@ Index: iam/fs/ext3/iam_lvar.c + key, ksize)); + lvar_key_set(leaf, k); + lvar_rec_set(leaf, r); -+ assert(n_at_rec(leaf)); ++ assert_corr(n_at_rec(leaf)); +} + +static void lvar_rec_del(struct iam_leaf *leaf, int shift) @@ -3173,7 +3189,7 @@ Index: iam/fs/ext3/iam_lvar.c + void *end; + int nob; + -+ assert(n_at_rec(leaf)); ++ assert_corr(n_at_rec(leaf)); + + end = n_end(leaf); + next = e_next(leaf, n_cur(leaf)); @@ -3225,8 +3241,8 @@ Index: iam/fs/ext3/iam_lvar.c + hdr = (void *)new_leaf->b_data; + + first_to_move = find_pivot(leaf, &last_to_stay); -+ assert(last_to_stay != NULL); -+ assert(e_next(leaf, last_to_stay) == first_to_move); ++ assert_corr(last_to_stay != NULL); ++ assert_corr(e_next(leaf, last_to_stay) == first_to_move); + + hash = e_hash(first_to_move); + if (hash == e_hash(last_to_stay)) @@ -3241,7 +3257,7 @@ Index: iam/fs/ext3/iam_lvar.c + h_used_adj(leaf, hdr, tomove); + h_used_adj(leaf, n_head(leaf), -tomove); + -+ assert(n_end(leaf) == first_to_move); ++ assert_corr(n_end(leaf) == first_to_move); + + /* + * Insert pointer to the new node (together with the least key in @@ -3263,7 +3279,7 @@ Index: iam/fs/ext3/iam_lvar.c + /* + * init cannot fail, as node was just initialized. + */ -+ assert(result == 0); ++ assert_corr(result == 0); + leaf->il_at = ((void *)leaf->il_at) + shift; + } +} @@ -3331,10 +3347,10 @@ Index: iam/fs/ext3/iam_lvar.c + entries = frame->entries; + + dx_set_count(entries, 2); -+ assert(dx_get_limit(entries) == dx_root_limit(path)); ++ assert_corr(dx_get_limit(entries) == dx_root_limit(path)); + + root = (void *)frame->bh->b_data; -+ assert(le64_to_cpu(root->vr_magic) == IAM_LVAR_ROOT_MAGIC); ++ assert_corr(le64_to_cpu(root->vr_magic) == IAM_LVAR_ROOT_MAGIC); + root->vr_indirect_levels ++; + frame->at = entries = iam_entry_shift(path, entries, 1); + memset(iam_ikey_at(path, entries), 0, @@ -3478,7 +3494,7 @@ Index: iam/fs/ext3/iam_lvar.c + * + * XXX: this key is hard-coded to be a sequence of 0's. + */ -+ assert(*(lvar_hash_t *)entry == 0); ++ assert_corr(*(lvar_hash_t *)entry == 0); + entry += sizeof(lvar_hash_t); + /* now @entry points to */ + if (ptrsize == 4) @@ -3521,7 +3537,7 @@ Index: iam/fs/ext3/iam_lvar.c + int result; + unsigned long bsize; + -+ assert(obj->i_size == 0); ++ assert_corr(obj->i_size == 0); + + sb = obj->i_sb; + bsize = sb->s_blocksize; @@ -3562,7 +3578,7 @@ Index: iam/fs/ext3/iam_lvar.c + struct buffer_head *bh; + const struct lvar_root *root; + -+ assert(c->ic_object != NULL); ++ assert_corr(c->ic_object != NULL); + + result = iam_node_read(c, lvar_root_ptr(c), NULL, &bh); + if (result == 0) { @@ -3598,7 +3614,7 @@ Index: iam/fs/ext3/iam_lvar.c Index: iam/fs/ext3/namei.c =================================================================== --- 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 ++++ iam/fs/ext3/namei.c 2006-10-03 20:59:58.000000000 +0400 @@ -24,81 +24,6 @@ * Theodore Ts'o, 2002 */ @@ -4143,20 +4159,20 @@ Index: iam/fs/ext3/namei.c -} - -static inline unsigned dx_node_limit(struct iam_path *p) -+int dx_index_is_compat(struct iam_path *path) - { +-{ - struct iam_descr *param = path_descr(p); - unsigned entry_space = path_obj(p)->i_sb->s_blocksize - - param->id_node_gap; - return entry_space / (param->id_key_size + param->id_ptr_size); +-} +- +-static inline int dx_index_is_compat(struct iam_path *path) ++int dx_index_is_compat(struct iam_path *path) + { +- return path_descr(path) == &htree_compat_param; + return iam_path_descr(path) == &iam_htree_compat_param; } --static inline int dx_index_is_compat(struct iam_path *path) --{ -- return path_descr(path) == &htree_compat_param; --} -- -static struct iam_entry *dx_get_entries(struct iam_path *path, void *data, - int root) -{ @@ -4164,14 +4180,14 @@ Index: iam/fs/ext3/namei.c - (root ? - path_descr(path)->id_root_gap : path_descr(path)->id_node_gap); -} -- + -static struct iam_entry *dx_node_get_entries(struct iam_path *path, - struct iam_frame *frame) -{ - return dx_get_entries(path, - frame->bh->b_data, frame == path->ip_frames); -} - +- -static int dx_node_check(struct iam_path *p, struct iam_frame *f) +int dx_node_check(struct iam_path *p, struct iam_frame *f) { @@ -4303,14 +4319,10 @@ Index: iam/fs/ext3/namei.c } /* -@@ -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 */ -- +@@ -800,598 +232,116 @@ struct stats dx_show_entries(struct dx_h + } + #endif /* DX_DEBUG */ + -static int dx_lookup(struct iam_path *path) -{ - u32 ptr; @@ -4671,7 +4683,8 @@ Index: iam/fs/ext3/namei.c -} - -static int split_leaf_node(handle_t *handle, struct iam_path *path) --{ ++int dx_lookup(struct iam_path *path) + { - struct inode *dir = path_obj(path); - unsigned continued = 0; - struct buffer_head *bh2; @@ -4747,7 +4760,10 @@ Index: iam/fs/ext3/namei.c - .hinfo = &hinfo - }; - int err, i; -- ++ 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] = @@ -4755,16 +4771,34 @@ Index: iam/fs/ext3/namei.c - err = dx_lookup(path); - if (err) - goto errout; -- ++ struct iam_descr *param; ++ struct iam_frame *frame; ++ struct iam_container *c; + - err = iam_leaf_insert(handle, path, k, r); -- ++ 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; ++ ptr = dx_get_block(path, frame->at), ++frame, ++i) { ++ struct iam_entry *entries; ++ struct iam_entry *p; ++ struct iam_entry *q; ++ struct iam_entry *m; ++ unsigned count; + - err = split_index_node(handle, path); - if (err) - 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; @@ -4773,19 +4807,22 @@ Index: iam/fs/ext3/namei.c -errout: - iam_path_fini(path); - return(err); -+ return (struct stats) { names, space, bcount}; - } -+#endif /* DX_DEBUG */ +-} ++ 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) -+int dx_lookup(struct iam_path *path) - { +-{ - struct iam_leaf leaf; - struct iam_leaf_entry *p, *q; - int err, count; -- ++ err = param->id_ops->id_node_load(path, frame); ++ if (err != 0) ++ break; + - err = iam_leaf_init(path, &leaf); - if (err) - goto errout; @@ -4793,7 +4830,8 @@ Index: iam/fs/ext3/namei.c - err = iam_leaf_lookup(path, &leaf, k); - if (err) - goto errout; -- ++ assert_inv(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); @@ -4803,29 +4841,71 @@ Index: iam/fs/ext3/namei.c - 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; ++ entries = frame->entries; ++ count = dx_get_count(entries); ++ assert_corr(count && count <= dx_get_limit(entries)); ++ p = iam_entry_shift(path, entries, 1); ++ q = iam_entry_shift(path, entries, count - 1); ++ while (p <= q) { ++ m = iam_entry_shift(path, ++ p, iam_entry_diff(path, q, p) / 2); ++ dxtrace(printk(".")); ++ if (iam_ikeycmp(c, iam_ikey_at(path, m), ++ path->ip_ikey_target) > 0) ++ q = iam_entry_shift(path, m, -1); ++ else ++ p = iam_entry_shift(path, m, +1); ++ } - 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; ++ 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(",")); ++ at = iam_entry_shift(path, at, +1); ++ if (iam_ikeycmp(c, iam_ikey_at(path, at), ++ path->ip_ikey_target) > 0) { ++ if (at != iam_entry_shift(path, frame->at, 1)) { ++ BREAKPOINT(); ++ printk(KERN_EMERG "%i\n", ++ iam_ikeycmp(c, iam_ikey_at(path, at), ++ path->ip_ikey_target)); ++ } ++ at = iam_entry_shift(path, at, -1); ++ break; ++ } ++ } ++ assert_corr(at == frame->at); ++ } ++ } ++ if (err != 0) ++ iam_path_fini(path); ++ path->ip_frame = --frame; + return err; + } --/* + /* - * Delete existing record with key @k. - * - * Return values: 0: success, -ENOENT: not-found, -ve: other error. -- * ++ * Probe for a directory leaf block to search. + * - * postcondition: ergo(result == 0 || result == -ENOENT, - * !iam_lookup(c, k, *)); -- */ ++ * 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) -{ - struct dx_hash_info hinfo; @@ -4835,19 +4915,7 @@ Index: iam/fs/ext3/namei.c - .hinfo = &hinfo - }; - int err, i; -+ param = iam_path_descr(path); -+ c = path->ip_container; -+ -+ for (frame = path->ip_frames, i = 0, -+ ptr = param->id_ops->id_root_ptr(c); -+ i <= path->ip_indirect; -+ ptr = dx_get_block(path, frame->at), ++frame, ++i) { -+ struct iam_entry *entries; -+ struct iam_entry *p; -+ struct iam_entry *q; -+ struct iam_entry *m; -+ unsigned count; - +- - iam_path_init(path, c, &hc); - for (i = 0; i < ARRAY_SIZE(path->ip_key_scratch); ++i) - path->ip_key_scratch[i] = @@ -4855,31 +4923,23 @@ Index: iam/fs/ext3/namei.c - err = dx_lookup(path); - if (err) - goto errout; -+ err = param->id_ops->id_node_read(c, (iam_ptr_t)ptr, NULL, -+ &frame->bh); -+ if (err != 0) -+ break; - +- - err = iam_leaf_delete(h, path, k); -errout: - iam_path_fini(path); - return err; -} -+ err = param->id_ops->id_node_check(path, frame); -+ if (err != 0) -+ break; - +- -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) --{ ++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; -+ assert(dx_node_check(path, frame)); + int err; ++ struct iam_path_compat *ipc; - err = iam_leaf_init(path, &leaf); - if (err) @@ -4888,79 +4948,33 @@ Index: iam/fs/ext3/namei.c - err = iam_leaf_lookup(path, &leaf, k); - if (err) - goto errout; -+ 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); -+ while (p <= q) { -+ m = iam_entry_shift(path, -+ p, iam_entry_diff(path, q, p) / 2); -+ dxtrace(printk(".")); -+ if (iam_ikeycmp(c, iam_ikey_at(path, m), -+ path->ip_ikey_target) > 0) -+ q = iam_entry_shift(path, m, -1); -+ else -+ 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; ++ assert_corr(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); -+ at = entries; -+ while (n--) { -+ dxtrace(printk(",")); -+ at = iam_entry_shift(path, at, +1); -+ if (iam_ikeycmp(c, iam_ikey_at(path, at), -+ path->ip_ikey_target) > 0) { -+ if (at != iam_entry_shift(path, frame->at, 1)) { -+ BREAKPOINT(); -+ printk(KERN_EMERG "%i\n", -+ iam_ikeycmp(c, iam_ikey_at(path, at), -+ path->ip_ikey_target)); -+ } -+ at = iam_entry_shift(path, at, -1); -+ break; -+ } -+ } -+ assert(at == frame->at); -+ } -+ } -+ if (err != 0) -+ iam_path_fini(path); -+ path->ip_frame = --frame; - return err; - } -+ - /* +- return err; +-} +-/* - * Replace existing record with key @k, or insert new one. New record data are - * in @r. - * - * Return values: 0: success, -ve: error. -+ * Probe for a directory leaf block to search. - * +- * - * 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_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; @@ -4973,23 +4987,15 @@ Index: iam/fs/ext3/namei.c - 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); ++ assert_corr(dx_index_is_compat(path)); + err = dx_lookup(path); - if (err) - goto errout; -+ int err; -+ struct iam_path_compat *ipc; - +- - 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; -+ -+ assert(dx_index_is_compat(path)); -+ err = dx_lookup(path); -+ assert(err != 0 || path->ip_frames[path->ip_indirect].bh != NULL); ++ assert_corr(err != 0 || path->ip_frames[path->ip_indirect].bh != NULL); return err; } @@ -5018,7 +5024,7 @@ Index: iam/fs/ext3/namei.c p = path->ip_frame; /* * Find the next leaf page by incrementing the frame pointer. -@@ -1438,28 +387,34 @@ static int ext3_htree_next_block(struct +@@ -1438,39 +387,55 @@ static int ext3_htree_next_block(struct --p; } @@ -5069,7 +5075,12 @@ Index: iam/fs/ext3/namei.c if (err != 0) return err; /* Failure */ ++p; -@@ -1471,6 +426,16 @@ static int ext3_htree_next_block(struct + brelse (p->bh); + p->bh = bh; + p->at = p->entries = dx_node_get_entries(path, p); +- assert(dx_node_check(path, p)); ++ assert_inv(dx_node_check(path, p)); + } return 1; } @@ -5100,9 +5111,10 @@ Index: iam/fs/ext3/namei.c + struct iam_entry *new = iam_entry_shift(path, frame->at, +1); int count = dx_get_count(entries); - assert(count < dx_get_limit(entries)); +- assert(count < dx_get_limit(entries)); - assert(old < iam_entry_shift(path, entries, count)); -+ assert(frame->at < iam_entry_shift(path, entries, count)); ++ assert_corr(count < dx_get_limit(entries)); ++ assert_corr(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); @@ -5116,7 +5128,7 @@ Index: iam/fs/ext3/namei.c +void dx_insert_block(struct iam_path *path, struct iam_frame *frame, + u32 hash, u32 block) +{ -+ assert(dx_index_is_compat(path)); ++ assert_corr(dx_index_is_compat(path)); + iam_insert_key(path, frame, (struct iam_ikey *)&hash, block); +} + @@ -5450,7 +5462,7 @@ Index: iam/fs/ext3/namei.c + /* + * Algorithm below depends on this. + */ -+ assert(dx_root_limit(path) < dx_node_limit(path)); ++ assert_corr(dx_root_limit(path) < dx_node_limit(path)); + frame = path->ip_frame; entries = frame->entries; @@ -5490,7 +5502,7 @@ Index: iam/fs/ext3/namei.c struct iam_frame *frames; + struct iam_entry *next; + -+ assert(i == 0); ++ assert_corr(i == 0); frames = path->ip_frames; - root = (struct dx_root *) frames->bh->b_data; @@ -5510,14 +5522,17 @@ Index: iam/fs/ext3/namei.c /* Shift frames in the path */ memmove(frames + 2, frames + 1, -@@ -2537,48 +1603,60 @@ static int split_index_node(handle_t *ha +@@ -2536,49 +1602,61 @@ static int split_index_node(handle_t *ha + frames[1].at = iam_entry_shift(path, entries2, idx); frames[1].entries = entries = entries2; frames[1].bh = bh2; - assert(dx_node_check(path, frame)); +- assert(dx_node_check(path, frame)); ++ assert_inv(dx_node_check(path, frame)); + ++ path->ip_frame; ++ frame; - assert(dx_node_check(path, frame)); +- assert(dx_node_check(path, frame)); - bh_new[i] = NULL; /* buffer head is "consumed" */ ++ assert_inv(dx_node_check(path, frame)); + bh_new[0] = NULL; /* buffer head is "consumed" */ err = ext3_journal_get_write_access(handle, bh2); if (err) @@ -5558,9 +5573,10 @@ Index: iam/fs/ext3/namei.c + parent->at, +1); } - dx_insert_block(path, frame - 1, hash2, newblock[i]); - assert(dx_node_check(path, frame)); +- assert(dx_node_check(path, frame)); - assert(dx_node_check(path, frame - 1)); -+ assert(dx_node_check(path, parent)); ++ assert_inv(dx_node_check(path, frame)); ++ assert_inv(dx_node_check(path, parent)); dxtrace(dx_show_index ("node", frame->entries)); dxtrace(dx_show_index ("node", ((struct dx_node *) bh2->b_data)->entries)); @@ -5578,8 +5594,8 @@ Index: iam/fs/ext3/namei.c + * This function was called to make insertion of new leaf + * possible. Check that it fulfilled its obligations. + */ -+ assert(dx_get_count(path->ip_frame->entries) < -+ dx_get_limit(path->ip_frame->entries)); ++ assert_corr(dx_get_count(path->ip_frame->entries) < ++ dx_get_limit(path->ip_frame->entries)); + } + if (nr_splet > 0) { + /* @@ -5612,7 +5628,7 @@ Index: iam/fs/ext3/namei.c if (err != 0) goto cleanup; -@@ -2641,7 +1720,7 @@ static int ext3_dx_add_entry(handle_t *h +@@ -2641,11 +1720,11 @@ static int ext3_dx_add_entry(handle_t *h goto cleanup; /*copy split inode too*/ @@ -5621,6 +5637,11 @@ Index: iam/fs/ext3/namei.c if (!de) goto cleanup; +- assert(dx_node_check(path, frame)); ++ assert_inv(dx_node_check(path, frame)); + err = add_dirent_to_buf(handle, dentry, inode, de, bh); + goto cleanup2; + @@ -2758,12 +1837,12 @@ static struct inode * ext3_new_inode_wan * is so far negative - it has no inode. * @@ -5639,7 +5660,7 @@ Index: iam/fs/ext3/namei.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-10-03 00:15:55.000000000 +0400 ++++ iam/include/linux/lustre_iam.h 2006-10-03 21:14:47.000000000 +0400 @@ -1,9 +1,68 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: diff --git a/lustre/kernel_patches/patches/ext3-iam-uapi.patch b/lustre/kernel_patches/patches/ext3-iam-uapi.patch index 229a92c..e9fcf06 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-10-03 00:15:55.000000000 +0400 -+++ iam/fs/ext3/Makefile 2006-10-03 00:15:56.000000000 +0400 +--- iam.orig/fs/ext3/Makefile 2006-10-03 21:14:47.000000000 +0400 ++++ iam/fs/ext3/Makefile 2006-10-03 21:14:47.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-10-03 00:15:55.000000000 +0400 -+++ iam/fs/ext3/dir.c 2006-10-03 00:15:56.000000000 +0400 +--- iam.orig/fs/ext3/dir.c 2006-10-03 21:14:47.000000000 +0400 ++++ iam/fs/ext3/dir.c 2006-10-03 21:14:47.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-10-03 00:15:55.000000000 +0400 -+++ iam/fs/ext3/file.c 2006-10-03 00:15:56.000000000 +0400 +--- iam.orig/fs/ext3/file.c 2006-10-03 21:14:47.000000000 +0400 ++++ iam/fs/ext3/file.c 2006-10-03 21:14:47.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-10-03 00:15:56.000000000 +0400 ++++ iam/fs/ext3/iam-uapi.c 2006-10-03 21:14:47.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-10-03 00:15:55.000000000 +0400 -+++ iam/fs/ext3/ioctl.c 2006-10-03 00:15:56.000000000 +0400 +--- iam.orig/fs/ext3/ioctl.c 2006-10-03 21:14:47.000000000 +0400 ++++ iam/fs/ext3/ioctl.c 2006-10-03 21:14:47.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-10-03 00:15:55.000000000 +0400 -+++ iam/include/linux/lustre_iam.h 2006-10-03 00:15:56.000000000 +0400 +--- iam.orig/include/linux/lustre_iam.h 2006-10-03 21:14:47.000000000 +0400 ++++ iam/include/linux/lustre_iam.h 2006-10-03 21:14:47.000000000 +0400 @@ -30,9 +30,6 @@ #ifndef __LINUX_LUSTRE_IAM_H__ #define __LINUX_LUSTRE_IAM_H__ @@ -552,7 +552,7 @@ Index: iam/include/linux/lustre_iam.h /* * linux/include/linux/lustre_iam.h */ -@@ -57,14 +54,21 @@ enum { +@@ -57,14 +54,64 @@ enum { * [2] reserved for leaf node operations. * * [3] reserved for index operations. @@ -572,10 +572,53 @@ Index: iam/include/linux/lustre_iam.h +/* handle_t, journal_start(), journal_stop() */ +#include + ++/* ++ * Debugging. ++ * ++ * Various debugging levels. ++ */ ++ ++/* ++ * Compile basic assertions in. You want this most of the time. ++ */ ++#define EXT3_ASSERT (1) ++ ++/* ++ * Compile heavier correctness checks in. You want this during development ++ * cycle. ++ */ ++#define EXT3_CORRECTNESS (0) ++ ++/* ++ * Compile heavy invariant checking in. You want this early during development ++ * or when chasing a bug. ++ */ ++#define EXT3_INVARIANT (0) ++ ++#ifndef assert ++#if EXT3_ASSERT ++#define assert(test) J_ASSERT(test) ++#else ++#define assert(test) ((void)(test)) ++#endif ++#endif ++ ++#if EXT3_CORRECTNESS ++#define assert_corr(test) J_ASSERT(test) ++#else ++#define assert_corr(test) do {;} while (0) ++#endif ++ ++#if EXT3_INVARIANT ++#define assert_inv(test) J_ASSERT(test) ++#else ++#define assert_inv(test) do {;} while (0) ++#endif ++ /* * Entry within index tree node. Consists of a key immediately followed * (without padding) by a pointer to the child node. -@@ -86,14 +90,21 @@ struct iam_entry_compat { +@@ -86,14 +133,21 @@ struct iam_entry_compat { */ struct iam_key; @@ -602,7 +645,7 @@ Index: iam/include/linux/lustre_iam.h typedef __u64 iam_ptr_t; /* -@@ -123,6 +134,31 @@ struct iam_leaf { +@@ -123,6 +177,31 @@ struct iam_leaf { void *il_descr_data; }; @@ -634,7 +677,7 @@ Index: iam/include/linux/lustre_iam.h struct iam_operations { /* * Returns pointer (in the same sense as pointer in index entry) to -@@ -131,11 +167,15 @@ struct iam_operations { +@@ -131,11 +210,15 @@ struct iam_operations { __u32 (*id_root_ptr)(struct iam_container *c); /* @@ -652,7 +695,7 @@ Index: iam/include/linux/lustre_iam.h * Initialize new node (stored in @bh) that is going to be added into * tree. */ -@@ -144,23 +184,33 @@ struct iam_operations { +@@ -144,23 +227,33 @@ struct iam_operations { int (*id_node_read)(struct iam_container *c, iam_ptr_t ptr, handle_t *h, struct buffer_head **bh); /* @@ -694,7 +737,7 @@ Index: iam/include/linux/lustre_iam.h struct iam_leaf_operations { /* * leaf operations. -@@ -186,7 +236,8 @@ struct iam_leaf_operations { +@@ -186,7 +279,8 @@ struct iam_leaf_operations { void (*start)(struct iam_leaf *l); /* more leaf to the next entry. */ void (*next)(struct iam_leaf *l); @@ -704,7 +747,7 @@ Index: iam/include/linux/lustre_iam.h * either pointer to the key stored in node, or copy key into * @k buffer supplied by caller and return pointer to this * buffer. The latter approach is used when keys in nodes are -@@ -194,8 +245,10 @@ struct iam_leaf_operations { +@@ -194,8 +288,10 @@ struct iam_leaf_operations { * all). * * Caller should assume that returned pointer is only valid @@ -717,7 +760,7 @@ Index: iam/include/linux/lustre_iam.h /* return pointer to entry body. Pointer is valid while corresponding leaf node is locked and pinned. */ struct iam_rec *(*rec)(const struct iam_leaf *l); -@@ -203,6 +256,9 @@ struct iam_leaf_operations { +@@ -203,6 +299,9 @@ struct iam_leaf_operations { void (*key_set)(struct iam_leaf *l, const struct iam_key *k); void (*rec_set)(struct iam_leaf *l, const struct iam_rec *r); @@ -727,7 +770,7 @@ Index: iam/include/linux/lustre_iam.h /* * Search leaf @l for a record with key @k or for a place * where such record is to be inserted. -@@ -210,6 +266,7 @@ struct iam_leaf_operations { +@@ -210,6 +309,7 @@ struct iam_leaf_operations { * Scratch keys from @path can be used. */ int (*lookup)(struct iam_leaf *l, const struct iam_key *k); @@ -735,7 +778,7 @@ Index: iam/include/linux/lustre_iam.h int (*can_add)(const struct iam_leaf *l, const struct iam_key *k, const struct iam_rec *r); -@@ -221,12 +278,13 @@ struct iam_leaf_operations { +@@ -221,12 +321,13 @@ struct iam_leaf_operations { /* * remove rec for a leaf */ @@ -751,7 +794,7 @@ Index: iam/include/linux/lustre_iam.h }; struct iam_path *iam_leaf_path(const struct iam_leaf *leaf); -@@ -241,6 +299,10 @@ struct iam_descr { +@@ -241,6 +342,10 @@ struct iam_descr { */ size_t id_key_size; /* @@ -762,7 +805,7 @@ Index: iam/include/linux/lustre_iam.h * Size of a pointer to the next level (stored in index nodes), in * bytes. */ -@@ -264,6 +326,9 @@ struct iam_descr { +@@ -264,6 +369,9 @@ struct iam_descr { struct iam_leaf_operations *id_leaf_ops; }; @@ -772,7 +815,7 @@ Index: iam/include/linux/lustre_iam.h struct iam_container { /* * Underlying flat file. IO against this object is issued to -@@ -284,7 +349,7 @@ struct iam_path_descr { +@@ -284,7 +392,7 @@ struct iam_path_descr { /* * Scratch-pad area for temporary keys. */ @@ -781,7 +824,7 @@ Index: iam/include/linux/lustre_iam.h }; /* -@@ -316,6 +381,7 @@ struct iam_path { +@@ -316,6 +424,7 @@ struct iam_path { * Key searched for. */ const struct iam_key *ip_key_target; @@ -789,7 +832,7 @@ Index: iam/include/linux/lustre_iam.h /* * Description-specific data. */ -@@ -334,6 +400,7 @@ struct iam_path_compat { +@@ -334,6 +443,7 @@ struct iam_path_compat { struct dx_hash_info *ipc_hinfo; struct dentry *ipc_dentry; struct iam_path_descr ipc_descr; @@ -797,7 +840,7 @@ Index: iam/include/linux/lustre_iam.h }; /* -@@ -347,7 +414,9 @@ enum iam_it_state { +@@ -347,7 +457,9 @@ enum iam_it_state { /* initial state */ IAM_IT_DETACHED, /* iterator is above particular record in the container */ @@ -808,7 +851,7 @@ Index: iam/include/linux/lustre_iam.h }; /* -@@ -355,7 +424,7 @@ enum iam_it_state { +@@ -355,7 +467,7 @@ enum iam_it_state { */ enum iam_it_flags { /* @@ -817,7 +860,7 @@ Index: iam/include/linux/lustre_iam.h */ IAM_IT_MOVE = (1 << 0), /* -@@ -372,15 +441,26 @@ enum iam_it_flags { +@@ -372,15 +484,26 @@ enum iam_it_flags { * doesn't point to any particular record in this container. * * After successful call to iam_it_get() and until corresponding call to @@ -847,7 +890,7 @@ Index: iam/include/linux/lustre_iam.h * */ struct iam_iterator { -@@ -390,7 +470,8 @@ struct iam_iterator { +@@ -390,7 +513,8 @@ struct iam_iterator { __u32 ii_flags; enum iam_it_state ii_state; /* @@ -857,7 +900,7 @@ Index: iam/include/linux/lustre_iam.h */ struct iam_path ii_path; }; -@@ -405,133 +486,26 @@ void iam_path_compat_fini(struct iam_pat +@@ -405,133 +529,26 @@ void iam_path_compat_fini(struct iam_pat struct iam_path_descr *iam_ipd_alloc(int keysize); void iam_ipd_free(struct iam_path_descr *ipd); @@ -996,7 +1039,7 @@ Index: iam/include/linux/lustre_iam.h int iam_it_load(struct iam_iterator *it, iam_pos_t pos); int iam_lookup(struct iam_container *c, const struct iam_key *k, -@@ -539,10 +513,10 @@ int iam_lookup(struct iam_container *c, +@@ -539,10 +556,10 @@ int iam_lookup(struct iam_container *c, int iam_delete(handle_t *h, struct iam_container *c, const struct iam_key *k, struct iam_path_descr *pd); int iam_update(handle_t *h, struct iam_container *c, const struct iam_key *k, @@ -1009,7 +1052,18 @@ Index: iam/include/linux/lustre_iam.h /* * Initialize container @c. */ -@@ -577,16 +551,65 @@ static inline struct inode *iam_path_obj +@@ -558,10 +575,6 @@ void iam_container_fini(struct iam_conta + */ + int iam_container_setup(struct iam_container *c); + +-#ifndef assert +-#define assert(test) J_ASSERT(test) +-#endif +- + static inline struct iam_descr *iam_container_descr(struct iam_container *c) + { + return c->ic_descr; +@@ -577,16 +590,65 @@ static inline struct inode *iam_path_obj return p->ip_container->ic_object; } @@ -1029,19 +1083,15 @@ Index: iam/include/linux/lustre_iam.h +static inline struct iam_entry *iam_entry_shift(struct iam_path *p, + struct iam_entry *entry, + int shift) - { -- memcpy(k1, k2, c->ic_descr->id_key_size); ++{ + void *e = entry; + return e + shift * iam_entry_size(p); - } - --static inline int iam_keycmp(const struct iam_container *c, -- const struct iam_key *k1, const struct iam_key *k2) ++} ++ +static inline struct iam_ikey *iam_get_ikey(struct iam_path *p, + struct iam_entry *entry, + struct iam_ikey *key) - { -- return c->ic_descr->id_ops->id_keycmp(c, k1, k2); ++{ + return memcpy(key, entry, iam_path_descr(p)->id_ikey_size); +} + @@ -1058,7 +1108,7 @@ Index: iam/include/linux/lustre_iam.h + ptrdiff_t diff; + + diff = (void *)e1 - (void *)e2; -+ assert(diff / iam_entry_size(p) * iam_entry_size(p) == diff); ++ assert_corr(diff / iam_entry_size(p) * iam_entry_size(p) == diff); + return diff / iam_entry_size(p); +} + @@ -1068,20 +1118,24 @@ Index: iam/include/linux/lustre_iam.h + */ +static inline void iam_ikeycpy0(const struct iam_container *c, + struct iam_ikey *k1, const struct iam_ikey *k2) -+{ + { +- memcpy(k1, k2, c->ic_descr->id_key_size); + if (k1 != k2) + iam_ikeycpy(c, k1, k2); -+} -+ + } + +-static inline int iam_keycmp(const struct iam_container *c, +- const struct iam_key *k1, const struct iam_key *k2) +static inline int iam_ikeycmp(const struct iam_container *c, + const struct iam_ikey *k1, + const struct iam_ikey *k2) -+{ + { +- return c->ic_descr->id_ops->id_keycmp(c, k1, k2); + return c->ic_descr->id_ops->id_ikeycmp(c, k1, k2); } static inline void iam_reccpy(const struct iam_path *p, struct iam_rec *rec_dst, -@@ -604,7 +627,7 @@ static inline void *iam_entry_off(struct +@@ -604,7 +666,7 @@ static inline void *iam_entry_off(struct static inline unsigned dx_get_block(struct iam_path *p, struct iam_entry *entry) { return le32_to_cpu(*(u32*)iam_entry_off(entry, @@ -1090,7 +1144,7 @@ Index: iam/include/linux/lustre_iam.h & 0x00ffffff; } -@@ -612,21 +635,64 @@ static inline void dx_set_block(struct i +@@ -612,21 +674,64 @@ static inline void dx_set_block(struct i struct iam_entry *entry, unsigned value) { *(u32*)iam_entry_off(entry, @@ -1159,7 +1213,7 @@ Index: iam/include/linux/lustre_iam.h static inline unsigned dx_get_count(struct iam_entry *entries) { return le16_to_cpu(((struct dx_countlimit *) entries)->count); -@@ -647,9 +713,21 @@ static inline unsigned dx_node_limit(str +@@ -647,9 +752,21 @@ static inline unsigned dx_node_limit(str struct iam_descr *param = iam_path_descr(p); unsigned entry_space = iam_path_obj(p)->i_sb->s_blocksize - param->id_node_gap; @@ -1182,7 +1236,7 @@ Index: iam/include/linux/lustre_iam.h static inline struct iam_entry *dx_get_entries(struct iam_path *path, void *data, int root) { -@@ -665,7 +743,8 @@ static inline struct iam_entry *dx_node_ +@@ -665,7 +782,8 @@ static inline struct iam_entry *dx_node_ frame->bh->b_data, frame == path->ip_frames); } @@ -1192,7 +1246,7 @@ Index: iam/include/linux/lustre_iam.h { assert(0 <= nr && nr < ARRAY_SIZE(path->ip_data->ipd_key_scratch)); return path->ip_data->ipd_key_scratch[nr]; -@@ -674,6 +753,7 @@ static inline struct iam_key *iam_path_k +@@ -674,6 +792,7 @@ static inline struct iam_key *iam_path_k int dx_lookup(struct iam_path *path); void dx_insert_block(struct iam_path *path, struct iam_frame *frame, u32 hash, u32 block); @@ -1200,7 +1254,7 @@ Index: iam/include/linux/lustre_iam.h int ext3_htree_next_block(struct inode *dir, __u32 hash, struct iam_path *path, __u32 *start_hash); -@@ -681,6 +761,20 @@ int ext3_htree_next_block(struct inode * +@@ -681,6 +800,20 @@ int ext3_htree_next_block(struct inode * struct buffer_head *ext3_append(handle_t *handle, struct inode *inode, u32 *block, int *err); int split_index_node(handle_t *handle, struct iam_path *path); @@ -1221,7 +1275,7 @@ Index: iam/include/linux/lustre_iam.h /* * external -@@ -698,10 +792,12 @@ int iam_node_read(struct iam_container * +@@ -698,10 +831,12 @@ int iam_node_read(struct iam_container * handle_t *handle, struct buffer_head **bh); void iam_insert_key(struct iam_path *path, struct iam_frame *frame, @@ -1235,7 +1289,7 @@ Index: iam/include/linux/lustre_iam.h struct iam_path *iam_leaf_path(const struct iam_leaf *leaf); struct iam_container *iam_leaf_container(const struct iam_leaf *leaf); -@@ -709,14 +805,79 @@ struct iam_descr *iam_leaf_descr(const s +@@ -709,14 +844,79 @@ struct iam_descr *iam_leaf_descr(const s struct iam_leaf_operations *iam_leaf_ops(const struct iam_leaf *leaf); -- 1.8.3.1