From 0245156c118bb069cb4dc96101864ead3ccbd8b4 Mon Sep 17 00:00:00 2001 From: nikita Date: Wed, 15 Nov 2006 22:06:10 +0000 Subject: [PATCH] iam: add more debugging based on dynlock_is_locked(). --- .../kernel_patches/patches/ext3-iam-separate.patch | 32 ++++++--- .../patches/ext3-pdirops-2.6.9.patch | 84 ++++++++++++++-------- 2 files changed, 78 insertions(+), 38 deletions(-) diff --git a/lustre/kernel_patches/patches/ext3-iam-separate.patch b/lustre/kernel_patches/patches/ext3-iam-separate.patch index 41fb562..f44f95c 100644 --- a/lustre/kernel_patches/patches/ext3-iam-separate.patch +++ b/lustre/kernel_patches/patches/ext3-iam-separate.patch @@ -15,7 +15,7 @@ Index: iam/fs/ext3/iam.c =================================================================== --- iam.orig/fs/ext3/iam.c +++ iam/fs/ext3/iam.c -@@ -0,0 +1,1430 @@ +@@ -0,0 +1,1432 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -371,7 +371,7 @@ Index: iam/fs/ext3/iam.c + +static int iam_leaf_load(struct iam_path *path) +{ -+ int block; ++ iam_ptr_t block; + int err; + struct iam_container *c; + struct buffer_head *bh; @@ -381,11 +381,11 @@ Index: iam/fs/ext3/iam.c + c = path->ip_container; + leaf = &path->ip_leaf; + descr = iam_path_descr(path); -+ block = dx_get_block(path, path->ip_frame->at); ++ block = path->ip_frame->leaf; + if (block == 0) { + /* XXX bug 11027 */ -+ printk(KERN_EMERG "wrong leaf: %p %d [%p %p %p]\n", -+ path->ip_frame->at, ++ printk(KERN_EMERG "wrong leaf: %lu %d [%p %p %p]\n", ++ (long unsigned)path->ip_frame->leaf, + dx_get_count(dx_node_get_entries(path, path->ip_frame)), + path->ip_frames[0].bh, path->ip_frames[1].bh, + path->ip_frames[2].bh); @@ -393,6 +393,7 @@ Index: iam/fs/ext3/iam.c + err = descr->id_ops->id_node_read(c, block, NULL, &bh); + if (err == 0) { + leaf->il_bh = bh; ++ leaf->il_curidx = block; + err = iam_leaf_ops(leaf)->init(leaf); + assert_inv(ergo(err == 0, iam_leaf_check(leaf))); + } @@ -418,6 +419,7 @@ Index: iam/fs/ext3/iam.c + if (leaf->il_bh) { + brelse(leaf->il_bh); + leaf->il_bh = NULL; ++ leaf->il_curidx = 0; + } + } +} @@ -1450,7 +1452,7 @@ Index: iam/fs/ext3/iam_htree.c =================================================================== --- iam.orig/fs/ext3/iam_htree.c +++ iam/fs/ext3/iam_htree.c -@@ -0,0 +1,683 @@ +@@ -0,0 +1,684 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -1886,6 +1888,7 @@ Index: iam/fs/ext3/iam_htree.c + * insertion point moves into new leaf. + */ + assert_corr(delim_hash >= old_hash); ++ l->il_curidx = new_blknr; + iam_htree_lookup(l, (void *)&old_hash); + } + iam_insert_key_lock(path, @@ -2138,7 +2141,7 @@ Index: iam/fs/ext3/iam_lfix.c =================================================================== --- iam.orig/fs/ext3/iam_lfix.c +++ iam/fs/ext3/iam_lfix.c -@@ -0,0 +1,727 @@ +@@ -0,0 +1,728 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -2612,6 +2615,7 @@ Index: iam/fs/ext3/iam_lfix.c + shift = iam_lfix_diff(l, l->il_at, start); + *bh = l->il_bh; + l->il_bh = new_leaf; ++ l->il_curidx = new_blknr; + result = iam_lfix_init(l); + /* + * init cannot fail, as node was just initialized. @@ -2870,7 +2874,7 @@ Index: iam/fs/ext3/iam_lvar.c =================================================================== --- iam.orig/fs/ext3/iam_lvar.c +++ iam/fs/ext3/iam_lvar.c -@@ -0,0 +1,1028 @@ +@@ -0,0 +1,1040 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -3269,6 +3273,7 @@ Index: iam/fs/ext3/iam_lvar.c +static void lvar_next(struct iam_leaf *l) +{ + assert_corr(n_at_rec(l)); ++ assert_corr(iam_leaf_is_locked(l)); + l->il_at = lvar_lentry(e_next(l, n_cur(l))); +} + @@ -3380,6 +3385,7 @@ Index: iam/fs/ext3/iam_lvar.c +{ + assert_corr(n_at_rec(l)); + assert_corr(strlen(kchar(k)) == e_keysize(n_cur(l))); ++ assert_corr(iam_leaf_is_locked(l)); + memcpy(e_key(n_cur(l)), k, e_keysize(n_cur(l))); + assert_inv(n_invariant(l)); +} @@ -3406,6 +3412,7 @@ Index: iam/fs/ext3/iam_lvar.c +static void lvar_rec_set(struct iam_leaf *l, const struct iam_rec *r) +{ + assert_corr(n_at_rec(l)); ++ assert_corr(iam_leaf_is_locked(l)); + iam_reccpy(iam_leaf_path(l), e_rec(n_cur(l)), r); + assert_inv(n_invariant(l)); +} @@ -3413,11 +3420,13 @@ Index: iam/fs/ext3/iam_lvar.c +static int lvar_can_add(const struct iam_leaf *l, + const struct iam_key *k, const struct iam_rec *r) +{ ++ assert_corr(iam_leaf_is_locked(l)); + return h_used(n_head(l)) + getsize(l, strlen(kchar(k))) <= blocksize(l); +} + +static int lvar_at_end(const struct iam_leaf *folio) +{ ++ assert_corr(iam_leaf_is_locked(folio)); + return n_cur(folio) == n_end(folio); +} + @@ -3433,6 +3442,7 @@ Index: iam/fs/ext3/iam_lvar.c + + assert_corr(lvar_can_add(leaf, k, r)); + assert_inv(n_invariant(leaf)); ++ assert_corr(iam_leaf_is_locked(leaf)); + + key = kchar(k); + ksize = strlen(key); @@ -3473,6 +3483,7 @@ Index: iam/fs/ext3/iam_lvar.c + + assert_corr(n_at_rec(leaf)); + assert_inv(n_invariant(leaf)); ++ assert_corr(iam_leaf_is_locked(leaf)); + + end = n_end(leaf); + next = e_next(leaf, n_cur(leaf)); @@ -3520,6 +3531,7 @@ Index: iam/fs/ext3/iam_lvar.c + lvar_hash_t hash; + + assert_inv(n_invariant(leaf)); ++ assert_corr(iam_leaf_is_locked(leaf)); + + new_leaf = *bh; + path = iam_leaf_path(leaf); @@ -3555,6 +3567,9 @@ Index: iam/fs/ext3/iam_lvar.c + shift = PDIFF(leaf->il_at, first_to_move); + *bh = leaf->il_bh; + leaf->il_bh = new_leaf; ++ leaf->il_curidx = new_blknr; ++ ++ assert_corr(iam_leaf_is_locked(leaf)); + result = lvar_init(leaf); + /* + * init cannot fail, as node was just initialized. @@ -3633,6 +3648,7 @@ Index: iam/fs/ext3/iam_lvar.c + struct lvar_root *root; + struct iam_entry *entries; + ++ assert_corr(iam_frame_is_locked(path, frame)); + entries = frame->entries; + + dx_set_count(entries, 2); diff --git a/lustre/kernel_patches/patches/ext3-pdirops-2.6.9.patch b/lustre/kernel_patches/patches/ext3-pdirops-2.6.9.patch index 34f686a..d28d554 100644 --- a/lustre/kernel_patches/patches/ext3-pdirops-2.6.9.patch +++ b/lustre/kernel_patches/patches/ext3-pdirops-2.6.9.patch @@ -479,14 +479,10 @@ Index: iam/fs/ext3/namei.c * there's no point to read in the successive index pages. */ iam_get_ikey(path, p->at, (struct iam_ikey *)&bhash); -@@ -425,25 +665,96 @@ static int ext3_htree_advance(struct ino +@@ -425,25 +665,92 @@ static int ext3_htree_advance(struct ino * block so no check is necessary */ while (num_frames--) { -+ /* -+ * XXX hmm... don't we need dx_{,un}lock_bh() and -+ * dx_path_check() calls here? -- nikita. -+ */ + iam_ptr_t idx; + + do_corr(schedule()); @@ -581,7 +577,7 @@ Index: iam/fs/ext3/namei.c } int ext3_htree_next_block(struct inode *dir, __u32 hash, -@@ -657,6 +968,15 @@ void iam_insert_key(struct iam_path *pat +@@ -657,6 +964,15 @@ void iam_insert_key(struct iam_path *pat dx_set_ikey(path, new, key); dx_set_block(path, new, ptr); dx_set_count(entries, count + 1); @@ -597,7 +593,7 @@ Index: iam/fs/ext3/namei.c } void dx_insert_block(struct iam_path *path, struct iam_frame *frame, -@@ -882,7 +1202,7 @@ static struct buffer_head * ext3_dx_find +@@ -882,7 +1198,7 @@ static struct buffer_head * ext3_dx_find sb = dir->i_sb; /* NFS may look up ".." - look at dx_root directory block */ if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){ @@ -606,7 +602,7 @@ Index: iam/fs/ext3/namei.c if (*err != 0) return NULL; } else { -@@ -1114,7 +1434,7 @@ struct ext3_dir_entry_2 *move_entries(st +@@ -1114,7 +1430,7 @@ struct ext3_dir_entry_2 *move_entries(st hash2 = map[split].hash; continued = hash2 == map[split - 1].hash; dxtrace(printk("Split block %i at %x, %i/%i\n", @@ -615,7 +611,7 @@ Index: iam/fs/ext3/namei.c /* Fancy dance to stay within two buffers */ de2 = dx_move_dirents(data1, data2, map + split, count - split); -@@ -1484,16 +1804,38 @@ static int shift_entries(struct iam_path +@@ -1484,16 +1800,38 @@ static int shift_entries(struct iam_path (char *) iam_entry_shift(path, entries, count1), count2 * iam_entry_size(path)); @@ -657,7 +653,7 @@ Index: iam/fs/ext3/namei.c { struct iam_entry *entries; /* old block contents */ -@@ -1501,6 +1843,8 @@ int split_index_node(handle_t *handle, s +@@ -1501,6 +1839,8 @@ int split_index_node(handle_t *handle, s struct iam_frame *frame, *safe; struct buffer_head *bh_new[DX_MAX_TREE_HEIGHT] = {0}; u32 newblock[DX_MAX_TREE_HEIGHT] = {0}; @@ -666,7 +662,7 @@ Index: iam/fs/ext3/namei.c struct inode *dir = iam_path_obj(path); struct iam_descr *descr; int nr_splet; -@@ -1523,12 +1867,14 @@ int split_index_node(handle_t *handle, s +@@ -1523,12 +1863,14 @@ int split_index_node(handle_t *handle, s * - first allocate all necessary blocks * * - insert pointers into them atomically. @@ -685,7 +681,7 @@ Index: iam/fs/ext3/namei.c dxtrace(printk("using %u of %u node entries\n", dx_get_count(entries), dx_get_limit(entries))); -@@ -1536,6 +1882,7 @@ int split_index_node(handle_t *handle, s +@@ -1536,6 +1878,7 @@ int split_index_node(handle_t *handle, s for (nr_splet = 0; frame >= path->ip_frames && dx_get_count(frame->entries) == dx_get_limit(frame->entries); --frame, ++nr_splet) { @@ -693,7 +689,7 @@ Index: iam/fs/ext3/namei.c if (nr_splet == DX_MAX_TREE_HEIGHT) { ext3_warning(dir->i_sb, __FUNCTION__, "Directory index full!\n"); -@@ -1545,14 +1892,53 @@ int split_index_node(handle_t *handle, s +@@ -1545,14 +1888,53 @@ int split_index_node(handle_t *handle, s } safe = frame; @@ -748,7 +744,7 @@ Index: iam/fs/ext3/namei.c BUFFER_TRACE(frame->bh, "get_write_access"); err = ext3_journal_get_write_access(handle, frame->bh); if (err) -@@ -1560,6 +1946,7 @@ int split_index_node(handle_t *handle, s +@@ -1560,6 +1942,7 @@ int split_index_node(handle_t *handle, s } /* Add "safe" node to transaction too */ if (safe + 1 != path->ip_frames) { @@ -756,7 +752,7 @@ Index: iam/fs/ext3/namei.c err = ext3_journal_get_write_access(handle, safe->bh); if (err) goto journal_error; -@@ -1596,16 +1983,21 @@ int split_index_node(handle_t *handle, s +@@ -1596,16 +1979,21 @@ int split_index_node(handle_t *handle, s assert_corr(i == 0); @@ -778,7 +774,7 @@ Index: iam/fs/ext3/namei.c /* Shift frames in the path */ memmove(frames + 2, frames + 1, (sizeof path->ip_frames) - 2 * sizeof frames[0]); -@@ -1613,18 +2005,22 @@ int split_index_node(handle_t *handle, s +@@ -1613,18 +2001,22 @@ int split_index_node(handle_t *handle, s frames[1].at = iam_entry_shift(path, entries2, idx); frames[1].entries = entries = entries2; frames[1].bh = bh2; @@ -801,7 +797,7 @@ Index: iam/fs/ext3/namei.c count = shift_entries(path, frame, count, entries, entries2, newblock[i]); /* Which index block gets the new entry? */ -@@ -1635,32 +2031,42 @@ int split_index_node(handle_t *handle, s +@@ -1635,32 +2027,42 @@ int split_index_node(handle_t *handle, s idx - count + d); frame->entries = entries = entries2; swap(frame->bh, bh2); @@ -845,7 +841,7 @@ Index: iam/fs/ext3/namei.c if (nr_splet > 0) { /* * Log ->i_size modification. -@@ -1674,6 +2080,10 @@ journal_error: +@@ -1674,6 +2076,10 @@ journal_error: ext3_std_error(dir->i_sb, err); cleanup: @@ -856,7 +852,7 @@ Index: iam/fs/ext3/namei.c for (i = 0; i < ARRAY_SIZE(bh_new); ++i) { if (bh_new[i] != NULL) brelse(bh_new[i]); -@@ -1695,18 +2105,18 @@ static int ext3_dx_add_entry(handle_t *h +@@ -1695,18 +2101,18 @@ static int ext3_dx_add_entry(handle_t *h struct buffer_head * bh = NULL; struct inode *dir = dentry->d_parent->d_inode; struct ext3_dir_entry_2 *de; @@ -877,7 +873,7 @@ Index: iam/fs/ext3/namei.c isize = dir->i_size; err = param->id_ops->id_node_read(path->ip_container, -@@ -1726,7 +2136,7 @@ static int ext3_dx_add_entry(handle_t *h +@@ -1726,7 +2132,7 @@ static int ext3_dx_add_entry(handle_t *h goto cleanup; } @@ -886,7 +882,7 @@ Index: iam/fs/ext3/namei.c if (err) goto cleanup; -@@ -1736,12 +2146,14 @@ static int ext3_dx_add_entry(handle_t *h +@@ -1736,12 +2142,14 @@ static int ext3_dx_add_entry(handle_t *h goto cleanup; assert_inv(dx_node_check(path, frame)); @@ -981,7 +977,7 @@ Index: iam/include/linux/lustre_iam.h }; /* -@@ -205,6 +215,10 @@ struct iam_leaf { +@@ -205,6 +215,11 @@ struct iam_leaf { struct buffer_head *il_bh; struct iam_lentry *il_entries; struct iam_lentry *il_at; @@ -989,10 +985,11 @@ Index: iam/include/linux/lustre_iam.h + * Lock on a leaf node. + */ + struct dynlock_handle *il_lock; ++ iam_ptr_t il_curidx; /* logical offset of leaf node. */ void *il_descr_data; }; -@@ -215,19 +229,23 @@ enum iam_lookup_t { +@@ -215,19 +230,23 @@ enum iam_lookup_t { /* * lookup found a record with the key requested */ @@ -1020,7 +1017,7 @@ Index: iam/include/linux/lustre_iam.h }; /* -@@ -271,8 +289,7 @@ struct iam_operations { +@@ -271,8 +290,7 @@ struct iam_operations { struct iam_frame *frame); struct iam_path_descr *(*id_ipd_alloc)(const struct iam_container *c); @@ -1030,7 +1027,7 @@ Index: iam/include/linux/lustre_iam.h /* * Format name. */ -@@ -331,6 +348,7 @@ struct iam_leaf_operations { +@@ -331,6 +349,7 @@ struct iam_leaf_operations { 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); @@ -1038,7 +1035,7 @@ Index: iam/include/linux/lustre_iam.h int (*key_size)(const struct iam_leaf *l); /* -@@ -473,7 +491,7 @@ struct iam_path_compat { +@@ -473,7 +492,7 @@ struct iam_path_compat { struct iam_container ipc_container; __u32 ipc_scratch[DX_SCRATCH_KEYS]; struct dx_hash_info *ipc_hinfo; @@ -1047,18 +1044,45 @@ Index: iam/include/linux/lustre_iam.h struct iam_path_descr ipc_descr; struct dx_hash_info ipc_hinfo_area; }; -@@ -848,7 +866,9 @@ static inline struct iam_ikey *iam_path_ +@@ -848,7 +867,36 @@ static inline struct iam_ikey *iam_path_ return path->ip_data->ipd_key_scratch[nr]; } -int dx_lookup(struct iam_path *path); ++static inline struct dynlock *path_dynlock(struct iam_path *path) ++{ ++ return &EXT3_I(iam_path_obj(path))->i_htree_lock; ++} ++ ++static inline int iam_leaf_is_locked(const struct iam_leaf *leaf) ++{ ++ int result; ++ ++ result = dynlock_is_locked(path_dynlock(leaf->il_path), ++ leaf->il_curidx); ++ if (!result) ++ dump_stack(); ++ return result; ++} ++ ++static inline int iam_frame_is_locked(struct iam_path *path, ++ const struct iam_frame *frame) ++{ ++ int result; ++ ++ result = dynlock_is_locked(path_dynlock(path), frame->curidx); ++ if (!result) ++ dump_stack(); ++ return result; ++} ++ +int dx_lookup_lock(struct iam_path *path, + struct dynlock_handle **dl, enum dynlock_type lt); + void dx_insert_block(struct iam_path *path, struct iam_frame *frame, u32 hash, u32 block); int dx_index_is_compat(struct iam_path *path); -@@ -858,7 +878,8 @@ int ext3_htree_next_block(struct inode * +@@ -858,7 +906,8 @@ int ext3_htree_next_block(struct inode * struct buffer_head *ext3_append(handle_t *handle, struct inode *inode, u32 *block, int *err); @@ -1068,7 +1092,7 @@ Index: iam/include/linux/lustre_iam.h struct ext3_dir_entry_2 *split_entry(struct inode *dir, struct ext3_dir_entry_2 *de, unsigned long ino, mode_t mode, -@@ -874,6 +895,10 @@ struct ext3_dir_entry_2 *move_entries(st +@@ -874,6 +923,10 @@ struct ext3_dir_entry_2 *move_entries(st extern struct iam_descr iam_htree_compat_param; @@ -1079,7 +1103,7 @@ Index: iam/include/linux/lustre_iam.h /* * external */ -@@ -889,7 +914,7 @@ int iam_read_leaf(struct iam_path *p); +@@ -889,7 +942,7 @@ int iam_read_leaf(struct iam_path *p); int iam_node_read(struct iam_container *c, iam_ptr_t ptr, handle_t *handle, struct buffer_head **bh); -- 1.8.3.1