From dc86b67e94ff6fe65198473c5d92209a06f1a1b7 Mon Sep 17 00:00:00 2001 From: nikita Date: Fri, 10 Nov 2006 16:46:00 +0000 Subject: [PATCH] iam: take dx lock when inserting new pointer into index node. --- .../kernel_patches/patches/ext3-iam-separate.patch | 11 ++-- .../patches/ext3-pdirops-2.6.9.patch | 63 +++++++++++++++------- 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/lustre/kernel_patches/patches/ext3-iam-separate.patch b/lustre/kernel_patches/patches/ext3-iam-separate.patch index f424195..3939256 100644 --- a/lustre/kernel_patches/patches/ext3-iam-separate.patch +++ b/lustre/kernel_patches/patches/ext3-iam-separate.patch @@ -1422,7 +1422,7 @@ Index: iam/fs/ext3/iam_htree.c =================================================================== --- iam.orig/fs/ext3/iam_htree.c +++ iam/fs/ext3/iam_htree.c -@@ -0,0 +1,682 @@ +@@ -0,0 +1,683 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -1853,7 +1853,8 @@ Index: iam/fs/ext3/iam_htree.c + * the node) into index node. + */ + path = iam_leaf_path(l); -+ iam_insert_key(path, path->ip_frame, (void *)&delim_hash, new_blknr); ++ iam_insert_key_lock(path, ++ path->ip_frame, (void *)&delim_hash, new_blknr); + if (l->il_bh == newbh) { + /* + * insertion point moves into new leaf. @@ -2525,7 +2526,7 @@ Index: iam/fs/ext3/iam_lfix.c + * Insert pointer to the new node (together with the least key in + * the node) into index node. + */ -+ iam_insert_key(path, path->ip_frame, pivot, new_blknr); ++ iam_insert_key_lock(path, path->ip_frame, pivot, new_blknr); + if ((void *)l->il_at >= start) { + /* + * insertion point moves into new leaf. @@ -3452,8 +3453,8 @@ Index: iam/fs/ext3/iam_lvar.c + * Insert pointer to the new node (together with the least key in + * the node) into index node. + */ -+ iam_insert_key(path, path->ip_frame, (struct iam_ikey *)&hash, -+ new_blknr); ++ iam_insert_key_lock(path, path->ip_frame, (struct iam_ikey *)&hash, ++ new_blknr); + if (n_cur(leaf) >= first_to_move) { + /* + * insertion point moves into new leaf. 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 5702631..efe56a5 100644 --- a/lustre/kernel_patches/patches/ext3-pdirops-2.6.9.patch +++ b/lustre/kernel_patches/patches/ext3-pdirops-2.6.9.patch @@ -535,7 +535,22 @@ Index: iam/fs/ext3/namei.c } int ext3_htree_next_block(struct inode *dir, __u32 hash, -@@ -882,7 +1160,7 @@ static struct buffer_head * ext3_dx_find +@@ -659,6 +937,14 @@ void iam_insert_key(struct iam_path *pat + dx_set_count(entries, count + 1); + } + ++void iam_insert_key_lock(struct iam_path *path, struct iam_frame *frame, ++ const struct iam_ikey *key, iam_ptr_t ptr) ++{ ++ dx_lock_bh(frame->bh); ++ iam_insert_key(path, frame, key, ptr); ++ dx_unlock_bh(frame->bh); ++} ++ + void dx_insert_block(struct iam_path *path, struct iam_frame *frame, + u32 hash, u32 block) + { +@@ -882,7 +1168,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')){ @@ -544,7 +559,7 @@ Index: iam/fs/ext3/namei.c if (*err != 0) return NULL; } else { -@@ -1114,7 +1392,7 @@ struct ext3_dir_entry_2 *move_entries(st +@@ -1114,7 +1400,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", @@ -553,7 +568,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 +1762,40 @@ static int shift_entries(struct iam_path +@@ -1484,16 +1770,38 @@ static int shift_entries(struct iam_path (char *) iam_entry_shift(path, entries, count1), count2 * iam_entry_size(path)); @@ -561,6 +576,7 @@ Index: iam/fs/ext3/namei.c dx_set_count(entries2, count2 + delta); dx_set_limit(entries2, dx_node_limit(path)); +- iam_insert_key(path, parent, pivot, newblock); + /* + * NOTE: very subtle piece of code competing dx_probe() may find 2nd + * level index in root index, then we insert new index here and set @@ -568,9 +584,7 @@ Index: iam/fs/ext3/namei.c + * index w/o hash it looks for. the solution is to check root index + * after we locked just founded 2nd level index -bzzz + */ -+ dx_lock_bh(parent->bh); - iam_insert_key(path, parent, pivot, newblock); -+ dx_unlock_bh(parent->bh); ++ iam_insert_key_lock(path, parent, pivot, newblock); + + /* + * now old and new 2nd level index blocks contain all pointers, so @@ -596,7 +610,7 @@ Index: iam/fs/ext3/namei.c { struct iam_entry *entries; /* old block contents */ -@@ -1501,6 +1803,8 @@ int split_index_node(handle_t *handle, s +@@ -1501,6 +1809,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}; @@ -605,7 +619,7 @@ Index: iam/fs/ext3/namei.c struct inode *dir = iam_path_obj(path); struct iam_descr *descr; int nr_splet; -@@ -1523,12 +1827,14 @@ int split_index_node(handle_t *handle, s +@@ -1523,12 +1833,14 @@ int split_index_node(handle_t *handle, s * - first allocate all necessary blocks * * - insert pointers into them atomically. @@ -624,7 +638,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 +1842,7 @@ int split_index_node(handle_t *handle, s +@@ -1536,6 +1848,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) { @@ -632,7 +646,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 +1852,40 @@ int split_index_node(handle_t *handle, s +@@ -1545,14 +1858,40 @@ int split_index_node(handle_t *handle, s } safe = frame; @@ -674,7 +688,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 +1893,7 @@ int split_index_node(handle_t *handle, s +@@ -1560,6 +1899,7 @@ int split_index_node(handle_t *handle, s } /* Add "safe" node to transaction too */ if (safe + 1 != path->ip_frames) { @@ -682,7 +696,7 @@ Index: iam/fs/ext3/namei.c err = ext3_journal_get_write_access(handle, safe->bh); if (err) goto journal_error; -@@ -1596,16 +1930,21 @@ int split_index_node(handle_t *handle, s +@@ -1596,16 +1936,21 @@ int split_index_node(handle_t *handle, s assert_corr(i == 0); @@ -704,7 +718,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]); -@@ -1621,10 +1960,12 @@ int split_index_node(handle_t *handle, s +@@ -1621,10 +1966,12 @@ int split_index_node(handle_t *handle, s err = ext3_journal_get_write_access(handle, bh2); if (err) goto journal_error; @@ -717,7 +731,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,6 +1976,9 @@ int split_index_node(handle_t *handle, s +@@ -1635,6 +1982,9 @@ int split_index_node(handle_t *handle, s idx - count + d); frame->entries = entries = entries2; swap(frame->bh, bh2); @@ -727,7 +741,7 @@ Index: iam/fs/ext3/namei.c bh_new[i] = bh2; parent->at = iam_entry_shift(path, parent->at, +1); -@@ -1647,10 +1991,12 @@ int split_index_node(handle_t *handle, s +@@ -1647,10 +1997,12 @@ int split_index_node(handle_t *handle, s err = ext3_journal_dirty_metadata(handle, bh2); if (err) goto journal_error; @@ -740,7 +754,7 @@ Index: iam/fs/ext3/namei.c err = ext3_journal_dirty_metadata(handle, bh); if (err) goto journal_error; -@@ -1661,6 +2007,9 @@ int split_index_node(handle_t *handle, s +@@ -1661,6 +2013,9 @@ int split_index_node(handle_t *handle, s assert_corr(dx_get_count(path->ip_frame->entries) < dx_get_limit(path->ip_frame->entries)); } @@ -750,7 +764,7 @@ Index: iam/fs/ext3/namei.c if (nr_splet > 0) { /* * Log ->i_size modification. -@@ -1674,6 +2023,10 @@ journal_error: +@@ -1674,6 +2029,10 @@ journal_error: ext3_std_error(dir->i_sb, err); cleanup: @@ -761,7 +775,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 +2048,18 @@ static int ext3_dx_add_entry(handle_t *h +@@ -1695,18 +2054,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; @@ -782,7 +796,7 @@ Index: iam/fs/ext3/namei.c isize = dir->i_size; err = param->id_ops->id_node_read(path->ip_container, -@@ -1726,7 +2079,7 @@ static int ext3_dx_add_entry(handle_t *h +@@ -1726,7 +2085,7 @@ static int ext3_dx_add_entry(handle_t *h goto cleanup; } @@ -791,7 +805,7 @@ Index: iam/fs/ext3/namei.c if (err) goto cleanup; -@@ -1742,6 +2095,7 @@ static int ext3_dx_add_entry(handle_t *h +@@ -1742,6 +2101,7 @@ static int ext3_dx_add_entry(handle_t *h journal_error: ext3_std_error(dir->i_sb, err); cleanup: @@ -977,3 +991,12 @@ Index: iam/include/linux/lustre_iam.h /* * external */ +@@ -889,7 +914,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); + +-void iam_insert_key(struct iam_path *path, struct iam_frame *frame, ++void iam_insert_key_lock(struct iam_path *path, struct iam_frame *frame, + const struct iam_ikey *key, iam_ptr_t ptr); + + int iam_leaf_at_end(const struct iam_leaf *l); -- 1.8.3.1