From: nikita Date: Mon, 9 Oct 2006 18:32:57 +0000 (+0000) Subject: - iam: assure that hash value is always even, even (heh) for dot and dotdot. X-Git-Tag: v1_8_0_110~486^2~623 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=6737d7a6f1a28e290da7cce604ba3437b399d7dc;p=fs%2Flustre-release.git - iam: assure that hash value is always even, even (heh) for dot and dotdot. - lvar_root(), lvar_leaf(): don't assume that new node is zeroed. --- diff --git a/lustre/kernel_patches/patches/ext3-iam-separate.patch b/lustre/kernel_patches/patches/ext3-iam-separate.patch index b498db3..e35ab18 100644 --- a/lustre/kernel_patches/patches/ext3-iam-separate.patch +++ b/lustre/kernel_patches/patches/ext3-iam-separate.patch @@ -2710,7 +2710,7 @@ Index: iam/fs/ext3/iam_lvar.c =================================================================== --- iam.orig/fs/ext3/iam_lvar.c +++ iam/fs/ext3/iam_lvar.c -@@ -0,0 +1,905 @@ +@@ -0,0 +1,960 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -2888,9 +2888,9 @@ Index: iam/fs/ext3/iam_lvar.c + if (namelen == 0) + return 0; + if (strncmp(name, ".", 1) == 0 && namelen == 1) -+ return 1; -+ if (strncmp(name, "..", 2) == 0 && namelen == 2) + return 2; ++ if (strncmp(name, "..", 2) == 0 && namelen == 2) ++ return 4; + + hinfo.hash_version = EXT3_SB(sb)->s_def_hash_version ; + hinfo.seed = 0; @@ -2963,6 +2963,40 @@ Index: iam/fs/ext3/iam_lvar.c + n_start(folio) <= lentry_lvar(folio->il_at) && + lentry_lvar(folio->il_at) < n_end(folio); +} ++ ++static int n_invariant(const struct iam_leaf *leaf) ++{ ++ struct lvar_leaf_entry *scan; ++ struct lvar_leaf_entry *end; ++ lvar_hash_t hash; ++ lvar_hash_t nexthash; ++ ++ end = n_end(leaf); ++ hash = 0; ++ ++ if (h_used(n_head(leaf)) > blocksize(leaf)) ++ return 0; ++ ++ for (scan = n_start(leaf); scan < end; scan = e_next(leaf, scan)) { ++ nexthash = e_hash(scan); ++ if (nexthash != get_hash(iam_leaf_container(leaf), ++ e_char(scan), e_keysize(scan))) { ++ return 0; ++ BREAKPOINT(); ++ } ++ if (nexthash < hash) { ++ BREAKPOINT(); ++ return 0; ++ } ++ hash = nexthash; ++ } ++ if (scan != end) { ++ BREAKPOINT(); ++ return 0; ++ } ++ return 1; ++} ++ +#endif + +static struct iam_ikey *lvar_ikey(const struct iam_leaf *l, @@ -3050,6 +3084,7 @@ Index: iam/fs/ext3/iam_lvar.c + int found_equal; + lvar_hash_t hash; + ++ assert_inv(n_invariant(leaf)); + end = n_end(leaf); + + name = kchar(k); @@ -3089,6 +3124,7 @@ Index: iam/fs/ext3/iam_lvar.c + result = IAM_LOOKUP_OK; + assert_corr(n_at_rec(leaf)); + } ++ assert_inv(n_invariant(leaf)); + return result; +} + @@ -3098,6 +3134,7 @@ Index: iam/fs/ext3/iam_lvar.c + struct lvar_leaf_entry *end; + lvar_hash_t hash; + ++ assert_inv(n_invariant(leaf)); + end = n_end(leaf); + hash = *(const lvar_hash_t *)ik; + @@ -3111,6 +3148,7 @@ Index: iam/fs/ext3/iam_lvar.c + IAM_LOOKUP_EXACT : IAM_LOOKUP_OK; + } + } ++ assert_inv(n_invariant(leaf)); + return -E2BIG; +} + @@ -3119,6 +3157,7 @@ Index: iam/fs/ext3/iam_lvar.c + 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))); ++ assert_inv(n_invariant(l)); +} + +static int lvar_key_cmp(const struct iam_leaf *l, const struct iam_key *k) @@ -3136,6 +3175,7 @@ Index: iam/fs/ext3/iam_lvar.c +{ + assert_corr(n_at_rec(l)); + iam_reccpy(iam_leaf_path(l), e_rec(n_cur(l)), r); ++ assert_inv(n_invariant(l)); +} + +static int lvar_can_add(const struct iam_leaf *l, @@ -3160,12 +3200,14 @@ Index: iam/fs/ext3/iam_lvar.c + ptrdiff_t diff; + + assert_corr(lvar_can_add(leaf, k, r)); ++ assert_inv(n_invariant(leaf)); + + key = kchar(k); + ksize = strlen(key); + shift = getsize(leaf, ksize); + + if (!lvar_at_end(leaf)) { ++ assert_corr(n_cur(leaf) < n_end(leaf)); + end = n_end(leaf); + if (lvar_key_cmp(leaf, k) <= 0) + lvar_next(leaf); @@ -3188,6 +3230,7 @@ Index: iam/fs/ext3/iam_lvar.c + lvar_key_set(leaf, k); + lvar_rec_set(leaf, r); + assert_corr(n_at_rec(leaf)); ++ assert_inv(n_invariant(leaf)); +} + +static void lvar_rec_del(struct iam_leaf *leaf, int shift) @@ -3197,12 +3240,14 @@ Index: iam/fs/ext3/iam_lvar.c + int nob; + + assert_corr(n_at_rec(leaf)); ++ assert_inv(n_invariant(leaf)); + + end = n_end(leaf); + next = e_next(leaf, n_cur(leaf)); + nob = e_size(leaf, n_cur(leaf)); + memmove(leaf->il_at, next, end - next); + h_used_adj(leaf, n_head(leaf), -nob); ++ assert_inv(n_invariant(leaf)); +} + +static void lvar_init_new(struct iam_container *c, struct buffer_head *bh) @@ -3242,6 +3287,8 @@ Index: iam/fs/ext3/iam_lvar.c + ptrdiff_t tomove; + lvar_hash_t hash; + ++ assert_inv(n_invariant(leaf)); ++ + new_leaf = *bh; + path = iam_leaf_path(leaf); + @@ -3289,6 +3336,8 @@ Index: iam/fs/ext3/iam_lvar.c + assert_corr(result == 0); + leaf->il_at = ((void *)leaf->il_at) + shift; + } ++ assert_corr(n_cur(leaf) < n_end(leaf)); ++ assert_inv(n_invariant(leaf)); +} + +static struct iam_leaf_operations lvar_leaf_ops = { @@ -3518,6 +3567,7 @@ Index: iam/fs/ext3/iam_lvar.c + int blocksize, int keysize, int ptrsize, int recsize) +{ + struct lvar_leaf_header *head; ++ struct lvar_leaf_entry *entry; + + /* form leaf */ + head = buf; @@ -3525,6 +3575,11 @@ Index: iam/fs/ext3/iam_lvar.c + .vlh_magic = cpu_to_le16(IAM_LVAR_LEAF_MAGIC), + .vlh_used = cpu_to_le16(sizeof *head + lvar_esize(0, recsize)) + }; ++ entry = (void *)(head + 1); ++ *entry = (typeof(*entry)) { ++ .vle_hash = 0, ++ .vle_keysize = 0 ++ }; +} + +#include diff --git a/lustre/obdclass/mea.c b/lustre/obdclass/mea.c index d5f5a78..89dc781 100644 --- a/lustre/obdclass/mea.c +++ b/lustre/obdclass/mea.c @@ -27,7 +27,7 @@ #include #include #include -#else +#else #include #include #include @@ -43,7 +43,7 @@ static int mea_last_char_hash(int count, char *name, int namelen) { unsigned int c; - + c = name[namelen - 1]; if (c == 0) CWARN("looks like wrong len is passed\n"); @@ -69,13 +69,13 @@ static int mea_hash_segment(int count, char *name, int namelen) int result; __u64 hash; __u32 hash_segment = MAX_HASH_SIZE; - + if (namelen == 0) return 0; - if (strncmp(name, ".", 1) == 0 && namelen == 1) - return 1; - if (strncmp(name, "..", 2) == 0 && namelen == 2) + if (strncmp(name, ".", 1) == 0 && namelen == 1) return 2; + if (strncmp(name, "..", 2) == 0 && namelen == 2) + return 4; hinfo.hash_version = LDISKFS_DX_HASH_TEA; hinfo.seed = 0; @@ -85,8 +85,8 @@ static int mea_hash_segment(int count, char *name, int namelen) do_div(hash_segment, count); do_div(hash, hash_segment); LASSERT(hash <= count); - - return hash; + + return hash; } #else static int mea_hash_segment(int count, char *name, int namelen) @@ -123,7 +123,7 @@ int raw_name2idx(int hashtype, int count, const char *name, int namelen) int mea_name2idx(struct lmv_stripe_md *mea, char *name, int namelen) { unsigned int c; - + LASSERT(mea && mea->mea_count); c = raw_name2idx(mea->mea_magic, mea->mea_count, name, namelen);