From: nikita Date: Tue, 27 Jun 2006 22:32:55 +0000 (+0000) Subject: iam update X-Git-Tag: v1_8_0_110~486^2~1525 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=805c6280ff9be17f4850a4c3b34f8aeba154a935;p=fs%2Flustre-release.git iam update --- diff --git a/lustre/cmm/cmm_object.c b/lustre/cmm/cmm_object.c index 863d3ba..1d11696 100644 --- a/lustre/cmm/cmm_object.c +++ b/lustre/cmm/cmm_object.c @@ -36,7 +36,7 @@ #include "cmm_internal.h" #include "mdc_internal.h" -static int cmm_fld_lookup(struct cmm_device *cm, +static int cmm_fld_lookup(struct cmm_device *cm, const struct lu_fid *fid, mdsno_t *mds) { int rc = 0; @@ -107,7 +107,7 @@ struct lu_object *cmm_object_alloc(const struct lu_context *ctx, lu_object_init(lo, NULL, ld); clo->cmm_obj.cmo_obj.mo_ops = &cml_mo_ops; clo->cmm_obj.cmo_obj.mo_dir_ops = &cml_dir_ops; - lo->lo_ops = &cml_obj_ops; + lo->lo_ops = &cml_obj_ops; } } else { struct cmr_object *cro; diff --git a/lustre/kernel_patches/patches/ext3-iam-separate.patch b/lustre/kernel_patches/patches/ext3-iam-separate.patch index 7169ecf..444d3c7 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-05-31 20:24:32.000000000 +0400 -+++ iam/fs/ext3/Makefile 2006-06-23 01:50:19.000000000 +0400 ++++ iam/fs/ext3/Makefile 2006-06-28 01:37:26.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-06-23 00:42:45.000000000 +0400 -@@ -0,0 +1,1242 @@ ++++ iam/fs/ext3/iam.c 2006-06-28 00:25:38.000000000 +0400 +@@ -0,0 +1,1229 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -159,6 +159,11 @@ Index: iam/fs/ext3/iam.c + static int initialized = 0; + + if (!initialized) { ++ /* ++ * Keep that order: htree should be registered first, ++ * so that iam_htree_guess() runs last. ++ */ ++ iam_htree_format_init(); + iam_lfix_format_init(); + initialized = 1; + } @@ -231,9 +236,10 @@ Index: iam/fs/ext3/iam.c +{ + int i; + ++ path->ipc_hinfo = &path->ipc_hinfo_area; + for (i = 0; i < ARRAY_SIZE(path->ipc_scratch); ++i) + path->ipc_descr.ipd_key_scratch[i] = -+ (struct iam_key *)&path->ipc_scratch[i]; ++ (struct iam_ikey *)&path->ipc_scratch[i]; + + iam_container_init(&path->ipc_container, + &iam_htree_compat_param, inode); @@ -319,19 +325,27 @@ Index: iam/fs/ext3/iam.c +} + +/* -+ * Return pointer to the current leaf key. This function may return either -+ * pointer to the key stored in node, or copy key into @key buffer supplied by -+ * caller and return pointer to this buffer. The latter approach is used when -+ * keys in nodes are not stored in plain form (e.g., htree doesn't store keys -+ * at all). ++ * Return pointer to the current leaf key. This function returns pointer to ++ * the key stored in node. + * + * Caller should assume that returned pointer is only valid while leaf node is + * pinned and locked. + */ -+static struct iam_key *iam_leaf_key(const struct iam_leaf *leaf, -+ struct iam_key *key) ++static struct iam_key *iam_leaf_key(const struct iam_leaf *leaf) ++{ ++ return iam_leaf_ops(leaf)->key(leaf); ++} ++ ++static struct iam_ikey *iam_leaf_ikey(const struct iam_leaf *leaf, ++ struct iam_ikey *key) ++{ ++ return iam_leaf_ops(leaf)->ikey(leaf, key); ++} ++ ++static int iam_leaf_keycmp(const struct iam_leaf *leaf, ++ const struct iam_key *key) +{ -+ return iam_leaf_ops(leaf)->key(leaf, key); ++ return iam_leaf_ops(leaf)->key_cmp(leaf, key); +} + +static int iam_leaf_check(struct iam_leaf *leaf); @@ -440,8 +454,8 @@ Index: iam/fs/ext3/iam.c + struct iam_lentry *orig; + struct iam_path *path; + struct iam_container *bag; -+ struct iam_key *k0; -+ struct iam_key *k1; ++ struct iam_ikey *k0; ++ struct iam_ikey *k1; + int result; + int first; + @@ -454,12 +468,12 @@ Index: iam/fs/ext3/iam.c + return result; + + first = 1; -+ k0 = iam_path_key(path, 0); -+ k1 = iam_path_key(path, 1); ++ k0 = iam_path_ikey(path, 0); ++ k1 = iam_path_ikey(path, 1); + while (!iam_leaf_at_end(leaf)) { -+ iam_keycpy(bag, k0, k1); -+ iam_keycpy(bag, k1, iam_leaf_key(leaf, k1)); -+ if (!first && iam_keycmp(bag, k0, k1) > 0) ++ iam_ikeycpy(bag, k0, k1); ++ iam_ikeycpy(bag, k1, iam_leaf_ikey(leaf, k1)); ++ if (!first && iam_ikeycmp(bag, k0, k1) > 0) + return 0; + first = 0; + iam_leaf_next(leaf); @@ -502,20 +516,15 @@ Index: iam/fs/ext3/iam.c +/* + * Helper function returning scratch key. + */ -+static struct iam_key *it_scratch_key(const struct iam_iterator *it, int n) -+{ -+ return iam_path_key(&it->ii_path, n); -+} -+ +static struct iam_container *iam_it_container(const struct iam_iterator *it) +{ + return it->ii_path.ip_container; +} + +static inline int it_keycmp(const struct iam_iterator *it, -+ const struct iam_key *k1, const struct iam_key *k2) ++ const struct iam_key *k) +{ -+ return iam_keycmp(iam_it_container(it), k1, k2); ++ return iam_leaf_keycmp(&it->ii_path.ip_leaf, k); +} + +static inline int it_at_rec(const struct iam_iterator *it) @@ -538,8 +547,7 @@ Index: iam/fs/ext3/iam.c + + result = iam_it_get(it, k); + if (result == 0 && -+ (it_state(it) != IAM_IT_ATTACHED || -+ it_keycmp(it, k, iam_it_key_get(it, it_scratch_key(it, 1))) != 0)) ++ (it_state(it) != IAM_IT_ATTACHED || it_keycmp(it, k) != 0)) + /* + * Return -ENOENT if cursor is located above record with a key + * different from one specified, or in the empty leaf. @@ -648,7 +656,7 @@ Index: iam/fs/ext3/iam.c + * + * precondition: it_state(it) == IAM_IT_DETACHED + * postcondition: ergo(result == 0 && it_state(it) == IAM_IT_ATTACHED, -+ * it_keycmp(it, iam_it_key_get(it, *), k) <= 0) ++ * it_keycmp(it, k) <= 0) + */ +int iam_it_get(struct iam_iterator *it, const struct iam_key *k) +{ @@ -674,8 +682,7 @@ Index: iam/fs/ext3/iam.c + } else + iam_it_unlock(it); + assert(ergo(result == 0 && it_state(it) == IAM_IT_ATTACHED, -+ it_keycmp(it, iam_it_key_get(it, it_scratch_key(it, 0)), -+ k) <= 0)); ++ it_keycmp(it, k) <= 0)); + /* + * See iam_it_get_exact() for explanation. + */ @@ -716,7 +723,7 @@ Index: iam/fs/ext3/iam.c + * dst->ii_flags = src->ii_flags && + * ergo(it_state(src) == IAM_IT_ATTACHED, + * iam_it_rec_get(dst) == iam_it_rec_get(src) && -+ * iam_it_key_get(dst, *1) == iam_it_key_get(src, *2)) ++ * iam_it_key_get(dst) == iam_it_key_get(src)) + */ +void iam_it_dup(struct iam_iterator *dst, const struct iam_iterator *src) +{ @@ -731,8 +738,7 @@ Index: iam/fs/ext3/iam.c + assert(dst->ii_flags = src->ii_flags); + assert(ergo(it_state(src) == IAM_IT_ATTACHED, + iam_it_rec_get(dst) == iam_it_rec_get(src) && -+ iam_it_key_get(dst, it_scratch_key(dst, 0)) == -+ iam_it_key_get(src, it_scratch_key(src, 0)))); ++ iam_it_key_get(dst) == iam_it_key_get(src))); + +} + @@ -855,26 +861,17 @@ Index: iam/fs/ext3/iam.c +} + +/* -+ * Assertionless version of iam_it_key_get(). -+ */ -+static struct iam_key *__iam_it_key_get(const struct iam_iterator *it, -+ struct iam_key *k) -+{ -+ return iam_leaf_key(&it->ii_path.ip_leaf, k); -+} -+ -+/* + * Return pointer to the key under iterator. + * + * precondition: it_state(it) == IAM_IT_ATTACHED || + * it_state(it) == IAM_IT_SKEWED + * postcondition: it_state(it) == IAM_IT_ATTACHED + */ -+struct iam_key *iam_it_key_get(const struct iam_iterator *it, struct iam_key *k) ++struct iam_key *iam_it_key_get(const struct iam_iterator *it) +{ + assert(it_state(it) == IAM_IT_ATTACHED); + assert(it_at_rec(it)); -+ return __iam_it_key_get(it, k); ++ return iam_leaf_key(&it->ii_path.ip_leaf); +} + +/* @@ -975,14 +972,11 @@ Index: iam/fs/ext3/iam.c + * (it_state(it) == IAM_IT_ATTACHED || + * it_state(it) == IAM_IT_SKEWED) && + * ergo(it_state(it) == IAM_IT_ATTACHED, -+ * it_keycmp(it, iam_it_key_get(it, it_scratch_key(it, 0)), -+ * k) < 0) && -+ * ergo(it_before(it), -+ * it_keycmp(it, __iam_it_key_get(it, it_scratch_key(it, 0)), -+ * k) > 0)); ++ * it_keycmp(it, k) < 0) && ++ * ergo(it_before(it), it_keycmp(it, k) > 0)); + * postcondition: ergo(result == 0, + * it_state(it) == IAM_IT_ATTACHED && -+ * it_keycmp(it, iam_it_key_get(it, *), k) == 0 && ++ * it_keycmp(it, k) == 0 && + * !memcmp(iam_it_rec_get(it), r, ...)) + */ +int iam_it_rec_insert(handle_t *h, struct iam_iterator *it, @@ -996,19 +990,13 @@ Index: iam/fs/ext3/iam.c + 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, iam_it_key_get(it, it_scratch_key(it, 0)), -+ k) < 0)); -+ assert(ergo(it_before(it), -+ it_keycmp(it, __iam_it_key_get(it, it_scratch_key(it, 0)), -+ k) > 0)); ++ assert(ergo(it_state(it) == IAM_IT_ATTACHED, it_keycmp(it, k) < 0)); ++ assert(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, iam_it_key_get(it, it_scratch_key(it, 0)), -+ k) == 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; @@ -1074,8 +1062,7 @@ Index: iam/fs/ext3/iam.c + assert(it_at_rec(it)); + assert(iam_it_container(it)->ic_descr->id_key_size <= sizeof result); + -+ result = 0; -+ iam_it_key_get(it, (struct iam_key *)&result); ++ result = *(iam_pos_t *)iam_it_key_get(it); + return result; +} + @@ -1261,8 +1248,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-06-22 16:56:26.000000000 +0400 -@@ -0,0 +1,579 @@ ++++ iam/fs/ext3/iam_htree.c 2006-06-28 01:17:33.000000000 +0400 +@@ -0,0 +1,636 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -1301,13 +1288,10 @@ Index: iam/fs/ext3/iam_htree.c +#include +#include + -+struct htree_dirent { -+ __le32 hd_ino; -+ __le16 hd_reclen; -+ u8 hd_namelen; -+ u8 hd_type; -+ char hd_name[0]; -+}; ++static inline struct ext3_dir_entry_2 *dent(struct iam_lentry *ent) ++{ ++ return (struct ext3_dir_entry_2 *)ent; ++} + +static inline struct iam_path_compat *getipc(const struct iam_leaf *folio) +{ @@ -1319,48 +1303,59 @@ Index: iam/fs/ext3/iam_htree.c + return container_of(path->ip_data, struct iam_path_compat, ipc_descr); +} + -+static inline struct htree_dirent *getent(const struct iam_leaf *folio) ++static inline struct ext3_dir_entry_2 *getent(const struct iam_leaf *folio) +{ -+ return (void *)folio->il_at; ++ return dent(folio->il_at); +} + -+static __u32 gethash(const struct iam_leaf *folio, -+ const struct htree_dirent *ent) ++static __u32 hashname(const struct iam_leaf *folio, ++ const char *name, int namelen) +{ + int result; + struct dx_hash_info *hinfo; + + hinfo = getipc(folio)->ipc_hinfo; + assert(hinfo != NULL); -+ result = ext3fs_dirhash(ent->hd_name, ent->hd_namelen, hinfo); ++ result = ext3fs_dirhash(name, namelen, hinfo); + assert(result == 0); + return hinfo->hash; +} + ++static __u32 gethash(const struct iam_leaf *folio, ++ const struct ext3_dir_entry_2 *ent) ++{ ++ return hashname(folio, ent->name, ent->name_len); ++} ++ +static inline size_t recsize(size_t namelen) +{ + return EXT3_DIR_REC_LEN(namelen); +} + -+static struct htree_dirent *gettop(const struct iam_leaf *folio) ++static struct ext3_dir_entry_2 *getlast(const struct iam_leaf *folio, int namelen) +{ + return + (void *)folio->il_bh->b_data + + iam_leaf_container(folio)->ic_object->i_sb->s_blocksize - -+ recsize(0); ++ recsize(namelen); +} + -+static inline int ent_is_live(const struct htree_dirent *ent) ++static struct ext3_dir_entry_2 *gettop(const struct iam_leaf *folio) +{ -+ return ent->hd_ino != 0; ++ return getlast(folio, 0); +} + -+static struct htree_dirent *entnext(const struct htree_dirent *ent) ++static inline int ent_is_live(const struct ext3_dir_entry_2 *ent) +{ -+ return (void *)ent + le16_to_cpu(ent->hd_reclen); ++ return ent->inode != 0; +} + -+static struct htree_dirent *skipdead(struct htree_dirent *ent) ++static struct ext3_dir_entry_2 *entnext(const struct ext3_dir_entry_2 *ent) ++{ ++ return (void *)ent + le16_to_cpu(ent->rec_len); ++} ++ ++static struct ext3_dir_entry_2 *skipdead(struct ext3_dir_entry_2 *ent) +{ + if (!ent_is_live(ent)) + ent = entnext(ent); @@ -1370,24 +1365,24 @@ Index: iam/fs/ext3/iam_htree.c + return ent; +} + -+static struct htree_dirent *getstart(const struct iam_leaf *folio) ++static struct ext3_dir_entry_2 *getstart(const struct iam_leaf *folio) +{ + return (void *)folio->il_bh->b_data; +} + -+static int getfreespace(const struct htree_dirent *ent) ++static int getfreespace(const struct ext3_dir_entry_2 *ent) +{ + int free; + -+ free = le16_to_cpu(ent->hd_reclen); ++ free = le16_to_cpu(ent->rec_len); + if (ent_is_live(ent)) -+ free -= recsize(ent->hd_namelen); ++ free -= recsize(ent->name_len); + assert(free >= 0); + return free; +} + +static int entcmp(const struct iam_leaf *folio, -+ const struct htree_dirent *e0, const struct htree_dirent *e1) ++ const struct ext3_dir_entry_2 *e0, const struct ext3_dir_entry_2 *e1) +{ + __u32 hash0; + __u32 hash1; @@ -1411,7 +1406,7 @@ Index: iam/fs/ext3/iam_htree.c + +static int iam_leaf_at_rec(const struct iam_leaf *folio) +{ -+ struct htree_dirent *ent; ++ struct ext3_dir_entry_2 *ent; + + ent = getent(folio); + return getstart(folio) <= ent && @@ -1422,7 +1417,7 @@ Index: iam/fs/ext3/iam_htree.c + * Leaf operations. + */ + -+struct iam_key *iam_htree_key(const struct iam_leaf *l, struct iam_key *key) ++struct iam_ikey *iam_htree_ikey(const struct iam_leaf *l, struct iam_ikey *key) +{ + __u32 *hash; + assert(iam_leaf_at_rec(l)); @@ -1432,6 +1427,13 @@ Index: iam/fs/ext3/iam_htree.c + return key; +} + ++struct iam_key *iam_htree_key(const struct iam_leaf *l) ++{ ++ assert(iam_leaf_at_rec(l)); ++ ++ return (struct iam_key *)&getent(l)->name; ++} ++ +static void iam_htree_start(struct iam_leaf *l) +{ + l->il_at = (void *)skipdead(getstart(l)); @@ -1453,13 +1455,13 @@ Index: iam/fs/ext3/iam_htree.c +struct iam_rec *iam_htree_rec(const struct iam_leaf *l) +{ + assert(iam_leaf_at_rec(l)); -+ return (void *)getent(l); ++ return (void *)&getent(l)->inode; +} + +static void iam_htree_next(struct iam_leaf *l) +{ -+ struct htree_dirent *scan; -+ struct htree_dirent *found; ++ struct ext3_dir_entry_2 *scan; ++ struct ext3_dir_entry_2 *found; + + assert(iam_leaf_at_rec(l)); + found = NULL; @@ -1478,28 +1480,38 @@ Index: iam/fs/ext3/iam_htree.c +} + + ++static inline int match(int len, const char *const name, ++ struct ext3_dir_entry_2 *de) ++{ ++ if (len != de->name_len) ++ return 0; ++ if (!de->inode) ++ return 0; ++ return !memcmp(name, de->name, len); ++} ++ +static int iam_htree_lookup(struct iam_leaf *l, const struct iam_key *k) +{ + struct iam_container *c; -+ struct htree_dirent *scan; -+ struct htree_dirent *found; ++ struct ext3_dir_entry_2 *scan; ++ struct ext3_dir_entry_2 *found; + __u32 hash; + int result; ++ int namelen; ++ const char *name; + + c = iam_leaf_container(l); -+ hash = *(__u32 *)k; ++ name = (const char *)k; ++ namelen = strlen(name); ++ hash = hashname(l, name, namelen); + found = NULL; -+ for (scan = getstart(l); scan < gettop(l); scan = entnext(scan)) { -+ __u32 scanhash; -+ -+ if (ent_is_live(scan)) { -+ scanhash = gethash(l, scan); -+ if (hash == scanhash) { -+ found = scan; -+ break; -+ } else if (scanhash < hash) -+ found = scan; -+ } ++ for (scan = getstart(l); scan < getlast(l, namelen); ++ scan = entnext(scan)) { ++ if (match(namelen, name, scan)) { ++ found = scan; ++ break; ++ } else if (ent_is_live(scan) && gethash(l, scan) <= hash) ++ found = scan; + } + if (found == NULL) { + /* @@ -1521,41 +1533,57 @@ Index: iam/fs/ext3/iam_htree.c + assert(0); +} + ++static int iam_htree_key_cmp(const struct iam_leaf *l, const struct iam_key *k) ++{ ++ struct ext3_dir_entry_2 *hd; ++ const char *name; ++ int result; ++ ++ name = (const char *)k; ++ hd = getent(l); ++ assert(ent_is_live(hd)); ++ ++ result = strncmp(hd->name, name, hd->name_len); ++ if (result == 0 && strlen(name) < hd->name_len) ++ result = -1; ++ return result; ++} ++ +static void iam_htree_rec_set(struct iam_leaf *l, const struct iam_rec *r) +{ -+ memcpy(l->il_at, r, recsize(((struct htree_dirent *)r)->hd_namelen)); ++ __u32 *ino; ++ ++ ino = (void *)r; ++ getent(l)->inode = cpu_to_le32(*ino); +} + +static void iam_htree_rec_add(struct iam_leaf *leaf, + const struct iam_key *k, const struct iam_rec *r) +{ -+ struct htree_dirent *scan; -+ struct htree_dirent *new; ++ struct ext3_dir_entry_2 *scan; + struct inode *dir; + const char *name; -+ int namelen; + -+ assert(iam_leaf_can_add(leaf, k, r)); ++ __u32 *ino; ++ int namelen; + -+ new = (void *)r; -+ assert(*(__u32 *)k == gethash(leaf, new)); ++ assert(iam_leaf_can_add(leaf, k, r)); + -+ dir = iam_leaf_container(leaf)->ic_object; -+ name = new->hd_name; -+ namelen = new->hd_namelen; ++ dir = iam_leaf_container(leaf)->ic_object; ++ ino = (void *)r; ++ name = (const char *)k; ++ namelen = strlen(name); + -+ scan = (void *)find_insertion_point(dir, leaf->il_bh, -+ name, namelen); ++ scan = find_insertion_point(dir, leaf->il_bh, name, namelen); + assert(!IS_ERR(scan)); -+ scan = (void *)split_entry(dir, (void *)scan, le32_to_cpu(new->hd_ino), -+ new->hd_type, name, namelen); ++ scan = split_entry(dir, scan, *ino, EXT3_FT_UNKNOWN, name, namelen); + leaf->il_at = (void *)scan; +} + +static void iam_htree_rec_del(struct iam_leaf *leaf) +{ -+ struct htree_dirent *scan; -+ struct htree_dirent *prev; ++ struct ext3_dir_entry_2 *scan; ++ struct ext3_dir_entry_2 *prev; + + assert(iam_leaf_at_rec(leaf)); + @@ -1565,11 +1593,11 @@ Index: iam/fs/ext3/iam_htree.c + + assert(scan == getent(leaf)); + if (prev != NULL) { -+ prev->hd_reclen = cpu_to_le16(le16_to_cpu(prev->hd_reclen) + -+ le16_to_cpu(scan->hd_reclen)); ++ prev->rec_len = cpu_to_le16(le16_to_cpu(prev->rec_len) + ++ le16_to_cpu(scan->rec_len)); + } else { + assert(scan == getstart(leaf)); -+ scan->hd_ino = 0; ++ scan->inode = 0; + } + iam_leaf_container(leaf)->ic_object->i_version ++; +} @@ -1577,11 +1605,12 @@ Index: iam/fs/ext3/iam_htree.c +static int iam_htree_can_add(const struct iam_leaf *leaf, + const struct iam_key *k, const struct iam_rec *r) +{ -+ struct htree_dirent *scan; ++ struct ext3_dir_entry_2 *scan; + int size; + -+ size = recsize(((struct htree_dirent *)r)->hd_namelen); -+ for (scan = getstart(leaf); scan < gettop(leaf); scan = entnext(scan)) { ++ size = recsize(strlen((const char *)k)); ++ for (scan = getstart(leaf); ++ scan < gettop(leaf); scan = entnext(scan)) { + if (getfreespace(scan) >= size) + return 1; + } @@ -1628,8 +1657,10 @@ Index: iam/fs/ext3/iam_htree.c + .start = iam_htree_start, + .next = iam_htree_next, + .key = iam_htree_key, ++ .ikey = iam_htree_ikey, + .rec = iam_htree_rec, + .key_set = iam_htree_key_set, ++ .key_cmp = iam_htree_key_cmp, + .rec_set = iam_htree_rec_set, + .lookup = iam_htree_lookup, + .at_end = iam_htree_at_end, @@ -1662,7 +1693,7 @@ Index: iam/fs/ext3/iam_htree.c + ext3_warning(sb, __FUNCTION__, + "Unrecognised inode hash code %d", + root->info.hash_version); -+ return ERR_BAD_DX_DIR; ++ return -EIO; + } + + if (root->info.unused_flags & 1) { @@ -1670,7 +1701,7 @@ Index: iam/fs/ext3/iam_htree.c + ext3_warning(sb, __FUNCTION__, + "Unimplemented inode hash flags: %#06x", + root->info.unused_flags); -+ return ERR_BAD_DX_DIR; ++ return -EIO; + } + + if (root->info.indirect_levels > DX_MAX_TREE_HEIGHT - 1) { @@ -1678,7 +1709,7 @@ Index: iam/fs/ext3/iam_htree.c + ext3_warning(sb, __FUNCTION__, + "Unimplemented inode hash depth: %#06x", + root->info.indirect_levels); -+ return ERR_BAD_DX_DIR; ++ return -EIO; + } + return 0; +} @@ -1697,6 +1728,8 @@ Index: iam/fs/ext3/iam_htree.c + struct dx_root *root; + struct iam_path_compat *ipc; + int check; ++ const char *name; ++ int namelen; + + root = data; + assert(path->ip_data != NULL); @@ -1714,12 +1747,18 @@ Index: iam/fs/ext3/iam_htree.c + + ipc->ipc_hinfo->hash_version = root->info.hash_version; + ipc->ipc_hinfo->seed = EXT3_SB(sb)->s_hash_seed; -+ if (ipc->ipc_dentry) -+ ext3fs_dirhash(ipc->ipc_dentry->d_name.name, -+ ipc->ipc_dentry->d_name.len, -+ ipc->ipc_hinfo); -+ path->ip_key_target = -+ (const struct iam_key *)&ipc->ipc_hinfo->hash; ++ name = NULL; ++ if (ipc->ipc_dentry) { ++ name = ipc->ipc_dentry->d_name.name; ++ namelen = ipc->ipc_dentry->d_name.len; ++ } else if (ipc->ipc_hinfo == &ipc->ipc_hinfo_area){ ++ name = (const char *)path->ip_key_target; ++ namelen = strlen(name); ++ } ++ if (name != NULL) ++ ext3fs_dirhash(name, namelen, ipc->ipc_hinfo); ++ path->ip_ikey_target = iam_path_ikey(path, 4); ++ *(__u32 *)path->ip_ikey_target = ipc->ipc_hinfo->hash; + } else { + /* non-root index */ + assert(entries == data + iam_path_descr(path)->id_node_gap); @@ -1758,8 +1797,9 @@ Index: iam/fs/ext3/iam_htree.c + return entries; +} + -+static int iam_htree_keycmp(const struct iam_container *c, -+ const struct iam_key *k1, const struct iam_key *k2) ++static int iam_htree_ikeycmp(const struct iam_container *c, ++ const struct iam_ikey *k1, ++ const struct iam_ikey *k2) +{ + __u32 p1 = le32_to_cpu(*(__u32 *)k1); + __u32 p2 = le32_to_cpu(*(__u32 *)k2); @@ -1773,6 +1813,7 @@ Index: iam/fs/ext3/iam_htree.c + + ipc = kmalloc(sizeof *ipc, GFP_KERNEL); + if (ipc != NULL) { ++ memset(ipc, 0, sizeof *ipc); + iam_path_compat_init(ipc, c->ic_object); + return &ipc->ipc_descr; + } else @@ -1794,7 +1835,7 @@ Index: iam/fs/ext3/iam_htree.c + .id_node_init = iam_htree_node_init, + .id_node_check = iam_htree_node_check, + .id_node_load = iam_htree_node_load, -+ .id_keycmp = iam_htree_keycmp, ++ .id_ikeycmp = iam_htree_ikeycmp, + .id_root_inc = iam_htree_root_inc, + .id_ipd_alloc = iam_htree_ipd_alloc, + .id_ipd_free = iam_htree_ipd_free, @@ -1806,12 +1847,14 @@ Index: iam/fs/ext3/iam_htree.c + * can be manipulated. + */ +struct iam_descr iam_htree_compat_param = { -+ .id_key_size = sizeof ((struct dx_map_entry *)NULL)->hash, -+ .id_ptr_size = sizeof ((struct dx_map_entry *)NULL)->offs, -+ .id_node_gap = offsetof(struct dx_node, entries), -+ .id_root_gap = offsetof(struct dx_root, entries), -+ .id_ops = &iam_htree_ops, -+ .id_leaf_ops = &iam_htree_leaf_ops ++ .id_key_size = EXT3_NAME_LEN, ++ .id_rec_size = sizeof ((struct ext3_dir_entry_2 *)NULL)->inode, ++ .id_ikey_size = sizeof ((struct dx_map_entry *)NULL)->hash, ++ .id_ptr_size = sizeof ((struct dx_map_entry *)NULL)->offs, ++ .id_node_gap = offsetof(struct dx_node, entries), ++ .id_root_gap = offsetof(struct dx_root, entries), ++ .id_ops = &iam_htree_ops, ++ .id_leaf_ops = &iam_htree_leaf_ops +}; +EXPORT_SYMBOL(iam_htree_compat_param); + @@ -1826,7 +1869,8 @@ Index: iam/fs/ext3/iam_htree.c + result = iam_node_read(c, iam_htree_root_ptr(c), NULL, &bh); + if (result == 0) { + root = (void *)bh->b_data; -+ if (is_htree(c->ic_object->i_sb, root, 1)) ++ result = is_htree(c->ic_object->i_sb, root, 1); ++ if (result == 0) + c->ic_descr = &iam_htree_compat_param; + else + result = -EBADF; @@ -1845,8 +1889,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-06-22 15:30:33.000000000 +0400 -@@ -0,0 +1,629 @@ ++++ iam/fs/ext3/iam_lfix.c 2006-06-28 00:09:00.000000000 +0400 +@@ -0,0 +1,649 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -1917,6 +1961,13 @@ Index: iam/fs/ext3/iam_lfix.c + return (struct iam_key *)entry; +} + ++static inline int lfix_keycmp(const struct iam_container *c, ++ const struct iam_key *k1, ++ const struct iam_key *k2) ++{ ++ return memcmp(k1, k2, c->ic_descr->id_key_size); ++} ++ +static struct iam_leaf_head *iam_get_head(const struct iam_leaf *l) +{ + return (struct iam_leaf_head *)l->il_bh->b_data; @@ -1961,11 +2012,14 @@ Index: iam/fs/ext3/iam_lfix.c + folio->il_at < iam_lfix_get_end(folio); +} + -+/*This func is for flat key, for those keys, -+ *which are not stored explicitly -+ *it would be decrypt in the key buffer -+ */ -+struct iam_key *iam_lfix_key(const struct iam_leaf *l, struct iam_key *key) ++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)); ++ return (struct iam_ikey*)ie; ++} ++ ++struct iam_key *iam_lfix_key(const struct iam_leaf *l) +{ + void *ie = l->il_at; + assert(iam_leaf_at_rec(l)); @@ -2062,13 +2116,13 @@ Index: iam/fs/ext3/iam_lfix.c + + p = l->il_entries; + q = iam_lfix_shift(l, p, count - 1); -+ if (iam_keycmp(c, k, iam_leaf_key_at(p)) < 0) { ++ if (lfix_keycmp(c, k, iam_leaf_key_at(p)) < 0) { + /* + * @k is less than the least key in the leaf + */ + l->il_at = p; + result = IAM_LOOKUP_BEFORE; -+ } else if (iam_keycmp(c, iam_leaf_key_at(q), k) <= 0) { ++ } else if (lfix_keycmp(c, iam_leaf_key_at(q), k) <= 0) { + l->il_at = q; + } else { + /* @@ -2077,16 +2131,16 @@ 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); -+ (iam_keycmp(c, iam_leaf_key_at(m), k) <= 0 ? p : q) = m; ++ (lfix_keycmp(c, iam_leaf_key_at(m), k) <= 0 ? p : q) = m; + } -+ assert(iam_keycmp(c, iam_leaf_key_at(p), k) <= 0 && -+ iam_keycmp(c, k, iam_leaf_key_at(q)) < 0); ++ assert(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. + */ + while (p > l->il_entries) { + t = iam_lfix_shift(l, p, -1); -+ if (iam_keycmp(c, iam_leaf_key_at(t), k) == 0) ++ if (lfix_keycmp(c, iam_leaf_key_at(t), k) == 0) + p = t; + else + break; @@ -2101,7 +2155,12 @@ 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)); -+ iam_keycpy(iam_leaf_container(l), iam_leaf_key_at(l->il_at), k); ++ memcpy(iam_leaf_key_at(l->il_at), k, iam_leaf_descr(l)->id_key_size); ++} ++ ++static int iam_lfix_key_cmp(const struct iam_leaf *l, const struct iam_key *k) ++{ ++ return lfix_keycmp(iam_leaf_container(l), iam_leaf_key_at(l->il_at), k); +} + +static void iam_lfix_rec_set(struct iam_leaf *l, const struct iam_rec *r) @@ -2132,7 +2191,7 @@ Index: iam/fs/ext3/iam_lfix.c + if (!iam_leaf_at_end(leaf)) { + end = iam_lfix_get_end(leaf); + cur = leaf->il_at; -+ if (iam_keycmp(iam_leaf_container(leaf), ++ if (lfix_keycmp(iam_leaf_container(leaf), + k, iam_leaf_key_at(cur)) >= 0) + iam_lfix_next(leaf); + else @@ -2193,10 +2252,10 @@ Index: iam/fs/ext3/iam_lfix.c +static void iam_lfix_split(struct iam_leaf *l, struct buffer_head **bh, + iam_ptr_t new_blknr) +{ -+ struct iam_path *path; -+ struct iam_leaf_head *hdr; -+ const struct iam_key *pivot; -+ struct buffer_head *new_leaf; ++ struct iam_path *path; ++ struct iam_leaf_head *hdr; ++ const struct iam_ikey *pivot; ++ struct buffer_head *new_leaf; + + unsigned count; + unsigned split; @@ -2215,7 +2274,7 @@ Index: iam/fs/ext3/iam_lfix.c + 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(start); ++ pivot = (const struct iam_ikey *)iam_leaf_key_at(start); + + memmove(iam_entries(new_leaf), start, finis - start); + hdr->ill_count = count - split; @@ -2252,8 +2311,10 @@ Index: iam/fs/ext3/iam_lfix.c + .start = iam_lfix_start, + .next = iam_lfix_next, + .key = iam_lfix_key, ++ .ikey = iam_lfix_ikey, + .rec = iam_lfix_rec, + .key_set = iam_lfix_key_set, ++ .key_cmp = iam_lfix_key_cmp, + .rec_set = iam_lfix_rec_set, + .lookup = iam_lfix_lookup, + .at_end = iam_lfix_at_end, @@ -2364,20 +2425,22 @@ Index: iam/fs/ext3/iam_lfix.c + + root = data; + path->ip_indirect = le16_to_cpu(root->ilr_indirect_levels); ++ path->ip_ikey_target = (struct iam_ikey *)path->ip_key_target; + } + frame->entries = frame->at = entries; + return 0; +} + -+static int iam_lfix_keycmp(const struct iam_container *c, -+ const struct iam_key *k1, const struct iam_key *k2) ++static int iam_lfix_ikeycmp(const struct iam_container *c, ++ const struct iam_ikey *k1, ++ const struct iam_ikey *k2) +{ -+ return memcmp(k1, k2, c->ic_descr->id_key_size); ++ return memcmp(k1, k2, c->ic_descr->id_ikey_size); +} + +static struct iam_path_descr *iam_lfix_ipd_alloc(const struct iam_container *c) +{ -+ return iam_ipd_alloc(c->ic_descr->id_key_size); ++ return iam_ipd_alloc(c->ic_descr->id_ikey_size); +} + +static void iam_lfix_ipd_free(const struct iam_container *c, @@ -2392,7 +2455,7 @@ Index: iam/fs/ext3/iam_lfix.c + .id_node_init = iam_lfix_node_init, + .id_node_check = iam_lfix_node_check, + .id_node_load = iam_lfix_node_load, -+ .id_keycmp = iam_lfix_keycmp, ++ .id_ikeycmp = iam_lfix_ikeycmp, + .id_root_inc = iam_lfix_root_inc, + .id_ipd_alloc = iam_lfix_ipd_alloc, + .id_ipd_free = iam_lfix_ipd_free, @@ -2414,13 +2477,14 @@ Index: iam/fs/ext3/iam_lfix.c + struct iam_descr *descr; + + descr = c->ic_descr; -+ descr->id_key_size = le16_to_cpu(root->ilr_keysize); -+ descr->id_rec_size = le16_to_cpu(root->ilr_recsize); -+ descr->id_ptr_size = le16_to_cpu(root->ilr_ptrsize); -+ descr->id_root_gap = sizeof(struct iam_lfix_root); -+ descr->id_node_gap = 0; -+ descr->id_ops = &iam_lfix_ops; -+ descr->id_leaf_ops = &iam_lfix_leaf_ops; ++ descr->id_key_size = le16_to_cpu(root->ilr_keysize); ++ descr->id_ikey_size = le16_to_cpu(root->ilr_keysize); ++ descr->id_rec_size = le16_to_cpu(root->ilr_recsize); ++ descr->id_ptr_size = le16_to_cpu(root->ilr_ptrsize); ++ descr->id_root_gap = sizeof(struct iam_lfix_root); ++ descr->id_node_gap = 0; ++ descr->id_ops = &iam_lfix_ops; ++ descr->id_leaf_ops = &iam_lfix_leaf_ops; + } else + result = -EBADF; + } @@ -2479,7 +2543,7 @@ Index: iam/fs/ext3/iam_lfix.c Index: iam/fs/ext3/namei.c =================================================================== --- iam.orig/fs/ext3/namei.c 2006-05-31 20:24:32.000000000 +0400 -+++ iam/fs/ext3/namei.c 2006-06-22 16:57:21.000000000 +0400 ++++ iam/fs/ext3/namei.c 2006-06-27 21:10:17.000000000 +0400 @@ -24,81 +24,6 @@ * Theodore Ts'o, 2002 */ @@ -2901,7 +2965,7 @@ Index: iam/fs/ext3/namei.c static unsigned dx_get_limit(struct iam_entry *entries); static void dx_set_count(struct iam_entry *entries, unsigned value); static void dx_set_limit(struct iam_entry *entries, unsigned value); -@@ -457,264 +100,51 @@ static void dx_sort_map(struct dx_map_en +@@ -457,264 +100,52 @@ 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); @@ -3071,11 +3135,12 @@ Index: iam/fs/ext3/namei.c for (i = 0; i < count - 1; ++i, e = iam_entry_shift(p, e, 1)) { - keycpy(c, p->ip_key_scratch[0], p->ip_key_scratch[1]); - dx_get_key(p, e, p->ip_key_scratch[1]); -+ iam_keycpy(c, iam_path_key(p, 0), iam_path_key(p, 1)); -+ iam_get_key(p, e, iam_path_key(p, 1)); ++ iam_ikeycpy(c, iam_path_ikey(p, 0), iam_path_ikey(p, 1)); ++ iam_get_ikey(p, e, iam_path_ikey(p, 1)); if (i > 0 && - keycmp(c, p->ip_key_scratch[0], p->ip_key_scratch[1]) > 0) -+ iam_keycmp(c, iam_path_key(p, 0), iam_path_key(p, 1)) > 0) { ++ iam_ikeycmp(c, iam_path_ikey(p, 0), ++ iam_path_ikey(p, 1)) > 0) { + BREAKPOINT; return 0; - } @@ -3182,7 +3247,7 @@ Index: iam/fs/ext3/namei.c } /* -@@ -800,598 +230,132 @@ struct stats dx_show_entries(struct dx_h +@@ -800,598 +231,132 @@ struct stats dx_show_entries(struct dx_h } #endif /* DX_DEBUG */ @@ -3622,12 +3687,7 @@ Index: iam/fs/ext3/namei.c - .hinfo = &hinfo - }; - int err, i; -+int dx_lookup(struct iam_path *path) -+{ -+ u32 ptr; -+ int err = 0; -+ int i; - +- - iam_path_init(path, c, &hc); - for (i = 0; i < ARRAY_SIZE(path->ip_key_scratch); ++i) - path->ip_key_scratch[i] = @@ -3635,6 +3695,12 @@ Index: iam/fs/ext3/namei.c - err = dx_lookup(path); - if (err) - goto errout; ++int dx_lookup(struct iam_path *path) ++{ ++ u32 ptr; ++ int err = 0; ++ int i; ++ + struct iam_descr *param; + struct iam_frame *frame; + struct iam_container *c; @@ -3715,8 +3781,8 @@ Index: iam/fs/ext3/namei.c + * key in the node. + */ + if (!dx_index_is_compat(path) && -+ iam_keycmp(c, iam_key_at(path, p), -+ path->ip_key_target) > 0) { ++ iam_ikeycmp(c, iam_ikey_at(path, p), ++ path->ip_ikey_target) > 0) { + struct inode *obj; + + obj = c->ic_object; @@ -3730,8 +3796,8 @@ Index: iam/fs/ext3/namei.c + m = iam_entry_shift(path, + p, iam_entry_diff(path, q, p) / 2); + dxtrace(printk(".")); -+ if (iam_keycmp(c, iam_key_at(path, m), -+ path->ip_key_target) > 0) ++ 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); @@ -3751,13 +3817,13 @@ Index: iam/fs/ext3/namei.c + while (n--) { + dxtrace(printk(",")); + at = iam_entry_shift(path, at, +1); -+ if (iam_keycmp(c, iam_key_at(path, at), -+ path->ip_key_target) > 0) { ++ 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_keycmp(c, iam_key_at(path, at), -+ path->ip_key_target)); ++ iam_ikeycmp(c, iam_ikey_at(path, at), ++ path->ip_ikey_target)); + } + at = iam_entry_shift(path, at, -1); + break; @@ -3884,7 +3950,7 @@ 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 -@@ -1409,16 +373,15 @@ EXPORT_SYMBOL(iam_update); +@@ -1409,16 +374,15 @@ EXPORT_SYMBOL(iam_update); * If start_hash is non-null, it will be filled in with the starting * hash of the next page. */ @@ -3904,7 +3970,7 @@ Index: iam/fs/ext3/namei.c p = path->ip_frame; /* * Find the next leaf page by incrementing the frame pointer. -@@ -1438,28 +401,34 @@ static int ext3_htree_next_block(struct +@@ -1438,28 +402,34 @@ static int ext3_htree_next_block(struct --p; } @@ -3932,7 +3998,7 @@ Index: iam/fs/ext3/namei.c + * 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); ++ iam_get_ikey(path, p->at, (struct iam_ikey *)&bhash); + if (start_hash) + *start_hash = bhash; + if ((hash & 1) == 0) { @@ -3955,7 +4021,7 @@ Index: iam/fs/ext3/namei.c if (err != 0) return err; /* Failure */ ++p; -@@ -1471,6 +440,16 @@ static int ext3_htree_next_block(struct +@@ -1471,6 +441,16 @@ static int ext3_htree_next_block(struct return 1; } @@ -3972,14 +4038,14 @@ Index: iam/fs/ext3/namei.c /* * p is at least 6 bytes before the end of page -@@ -1662,21 +641,30 @@ static void dx_sort_map (struct dx_map_e +@@ -1662,21 +642,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 iam_insert_key(struct iam_path *path, struct iam_frame *frame, -+ const struct iam_key *key, iam_ptr_t ptr) ++ const struct iam_ikey *key, iam_ptr_t ptr) { struct iam_entry *entries = frame->entries; - struct iam_entry *old = frame->at, *new = iam_entry_shift(path, old, +1); @@ -3994,7 +4060,7 @@ Index: iam/fs/ext3/namei.c (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_ikey(path, new, key); + dx_set_block(path, new, ptr); dx_set_count(entries, count + 1); } @@ -4003,13 +4069,13 @@ Index: iam/fs/ext3/namei.c + u32 hash, u32 block) +{ + assert(dx_index_is_compat(path)); -+ iam_insert_key(path, frame, (struct iam_key *)&hash, block); ++ iam_insert_key(path, frame, (struct iam_ikey *)&hash, block); +} + #endif -@@ -1897,14 +885,15 @@ static struct buffer_head * ext3_dx_find +@@ -1897,14 +886,15 @@ static struct buffer_head * ext3_dx_find if (*err != 0) return NULL; } else { @@ -4028,7 +4094,7 @@ Index: iam/fs/ext3/namei.c if (*err != 0) goto errout; de = (struct ext3_dir_entry_2 *) bh->b_data; -@@ -2061,22 +1050,69 @@ static struct ext3_dir_entry_2* dx_pack_ +@@ -2061,22 +1051,69 @@ static struct ext3_dir_entry_2* dx_pack_ return prev; } @@ -4105,7 +4171,7 @@ Index: iam/fs/ext3/namei.c int err; bh2 = ext3_append (handle, dir, &newblock, error); -@@ -2101,35 +1137,9 @@ static struct ext3_dir_entry_2 *do_split +@@ -2101,35 +1138,9 @@ static struct ext3_dir_entry_2 *do_split if (err) goto journal_error; @@ -4143,7 +4209,7 @@ Index: iam/fs/ext3/namei.c err = ext3_journal_dirty_metadata (handle, bh2); if (err) goto journal_error; -@@ -2143,6 +1153,67 @@ errout: +@@ -2143,6 +1154,67 @@ errout: } #endif @@ -4211,7 +4277,7 @@ Index: iam/fs/ext3/namei.c /* * Add a new entry into a directory (leaf) block. If de is non-NULL, -@@ -2162,34 +1233,16 @@ static int add_dirent_to_buf(handle_t *h +@@ -2162,34 +1234,16 @@ static int add_dirent_to_buf(handle_t *h struct inode *dir = dentry->d_parent->d_inode; const char *name = dentry->d_name.name; int namelen = dentry->d_name.len; @@ -4253,7 +4319,7 @@ Index: iam/fs/ext3/namei.c } BUFFER_TRACE(bh, "get_write_access"); err = ext3_journal_get_write_access(handle, bh); -@@ -2200,22 +1253,9 @@ static int add_dirent_to_buf(handle_t *h +@@ -2200,22 +1254,9 @@ static int add_dirent_to_buf(handle_t *h } /* By now the buffer is marked for journaling */ @@ -4279,7 +4345,7 @@ Index: iam/fs/ext3/namei.c /* * XXX shouldn't update any times until successful * completion of syscall, but too many callers depend -@@ -2392,18 +1432,25 @@ static int ext3_add_entry (handle_t *han +@@ -2392,18 +1433,25 @@ static int ext3_add_entry (handle_t *han } #ifdef CONFIG_EXT3_INDEX @@ -4308,7 +4374,7 @@ Index: iam/fs/ext3/namei.c frame = path->ip_frame; entries = frame->entries; -@@ -2442,7 +1489,8 @@ static int split_index_node(handle_t *ha +@@ -2442,7 +1490,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] || @@ -4318,7 +4384,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); -@@ -2461,6 +1509,7 @@ static int split_index_node(handle_t *ha +@@ -2461,6 +1510,7 @@ static int split_index_node(handle_t *ha unsigned count; int idx; struct buffer_head *bh2; @@ -4326,7 +4392,7 @@ Index: iam/fs/ext3/namei.c entries = frame->entries; count = dx_get_count(entries); -@@ -2469,6 +1518,7 @@ static int split_index_node(handle_t *ha +@@ -2469,6 +1519,7 @@ static int split_index_node(handle_t *ha bh2 = bh_new[i]; entries2 = dx_get_entries(path, bh2->b_data, 0); @@ -4334,7 +4400,7 @@ Index: iam/fs/ext3/namei.c if (frame == path->ip_frames) { /* splitting root node. Tricky point: * -@@ -2480,22 +1530,20 @@ static int split_index_node(handle_t *ha +@@ -2480,22 +1531,20 @@ static int split_index_node(handle_t *ha * capacity of the root node is smaller than that of * non-root one. */ @@ -4363,7 +4429,7 @@ Index: iam/fs/ext3/namei.c /* Shift frames in the path */ memmove(frames + 2, frames + 1, -@@ -2505,20 +1553,21 @@ static int split_index_node(handle_t *ha +@@ -2505,20 +1554,21 @@ static int split_index_node(handle_t *ha frames[1].entries = entries = entries2; frames[1].bh = bh2; assert(dx_node_check(path, frame)); @@ -4379,19 +4445,19 @@ Index: iam/fs/ext3/namei.c /* splitting non-root index node. */ unsigned count1 = count/2, count2 = count - count1; - unsigned hash2; -+ struct iam_key *pivot = iam_path_key(path, 3); ++ struct iam_ikey *pivot = iam_path_ikey(path, 3); + struct iam_frame *parent = frame - 1; - dx_get_key(path, - iam_entry_shift(path, entries, count1), - (struct iam_key *)&hash2); -+ iam_get_key(path, -+ iam_entry_shift(path, entries, count1), -+ pivot); ++ iam_get_ikey(path, ++ iam_entry_shift(path, entries, count1), ++ pivot); dxtrace(printk("Split index %i/%i\n", count1, count2)); -@@ -2537,16 +1586,30 @@ static int split_index_node(handle_t *ha +@@ -2537,16 +1587,30 @@ static int split_index_node(handle_t *ha swap(frame->bh, bh2); bh_new[i] = bh2; } @@ -4424,7 +4490,7 @@ Index: iam/fs/ext3/namei.c } goto cleanup; journal_error: -@@ -2578,7 +1641,7 @@ static int ext3_dx_add_entry(handle_t *h +@@ -2578,7 +1642,7 @@ static int ext3_dx_add_entry(handle_t *h size_t isize; iam_path_compat_init(&cpath, dir); @@ -4433,7 +4499,7 @@ Index: iam/fs/ext3/namei.c err = dx_probe(dentry, NULL, &hinfo, path); if (err != 0) -@@ -2588,8 +1651,9 @@ static int ext3_dx_add_entry(handle_t *h +@@ -2588,8 +1652,9 @@ static int ext3_dx_add_entry(handle_t *h /* XXX nikita: global serialization! */ isize = dir->i_size; @@ -4445,7 +4511,7 @@ Index: iam/fs/ext3/namei.c if (err != 0) goto cleanup; -@@ -2609,7 +1673,7 @@ static int ext3_dx_add_entry(handle_t *h +@@ -2609,7 +1674,7 @@ static int ext3_dx_add_entry(handle_t *h goto cleanup; /*copy split inode too*/ @@ -4454,7 +4520,7 @@ Index: iam/fs/ext3/namei.c if (!de) goto cleanup; -@@ -2724,12 +1788,12 @@ static struct inode * ext3_new_inode_wan +@@ -2724,12 +1789,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 @@ -4472,7 +4538,7 @@ Index: iam/fs/ext3/namei.c Index: iam/include/linux/lustre_iam.h =================================================================== --- iam.orig/include/linux/lustre_iam.h 2006-05-31 20:24:32.000000000 +0400 -+++ iam/include/linux/lustre_iam.h 2006-06-23 01:50:19.000000000 +0400 ++++ iam/include/linux/lustre_iam.h 2006-06-28 01:37:26.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 f97e59f..553a2fe 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-06-23 01:50:19.000000000 +0400 -+++ iam/fs/ext3/Makefile 2006-06-23 01:50:19.000000000 +0400 +--- iam.orig/fs/ext3/Makefile 2006-06-28 01:37:26.000000000 +0400 ++++ iam/fs/ext3/Makefile 2006-06-28 01:37:26.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 \ @@ -11,10 +11,109 @@ Index: iam/fs/ext3/Makefile ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o +Index: iam/fs/ext3/dir.c +=================================================================== +--- iam.orig/fs/ext3/dir.c 2006-06-28 01:37:26.000000000 +0400 ++++ iam/fs/ext3/dir.c 2006-06-28 01:37:26.000000000 +0400 +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + static unsigned char ext3_filetype_table[] = { + DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK +@@ -59,7 +60,7 @@ static unsigned char get_dtype(struct su + + return (ext3_filetype_table[filetype]); + } +- ++ + + int ext3_check_dir_entry (const char * function, struct inode * dir, + struct ext3_dir_entry_2 * de, +@@ -165,7 +166,7 @@ revalidate: + * to make sure. */ + if (filp->f_version != inode->i_version) { + for (i = 0; i < sb->s_blocksize && i < offset; ) { +- de = (struct ext3_dir_entry_2 *) ++ de = (struct ext3_dir_entry_2 *) + (bh->b_data + i); + /* It's too expensive to do a full + * dirent test each time round this +@@ -184,7 +185,7 @@ revalidate: + filp->f_version = inode->i_version; + } + +- while (!error && filp->f_pos < inode->i_size ++ while (!error && filp->f_pos < inode->i_size + && offset < sb->s_blocksize) { + de = (struct ext3_dir_entry_2 *) (bh->b_data + offset); + if (!ext3_check_dir_entry ("ext3_readdir", inode, de, +@@ -232,7 +233,7 @@ out: + /* + * These functions convert from the major/minor hash to an f_pos + * value. +- * ++ * + * Currently we only use major hash numer. This is unfortunate, but + * on 32-bit machines, the same VFS interface is used for lseek and + * llseek, so if we use the 64 bit offset, then the 32-bit versions of +@@ -253,7 +254,7 @@ out: + struct fname { + __u32 hash; + __u32 minor_hash; +- struct rb_node rb_hash; ++ struct rb_node rb_hash; + struct fname *next; + __u32 inode; + __u8 name_len; +@@ -305,12 +306,14 @@ static void free_rb_tree_fname(struct rb + root->rb_node = NULL; + } + ++extern struct iam_private_info *ext3_iam_alloc_info(int flags); ++extern void ext3_iam_release_info(struct iam_private_info *info); + + struct dir_private_info *create_dir_info(loff_t pos) + { + struct dir_private_info *p; + +- p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL); ++ p = ext3_iam_alloc_info(GFP_KERNEL); + if (!p) + return NULL; + p->root.rb_node = NULL; +@@ -326,6 +329,7 @@ struct dir_private_info *create_dir_info + void ext3_htree_free_dir_info(struct dir_private_info *p) + { + free_rb_tree_fname(&p->root); ++ ext3_iam_release_info((void *)p); + kfree(p); + } + +@@ -413,7 +417,7 @@ static int call_filldir(struct file * fi + curr_pos = hash2pos(fname->hash, fname->minor_hash); + while (fname) { + error = filldir(dirent, fname->name, +- fname->name_len, curr_pos, ++ fname->name_len, curr_pos, + fname->inode, + get_dtype(sb, fname->file_type)); + if (error) { +@@ -468,7 +472,7 @@ static int ext3_dx_readdir(struct file * + /* + * Fill the rbtree if we have no more entries, + * or the inode has changed since we last read in the +- * cached entries. ++ * cached entries. + */ + if ((!info->curr_node) || + (filp->f_version != inode->i_version)) { Index: iam/fs/ext3/file.c =================================================================== ---- iam.orig/fs/ext3/file.c 2006-06-23 01:50:19.000000000 +0400 -+++ iam/fs/ext3/file.c 2006-06-23 01:50:19.000000000 +0400 +--- iam.orig/fs/ext3/file.c 2006-06-28 01:37:26.000000000 +0400 ++++ iam/fs/ext3/file.c 2006-06-28 01:37:26.000000000 +0400 @@ -23,6 +23,7 @@ #include #include @@ -50,8 +149,8 @@ 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-06-23 01:50:19.000000000 +0400 -@@ -0,0 +1,348 @@ ++++ iam/fs/ext3/iam-uapi.c 2006-06-28 01:37:26.000000000 +0400 +@@ -0,0 +1,357 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -92,6 +191,7 @@ Index: iam/fs/ext3/iam-uapi.c +#include + +struct iam_private_info { ++ struct dir_private_info ipi_dir; /* has to be first */ + struct iam_container ipi_bag; + struct iam_descr ipi_descr; + struct iam_iterator ipi_it; @@ -139,8 +239,8 @@ Index: iam/fs/ext3/iam-uapi.c + } + st = it->ii_state; + if (st == IAM_IT_ATTACHED || st == IAM_IT_SKEWED) -+ iam_keycpy0(&ipi->ipi_bag, itop->iui_op.iul_key, -+ iam_it_key_get(it, itop->iui_op.iul_key)); ++ memcpy(itop->iui_op.iul_key, iam_it_key_get(it), ++ ipi->ipi_bag.ic_descr->id_key_size); + if (st == IAM_IT_ATTACHED) + iam_reccpy(&it->ii_path, + itop->iui_op.iul_rec, iam_it_rec_get(it)); @@ -178,7 +278,7 @@ Index: iam/fs/ext3/iam-uapi.c + return result; +} + -+static struct iam_private_info *ext3_iam_alloc_info(int flags) ++struct iam_private_info *ext3_iam_alloc_info(int flags) +{ + struct iam_private_info *info; + @@ -188,16 +288,22 @@ Index: iam/fs/ext3/iam-uapi.c + return info; +} + ++void ext3_iam_release_info(struct iam_private_info *info) ++{ ++ iam_it_put(&info->ipi_it); ++ iam_it_fini(&info->ipi_it); ++ if (info->ipi_ipd != NULL) ++ info->ipi_bag.ic_descr->id_ops->id_ipd_free(&info->ipi_bag, ++ info->ipi_ipd); ++ iam_container_fini(&info->ipi_bag); ++} ++ +void ext3_iam_release(struct file *filp, struct inode *inode) +{ + struct iam_private_info *info; + + info = filp->private_data; -+ iam_it_put(&info->ipi_it); -+ iam_it_fini(&info->ipi_it); -+ iam_container_fini(&info->ipi_bag); -+ if (info->ipi_ipd != NULL) -+ iam_ipd_free(info->ipi_ipd); ++ ext3_iam_release_info(info); + + kfree(info); + EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL; @@ -220,7 +326,11 @@ Index: iam/fs/ext3/iam-uapi.c + if (result == 0) { + result = iam_container_setup(bag); + if (result == 0) { -+ info->ipi_ipd = iam_ipd_alloc(des->id_key_size); ++ /* ++ * Container setup might change ->ic_descr ++ */ ++ des = bag->ic_descr; ++ info->ipi_ipd = des->id_ops->id_ipd_alloc(bag); + if (info->ipi_ipd != NULL) { + filp->private_data = info; + EXT3_I(inode)->i_flags |= EXT3_INDEX_FL; @@ -337,8 +447,6 @@ Index: iam/fs/ext3/iam-uapi.c + + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) + result = -EACCES; -+ else if (!S_ISREG(inode->i_mode)) -+ result = -EBADF; + else if (cmd == IAM_IOC_INIT) { + if (filp->private_data == NULL) { + result = getua(&ua, arg); @@ -362,7 +470,7 @@ Index: iam/fs/ext3/iam-uapi.c + break; + } + -+ des = &get_ipi(filp)->ipi_descr; ++ des = get_ipi(filp)->ipi_bag.ic_descr; + if (cmd == IAM_IOC_GETINFO) { + ua.iui_keysize = des->id_key_size; + ua.iui_recsize = des->id_rec_size; @@ -402,8 +510,8 @@ Index: iam/fs/ext3/iam-uapi.c +} Index: iam/fs/ext3/ioctl.c =================================================================== ---- iam.orig/fs/ext3/ioctl.c 2006-06-23 01:50:19.000000000 +0400 -+++ iam/fs/ext3/ioctl.c 2006-06-23 01:50:19.000000000 +0400 +--- iam.orig/fs/ext3/ioctl.c 2006-06-28 01:37:26.000000000 +0400 ++++ iam/fs/ext3/ioctl.c 2006-06-28 01:37:26.000000000 +0400 @@ -250,6 +250,6 @@ flags_err: @@ -414,8 +522,8 @@ Index: iam/fs/ext3/ioctl.c } Index: iam/include/linux/lustre_iam.h =================================================================== ---- iam.orig/include/linux/lustre_iam.h 2006-06-23 01:50:19.000000000 +0400 -+++ iam/include/linux/lustre_iam.h 2006-06-23 01:50:19.000000000 +0400 +--- iam.orig/include/linux/lustre_iam.h 2006-06-28 01:37:26.000000000 +0400 ++++ iam/include/linux/lustre_iam.h 2006-06-28 01:37:26.000000000 +0400 @@ -30,9 +30,6 @@ #ifndef __LINUX_LUSTRE_IAM_H__ #define __LINUX_LUSTRE_IAM_H__ @@ -426,7 +534,18 @@ Index: iam/include/linux/lustre_iam.h /* * linux/include/linux/lustre_iam.h */ -@@ -65,6 +62,10 @@ enum { +@@ -57,14 +54,20 @@ enum { + * [2] reserved for leaf node operations. + * + * [3] reserved for index operations. ++ * ++ * [4] reserved for path->ip_ikey_target + */ +- DX_SCRATCH_KEYS = 4, ++ DX_SCRATCH_KEYS = 5, + /* + * Maximal format name length. + */ DX_FMT_NAME_LEN = 16 }; @@ -437,15 +556,25 @@ Index: iam/include/linux/lustre_iam.h /* * Entry within index tree node. Consists of a key immediately followed * (without padding) by a pointer to the child node. -@@ -89,11 +90,11 @@ struct iam_key; - /* Incomplete type use to refer to the records stored in iam containers. */ +@@ -86,14 +89,21 @@ struct iam_entry_compat { + */ + struct iam_key; + +-/* Incomplete type use to refer to the records stored in iam containers. */ ++/* ++ * Incomplete type use to refer to the records stored in iam containers. ++ */ struct iam_rec; -struct iam_cookie { - struct iam_key *ic_key; - struct iam_rec *ic_rec; -}; -- ++/* ++ * Key in index node. Possibly compressed. Fixed size. ++ */ ++struct iam_ikey; + +/* + * Scalar type into which certain iam_key's can be uniquely mapped. Used to + * support interfaces like readdir(), where iteration over index has to be @@ -454,7 +583,7 @@ Index: iam/include/linux/lustre_iam.h typedef __u64 iam_ptr_t; /* -@@ -123,6 +124,27 @@ struct iam_leaf { +@@ -123,6 +133,27 @@ struct iam_leaf { void *il_descr_data; }; @@ -482,7 +611,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 +153,15 @@ struct iam_operations { +@@ -131,11 +162,15 @@ struct iam_operations { __u32 (*id_root_ptr)(struct iam_container *c); /* @@ -500,9 +629,18 @@ Index: iam/include/linux/lustre_iam.h * Initialize new node (stored in @bh) that is going to be added into * tree. */ -@@ -149,18 +175,27 @@ struct iam_operations { - int (*id_keycmp)(const struct iam_container *c, - const struct iam_key *k1, const struct iam_key *k2); +@@ -144,23 +179,33 @@ struct iam_operations { + int (*id_node_read)(struct iam_container *c, iam_ptr_t ptr, + handle_t *h, struct buffer_head **bh); + /* +- * Key comparison function. Returns -1, 0, +1. ++ * Key comparison functions. Returns -1, 0, +1. + */ +- int (*id_keycmp)(const struct iam_container *c, +- const struct iam_key *k1, const struct iam_key *k2); ++ int (*id_ikeycmp)(const struct iam_container *c, ++ const struct iam_ikey *k1, ++ const struct iam_ikey *k2); /* - * Create new container. - * @@ -533,7 +671,39 @@ Index: iam/include/linux/lustre_iam.h struct iam_leaf_operations { /* * leaf operations. -@@ -226,7 +261,8 @@ struct iam_leaf_operations { +@@ -186,7 +231,8 @@ struct iam_leaf_operations { + void (*start)(struct iam_leaf *l); + /* more leaf to the next entry. */ + void (*next)(struct iam_leaf *l); +- /* return key of current leaf record. This method may return ++ /* ++ * return key of current leaf record. This method may return + * 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 +240,10 @@ struct iam_leaf_operations { + * all). + * + * Caller should assume that returned pointer is only valid +- * while leaf node is pinned and locked.*/ +- struct iam_key *(*key)(const struct iam_leaf *l, struct iam_key *k); ++ * while leaf node is pinned and locked. ++ */ ++ struct iam_ikey *(*ikey)(const struct iam_leaf *l, struct iam_ikey *k); ++ struct iam_key *(*key)(const struct iam_leaf *l); + /* 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 +251,8 @@ 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); + ++ int (*key_cmp)(const struct iam_leaf *l, const struct iam_key *k); ++ + /* + * Search leaf @l for a record with key @k or for a place + * where such record is to be inserted. +@@ -226,7 +276,8 @@ struct iam_leaf_operations { * split leaf node, moving some entries into @bh (the latter currently * is assumed to be empty). */ @@ -543,7 +713,18 @@ Index: iam/include/linux/lustre_iam.h }; struct iam_path *iam_leaf_path(const struct iam_leaf *leaf); -@@ -264,6 +300,9 @@ struct iam_descr { +@@ -241,6 +292,10 @@ struct iam_descr { + */ + size_t id_key_size; + /* ++ * Size of a key in index nodes, in bytes. ++ */ ++ size_t id_ikey_size; ++ /* + * Size of a pointer to the next level (stored in index nodes), in + * bytes. + */ +@@ -264,6 +319,9 @@ struct iam_descr { struct iam_leaf_operations *id_leaf_ops; }; @@ -553,7 +734,32 @@ Index: iam/include/linux/lustre_iam.h struct iam_container { /* * Underlying flat file. IO against this object is issued to -@@ -347,7 +386,9 @@ enum iam_it_state { +@@ -284,7 +342,7 @@ struct iam_path_descr { + /* + * Scratch-pad area for temporary keys. + */ +- struct iam_key *ipd_key_scratch[DX_SCRATCH_KEYS]; ++ struct iam_ikey *ipd_key_scratch[DX_SCRATCH_KEYS]; + }; + + /* +@@ -316,6 +374,7 @@ struct iam_path { + * Key searched for. + */ + const struct iam_key *ip_key_target; ++ struct iam_ikey *ip_ikey_target; + /* + * Description-specific data. + */ +@@ -334,6 +393,7 @@ struct iam_path_compat { + struct dx_hash_info *ipc_hinfo; + struct dentry *ipc_dentry; + struct iam_path_descr ipc_descr; ++ struct dx_hash_info ipc_hinfo_area; + }; + + /* +@@ -347,7 +407,9 @@ enum iam_it_state { /* initial state */ IAM_IT_DETACHED, /* iterator is above particular record in the container */ @@ -564,7 +770,7 @@ Index: iam/include/linux/lustre_iam.h }; /* -@@ -355,7 +396,7 @@ enum iam_it_state { +@@ -355,7 +417,7 @@ enum iam_it_state { */ enum iam_it_flags { /* @@ -573,7 +779,7 @@ Index: iam/include/linux/lustre_iam.h */ IAM_IT_MOVE = (1 << 0), /* -@@ -372,15 +413,26 @@ enum iam_it_flags { +@@ -372,15 +434,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 @@ -603,7 +809,7 @@ Index: iam/include/linux/lustre_iam.h * */ struct iam_iterator { -@@ -390,7 +442,8 @@ struct iam_iterator { +@@ -390,7 +463,8 @@ struct iam_iterator { __u32 ii_flags; enum iam_it_state ii_state; /* @@ -613,175 +819,182 @@ Index: iam/include/linux/lustre_iam.h */ struct iam_path ii_path; }; -@@ -420,27 +473,37 @@ int iam_it_init(struct iam_iterator *it - void iam_it_fini(struct iam_iterator *it); +@@ -405,133 +479,24 @@ 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); - /* +-/* +- * Initialize iterator to IAM_IT_DETACHED state. +- * +- * postcondition: it_state(it) == IAM_IT_DETACHED +- */ + int iam_it_init(struct iam_iterator *it, struct iam_container *c, __u32 flags, + struct iam_path_descr *pd); +-/* +- * Finalize iterator and release all resources. +- * +- * precondition: it_state(it) == IAM_IT_DETACHED +- */ + void iam_it_fini(struct iam_iterator *it); +- +-/* - * Attach iterator. After successful completion, @it points to record with the - * largest key not larger than @k. Semantics of ->id_create() method guarantee - * that such record will always be found. -+ * Attach iterator. After successful completion, @it points to record with -+ * smallest key not larger than @k. - * - * Return value: 0: positioned on existing record, - * -ve: error. - * - * precondition: it_state(it) == IAM_IT_DETACHED +- * +- * Return value: 0: positioned on existing record, +- * -ve: error. +- * +- * precondition: it_state(it) == IAM_IT_DETACHED - * postcondition: ergo(result == 0, - * (it_state(it) == IAM_IT_ATTACHED && - * it_keycmp(it, iam_it_key_get(it, *), k) < 0)) -+ * postcondition: ergo(result == 0 && it_state(it) == IAM_IT_ATTACHED, -+ * it_keycmp(it, iam_it_key_get(it, *), k) <= 0) - */ +- */ int iam_it_get(struct iam_iterator *it, const struct iam_key *k); - - /* -+ * Attach iterator, and assure it points to the record (not skewed). -+ * -+ * Return value: 0: positioned on existing record, -+ * -ve: error. -+ * -+ * precondition: it_state(it) == IAM_IT_DETACHED && -+ * !(it->ii_flags&IAM_IT_WRITE) -+ * postcondition: ergo(result == 0, it_state(it) == IAM_IT_ATTACHED) -+ */ -+int iam_it_get_at(struct iam_iterator *it, const struct iam_key *k); -+ -+/* - * Duplicates iterator. - * - * postcondition: it_state(dst) == it_state(src) && - * iam_it_container(dst) == iam_it_container(src) && - * dst->ii_flags = src->ii_flags && +- +-/* +- * Duplicates iterator. +- * +- * postcondition: it_state(dst) == it_state(src) && +- * iam_it_container(dst) == iam_it_container(src) && +- * dst->ii_flags = src->ii_flags && - * ergo(it_state(it) == IAM_IT_ATTACHED, -+ * ergo(it_state(src) == IAM_IT_ATTACHED, - * iam_it_rec_get(dst) == iam_it_rec_get(src) && - * iam_it_key_get(dst, *1) == iam_it_key_get(src, *2)) - */ -@@ -460,15 +523,17 @@ void iam_it_put(struct iam_iterator *it) - * +1: end of container reached - * -ve: error - * +- * iam_it_rec_get(dst) == iam_it_rec_get(src) && +- * iam_it_key_get(dst, *1) == iam_it_key_get(src, *2)) +- */ ++int iam_it_get_at(struct iam_iterator *it, const struct iam_key *k); + void iam_it_dup(struct iam_iterator *dst, const struct iam_iterator *src); +- +-/* +- * Detach iterator. Does nothing it detached state. +- * +- * postcondition: it_state(it) == IAM_IT_DETACHED +- */ + void iam_it_put(struct iam_iterator *it); +- +-/* +- * Move iterator one record right. +- * +- * Return value: 0: success, +- * +1: end of container reached +- * -ve: error +- * - * precondition: it_state(it) == IAM_IT_ATTACHED && it->ii_flags&IAM_IT_MOVE - * postcondition: ergo(result >= 0, it_state(it) == IAM_IT_ATTACHED) -+ * precondition: (it_state(it) == IAM_IT_ATTACHED || -+ * it_state(it) == IAM_IT_SKEWED) && it->ii_flags&IAM_IT_MOVE -+ * postcondition: ergo(result == 0, it_state(it) == IAM_IT_ATTACHED) && -+ * ergo(result > 0, it_state(it) == IAM_IT_DETACHED) - */ +- */ int iam_it_next(struct iam_iterator *it); - - /* - * Return pointer to the record under iterator. - * +- +-/* +- * Return pointer to the record under iterator. +- * - * precondition: it_state(it) == IAM_IT_ATTACHED -+ * precondition: it_state(it) == IAM_IT_ATTACHED && it_at_rec(it) - * postcondition: it_state(it) == IAM_IT_ATTACHED - */ +- * postcondition: it_state(it) == IAM_IT_ATTACHED +- */ struct iam_rec *iam_it_rec_get(const struct iam_iterator *it); -@@ -476,14 +541,15 @@ struct iam_rec *iam_it_rec_get(const str - /* - * Replace contents of record under iterator. - * +- +-/* +- * Replace contents of record under iterator. +- * - * precondition: it_state(it) == IAM_IT_ATTACHED && it->ii_flags&IAM_IT_WRITE -+ * precondition: it_state(it) == IAM_IT_ATTACHED && -+ * it->ii_flags&IAM_IT_WRITE - * postcondition: it_state(it) == IAM_IT_ATTACHED && - * ergo(result == 0, !memcmp(iam_it_rec_get(it), r, ...)) - */ +- * postcondition: it_state(it) == IAM_IT_ATTACHED && +- * ergo(result == 0, !memcmp(iam_it_rec_get(it), r, ...)) +- */ int iam_it_rec_set(handle_t *h, struct iam_iterator *it, struct iam_rec *r); - - /* +- +-/* - * Place key under iterator in @k, return @k -+ * Return pointer to the key under iterator. - * - * precondition: it_state(it) == IAM_IT_ATTACHED - * postcondition: it_state(it) == IAM_IT_ATTACHED -@@ -495,11 +561,17 @@ struct iam_key *iam_it_key_get(const str - * Insert new record with key @k and contents from @r, shifting records to the - * right. - * +- * +- * precondition: it_state(it) == IAM_IT_ATTACHED +- * postcondition: it_state(it) == IAM_IT_ATTACHED +- */ +-struct iam_key *iam_it_key_get(const struct iam_iterator *it, +- struct iam_key *k); +- +-/* +- * Insert new record with key @k and contents from @r, shifting records to the +- * right. +- * - * precondition: it_state(it) == IAM_IT_ATTACHED && - * it->ii_flags&IAM_IT_WRITE && - * it_keycmp(it, iam_it_key_get(it, *), k) < 0 - * postcondition: it_state(it) == IAM_IT_ATTACHED && - * ergo(result == 0, -+ * precondition: it->ii_flags&IAM_IT_WRITE && -+ * (it_state(it) == IAM_IT_ATTACHED || -+ * it_state(it) == IAM_IT_SKEWED) && -+ * ergo(it_state(it) == IAM_IT_ATTACHED, -+ * it_keycmp(it, iam_it_key_get(it, it_scratch_key(it, 0)), -+ * k) < 0) && -+ * ergo(it_before(it), -+ * it_keycmp(it, iam_it_key_get(it, it_scratch_key(it, 0)), -+ * k) > 0)); -+ * postcondition: ergo(result == 0, -+ * it_state(it) == IAM_IT_ATTACHED && - * it_keycmp(it, iam_it_key_get(it, *), k) == 0 && - * !memcmp(iam_it_rec_get(it), r, ...)) - */ -@@ -508,8 +580,10 @@ int iam_it_rec_insert(handle_t *h, struc - /* - * Delete record under iterator. - * +- * it_keycmp(it, iam_it_key_get(it, *), k) == 0 && +- * !memcmp(iam_it_rec_get(it), r, ...)) +- */ ++struct iam_key *iam_it_key_get(const struct iam_iterator *it); + int iam_it_rec_insert(handle_t *h, struct iam_iterator *it, + const struct iam_key *k, const struct iam_rec *r); +-/* +- * Delete record under iterator. +- * - * precondition: it_state(it) == IAM_IT_ATTACHED && it->ii_flags&IAM_IT_WRITE - * postcondition: it_state(it) == IAM_IT_ATTACHED -+ * precondition: it_state(it) == IAM_IT_ATTACHED && -+ * it->ii_flags&IAM_IT_WRITE && -+ * it_at_rec(it) -+ * postcondition: it_state(it) == IAM_IT_ATTACHED || it_state(it) == IAM_IT_EOC - */ +- */ int iam_it_rec_delete(handle_t *h, struct iam_iterator *it); -@@ -519,7 +593,7 @@ typedef __u64 iam_pos_t; - * Convert iterator to cookie. - * - * precondition: it_state(it) == IAM_IT_ATTACHED && + typedef __u64 iam_pos_t; + +-/* +- * Convert iterator to cookie. +- * +- * precondition: it_state(it) == IAM_IT_ATTACHED && - * path_descr(it->ii_path)->id_key_size <= sizeof(iam_pos_t) -+ * iam_path_descr(it->ii_path)->id_key_size <= sizeof(iam_pos_t) - * postcondition: it_state(it) == IAM_IT_ATTACHED - */ +- * postcondition: it_state(it) == IAM_IT_ATTACHED +- */ iam_pos_t iam_it_store(const struct iam_iterator *it); -@@ -527,8 +601,9 @@ iam_pos_t iam_it_store(const struct iam_ - /* - * Restore iterator from cookie. - * +- +-/* +- * Restore iterator from cookie. +- * - * precondition: it_state(it) == IAM_IT_DETACHED && it->ii_flags&IAM_IT_MOVE && - * path_descr(it->ii_path)->id_key_size <= sizeof(iam_pos_t) -+ * precondition: it_state(it) == IAM_IT_DETACHED && -+ * it->ii_flags&IAM_IT_MOVE && -+ * iam_path_descr(it->ii_path)->id_key_size <= sizeof(iam_pos_t) - * postcondition: ergo(result == 0, it_state(it) == IAM_IT_ATTACHED && - * iam_it_store(it) == pos) - */ -@@ -583,6 +658,54 @@ static inline void iam_keycpy(const stru - memcpy(k1, k2, c->ic_descr->id_key_size); +- * postcondition: ergo(result == 0, it_state(it) == IAM_IT_ATTACHED && +- * iam_it_store(it) == pos) +- */ + int iam_it_load(struct iam_iterator *it, iam_pos_t pos); + + int iam_lookup(struct iam_container *c, const struct iam_key *k, +@@ -577,16 +542,65 @@ static inline struct inode *iam_path_obj + return p->ip_container->ic_object; } -+static inline size_t iam_entry_size(struct iam_path *p) +-static inline void iam_keycpy(const struct iam_container *c, +- struct iam_key *k1, const struct iam_key *k2) ++static inline void iam_ikeycpy(const struct iam_container *c, ++ struct iam_ikey *k1, const struct iam_ikey *k2) +{ -+ return iam_path_descr(p)->id_key_size + iam_path_descr(p)->id_ptr_size; ++ memcpy(k1, k2, c->ic_descr->id_ikey_size); +} + ++static inline size_t iam_entry_size(struct iam_path *p) + { +- memcpy(k1, k2, c->ic_descr->id_key_size); ++ return iam_path_descr(p)->id_ikey_size + iam_path_descr(p)->id_ptr_size; + } + +-static inline int iam_keycmp(const struct iam_container *c, +- const struct iam_key *k1, const struct iam_key *k2) +static inline struct iam_entry *iam_entry_shift(struct iam_path *p, + struct iam_entry *entry, + int shift) -+{ + { +- return c->ic_descr->id_ops->id_keycmp(c, k1, k2); + void *e = entry; + return e + shift * iam_entry_size(p); +} + -+static inline struct iam_key *iam_get_key(struct iam_path *p, -+ struct iam_entry *entry, -+ struct iam_key *key) ++static inline struct iam_ikey *iam_get_ikey(struct iam_path *p, ++ struct iam_entry *entry, ++ struct iam_ikey *key) +{ -+ return memcpy(key, entry, iam_path_descr(p)->id_key_size); ++ return memcpy(key, entry, iam_path_descr(p)->id_ikey_size); +} + -+static inline struct iam_key *iam_key_at(struct iam_path *p, -+ struct iam_entry *entry) ++static inline struct iam_ikey *iam_ikey_at(struct iam_path *p, ++ struct iam_entry *entry) +{ -+ return (struct iam_key *)entry; ++ return (struct iam_ikey *)entry; +} + +static inline ptrdiff_t iam_entry_diff(struct iam_path *p, @@ -799,18 +1012,46 @@ Index: iam/include/linux/lustre_iam.h + * Helper for the frequent case, where key was already placed into @k1 by + * callback. + */ -+static inline void iam_keycpy0(const struct iam_container *c, -+ struct iam_key *k1, const struct iam_key *k2) ++static inline void iam_ikeycpy0(const struct iam_container *c, ++ struct iam_ikey *k1, const struct iam_ikey *k2) +{ + if (k1 != k2) -+ iam_keycpy(c, 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_ikeycmp(c, k1, k2); + } + + static inline void iam_reccpy(const struct iam_path *p, struct iam_rec *rec_dst, +@@ -604,7 +618,7 @@ static inline void *iam_entry_off(struct + static inline unsigned dx_get_block(struct iam_path *p, struct iam_entry *entry) { -@@ -622,11 +745,54 @@ static inline void dx_set_key(struct iam - iam_keycpy(p->ip_container, iam_entry_off(entry, 0), key); + return le32_to_cpu(*(u32*)iam_entry_off(entry, +- iam_path_descr(p)->id_key_size)) ++ iam_path_descr(p)->id_ikey_size)) + & 0x00ffffff; + } + +@@ -612,21 +626,64 @@ static inline void dx_set_block(struct i + struct iam_entry *entry, unsigned value) + { + *(u32*)iam_entry_off(entry, +- iam_path_descr(p)->id_key_size) = ++ iam_path_descr(p)->id_ikey_size) = + cpu_to_le32(value); + } + +-static inline void dx_set_key(struct iam_path *p, struct iam_entry *entry, +- const struct iam_key *key) ++static inline void dx_set_ikey(struct iam_path *p, struct iam_entry *entry, ++ const struct iam_ikey *key) + { +- iam_keycpy(p->ip_container, iam_entry_off(entry, 0), key); ++ iam_ikeycpy(p->ip_container, iam_entry_off(entry, 0), key); } +struct dx_map_entry @@ -864,23 +1105,37 @@ 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); -@@ -650,6 +816,15 @@ static inline unsigned dx_node_limit(str - return entry_space / (param->id_key_size + param->id_ptr_size); - } - +@@ -647,9 +704,18 @@ 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; +- return entry_space / (param->id_key_size + param->id_ptr_size); ++ return entry_space / (param->id_ikey_size + param->id_ptr_size); ++} ++ +static inline unsigned dx_root_limit(struct iam_path *p) +{ + struct iam_descr *param = iam_path_descr(p); + unsigned entry_space = iam_path_obj(p)->i_sb->s_blocksize - + param->id_root_gap; -+ return entry_space / (param->id_key_size + param->id_ptr_size); -+} -+ ++ return entry_space / (param->id_ikey_size + param->id_ptr_size); + } + + static inline struct iam_entry *dx_get_entries(struct iam_path *path, void *data, int root) { -@@ -674,6 +849,7 @@ static inline struct iam_key *iam_path_k +@@ -665,7 +731,8 @@ static inline struct iam_entry *dx_node_ + frame->bh->b_data, frame == path->ip_frames); + } + +-static inline struct iam_key *iam_path_key(const struct iam_path *path, int nr) ++static inline struct iam_ikey *iam_path_ikey(const struct iam_path *path, ++ int nr) + { + assert(0 <= nr && nr < ARRAY_SIZE(path->ip_data->ipd_key_scratch)); + return path->ip_data->ipd_key_scratch[nr]; +@@ -674,6 +741,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); @@ -888,7 +1143,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 +857,21 @@ int ext3_htree_next_block(struct inode * +@@ -681,6 +749,21 @@ 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); @@ -910,7 +1165,12 @@ Index: iam/include/linux/lustre_iam.h /* * external -@@ -702,6 +893,8 @@ void iam_insert_key(struct iam_path *pat +@@ -698,10 +781,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, +- const struct iam_key *key, iam_ptr_t ptr); ++ const struct iam_ikey *key, iam_ptr_t ptr); int iam_leaf_at_end(const struct iam_leaf *l); void iam_leaf_next(struct iam_leaf *folio); @@ -919,7 +1179,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,8 +902,26 @@ struct iam_descr *iam_leaf_descr(const s +@@ -709,14 +794,76 @@ struct iam_descr *iam_leaf_descr(const s struct iam_leaf_operations *iam_leaf_ops(const struct iam_leaf *leaf); @@ -946,10 +1206,11 @@ Index: iam/include/linux/lustre_iam.h struct list_head if_linkage; }; -@@ -718,5 +929,48 @@ void iam_format_register(struct iam_form + void iam_format_register(struct iam_format *fmt); void iam_lfix_format_init(void); - ++void iam_htree_format_init(void); ++ +struct iam_private_info; + +void ext3_iam_release(struct file *filp, struct inode *inode); @@ -992,6 +1253,6 @@ Index: iam/include/linux/lustre_iam.h + IAM_IOC_IT_NEXT = _IOW('i', 7, struct iam_uapi_it), + IAM_IOC_IT_STOP = _IOR('i', 8, struct iam_uapi_it) +}; -+ + /* __LINUX_LUSTRE_IAM_H__ */ #endif diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index e5285d1..7f418a9 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -774,7 +774,7 @@ static int mdt_reint_open(struct mdt_thread_info *info) /* Open it now. */ /* TODO: not supported yet result = mdt_md_open(info, child); - */ + */ destroy_child: if (result != 0 && created) diff --git a/lustre/osd/osd_handler.c b/lustre/osd/osd_handler.c index 2b68637..8023249 100644 --- a/lustre/osd/osd_handler.c +++ b/lustre/osd/osd_handler.c @@ -305,12 +305,14 @@ static void osd_object_free(const struct lu_context *ctx, struct lu_object *l) static void osd_object_delete(const struct lu_context *ctx, struct lu_object *l) { struct osd_object *o = osd_obj(l); + struct iam_container *bag; LASSERT(osd_invariant(o)); + bag = &o->oo_container; if (o->oo_ipd != NULL) { - LASSERT(o->oo_descr.id_ops->id_ipd_free != NULL); - o->oo_descr.id_ops->id_ipd_free(&o->oo_container, o->oo_ipd); + LASSERT(bag->ic_descr->id_ops->id_ipd_free != NULL); + bag->ic_descr->id_ops->id_ipd_free(&o->oo_container, o->oo_ipd); } if (o->oo_inode != NULL) { if (o->oo_container.ic_object == o->oo_inode) @@ -827,7 +829,7 @@ static int osd_index_try(const struct lu_context *ctx, struct dt_object *dt, if (osd_index_probe(ctx, obj, feat)) { struct iam_path_descr *ipd; - ipd = obj->oo_descr.id_ops->id_ipd_alloc(bag); + ipd = bag->ic_descr->id_ops->id_ipd_alloc(bag); if (ipd != NULL) { obj->oo_ipd = ipd; dt->do_index_ops = &osd_index_ops; diff --git a/lustre/osd/osd_internal.h b/lustre/osd/osd_internal.h index 4d02119..9a52e5d 100644 --- a/lustre/osd/osd_internal.h +++ b/lustre/osd/osd_internal.h @@ -33,6 +33,10 @@ /* struct rw_semaphore */ #include +/* handle_t, journal_start(), journal_stop() */ +#include +/* struct dx_hash_info */ +#include #include #include diff --git a/lustre/ptlrpc/layout.c b/lustre/ptlrpc/layout.c index 0c9ec7f..a4d2a16 100644 --- a/lustre/ptlrpc/layout.c +++ b/lustre/ptlrpc/layout.c @@ -484,7 +484,7 @@ const struct req_format RQF_MDS_REINT_OPEN = EXPORT_SYMBOL(RQF_MDS_REINT_OPEN); const struct req_format RQF_MDS_REINT_UNLINK = - DEFINE_REQ_FMT0("MDS_REINT_UNLINK", mds_reint_unlink_client, + DEFINE_REQ_FMT0("MDS_REINT_UNLINK", mds_reint_unlink_client, mds_reint_rename_or_unlink_server); EXPORT_SYMBOL(RQF_MDS_REINT_UNLINK); @@ -494,7 +494,7 @@ const struct req_format RQF_MDS_REINT_LINK = EXPORT_SYMBOL(RQF_MDS_REINT_LINK); const struct req_format RQF_MDS_REINT_RENAME = - DEFINE_REQ_FMT0("MDS_REINT_RENAME", mds_reint_rename_client, + DEFINE_REQ_FMT0("MDS_REINT_RENAME", mds_reint_rename_client, mds_reint_rename_or_unlink_server); EXPORT_SYMBOL(RQF_MDS_REINT_RENAME);