From: nikita Date: Fri, 27 Oct 2006 00:14:46 +0000 (+0000) Subject: iam: fix possible cause of dynlock-double-unlock. X-Git-Tag: v1_8_0_110~486^2~330 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=db068599738ac056b9d3b42523f4cff82b3e1b65;p=fs%2Flustre-release.git iam: fix possible cause of dynlock-double-unlock. --- 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 5712849..7685326 100644 --- a/lustre/kernel_patches/patches/ext3-pdirops-2.6.9.patch +++ b/lustre/kernel_patches/patches/ext3-pdirops-2.6.9.patch @@ -256,7 +256,7 @@ Index: iam/fs/ext3/namei.c if (err != 0) break; -@@ -283,53 +452,77 @@ int dx_lookup(struct iam_path *path) +@@ -283,53 +452,78 @@ int dx_lookup(struct iam_path *path) break; assert_inv(dx_node_check(path, frame)); @@ -365,6 +365,7 @@ Index: iam/fs/ext3/namei.c + if (dx_check_full_path(path) == 0) + break; + dx_unlock_htree(dir, *dl); ++ *dl = NULL; + iam_path_fini(path); + } + return result; @@ -373,7 +374,7 @@ Index: iam/fs/ext3/namei.c /* * Probe for a directory leaf block to search. * -@@ -339,7 +532,7 @@ int dx_lookup(struct iam_path *path) +@@ -339,7 +533,7 @@ int dx_lookup(struct iam_path *path) * check for this error code, and make sure it never gets reflected * back to userspace. */ @@ -382,7 +383,7 @@ Index: iam/fs/ext3/namei.c struct dx_hash_info *hinfo, struct iam_path *path) { int err; -@@ -347,7 +540,7 @@ static int dx_probe(struct dentry *dentr +@@ -347,7 +541,7 @@ static int dx_probe(struct dentry *dentr assert_corr(path->ip_data != NULL); ipc = container_of(path->ip_data, struct iam_path_compat, ipc_descr); @@ -391,7 +392,7 @@ Index: iam/fs/ext3/namei.c ipc->ipc_hinfo = hinfo; assert_corr(dx_index_is_compat(path)); -@@ -356,6 +549,7 @@ static int dx_probe(struct dentry *dentr +@@ -356,6 +550,7 @@ static int dx_probe(struct dentry *dentr return err; } @@ -399,7 +400,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 -@@ -393,8 +587,10 @@ static int ext3_htree_advance(struct ino +@@ -393,8 +588,10 @@ static int ext3_htree_advance(struct ino while (1) { p->at = iam_entry_shift(path, p->at, +1); if (p->at < iam_entry_shift(path, p->entries, @@ -411,7 +412,7 @@ Index: iam/fs/ext3/namei.c if (p == path->ip_frames) return 0; num_frames++; -@@ -409,7 +605,7 @@ static int ext3_htree_advance(struct ino +@@ -409,7 +606,7 @@ static int ext3_htree_advance(struct ino * If the hash is 1, then continue only if the next page has a * continuation hash of any value. This is used for readdir * handling. Otherwise, check to see if the hash matches the @@ -420,7 +421,7 @@ 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 +621,90 @@ static int ext3_htree_advance(struct ino +@@ -425,25 +622,90 @@ static int ext3_htree_advance(struct ino * block so no check is necessary */ while (num_frames--) { @@ -516,7 +517,7 @@ Index: iam/fs/ext3/namei.c } int ext3_htree_next_block(struct inode *dir, __u32 hash, -@@ -882,7 +1143,7 @@ static struct buffer_head * ext3_dx_find +@@ -882,7 +1144,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')){ @@ -525,7 +526,7 @@ Index: iam/fs/ext3/namei.c if (*err != 0) return NULL; } else { -@@ -1114,7 +1375,7 @@ struct ext3_dir_entry_2 *move_entries(st +@@ -1114,7 +1376,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", @@ -534,7 +535,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 +1745,40 @@ static int shift_entries(struct iam_path +@@ -1484,16 +1746,40 @@ static int shift_entries(struct iam_path (char *) iam_entry_shift(path, entries, count1), count2 * iam_entry_size(path)); @@ -577,7 +578,7 @@ Index: iam/fs/ext3/namei.c { struct iam_entry *entries; /* old block contents */ -@@ -1501,6 +1786,8 @@ int split_index_node(handle_t *handle, s +@@ -1501,6 +1787,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}; @@ -586,7 +587,7 @@ Index: iam/fs/ext3/namei.c struct inode *dir = iam_path_obj(path); struct iam_descr *descr; int nr_splet; -@@ -1523,12 +1810,14 @@ int split_index_node(handle_t *handle, s +@@ -1523,12 +1811,14 @@ int split_index_node(handle_t *handle, s * - first allocate all necessary blocks * * - insert pointers into them atomically. @@ -605,7 +606,7 @@ Index: iam/fs/ext3/namei.c dxtrace(printk("using %u of %u node entries\n", dx_get_count(entries), dx_get_limit(entries))); -@@ -1545,7 +1834,25 @@ int split_index_node(handle_t *handle, s +@@ -1545,7 +1835,25 @@ int split_index_node(handle_t *handle, s } safe = frame; @@ -614,7 +615,7 @@ Index: iam/fs/ext3/namei.c + /* + * Lock all nodes, bottom to top. + */ -+ for (frame = safe, i = 0; i <= nr_splet; ++i, ++frame) { ++ for (frame = path->ip_frame, i = nr_splet; i >= 0; --i, --frame) { + lock[i] = dx_lock_htree(dir, frame->curidx, DLT_WRITE); + if (lock[i] == NULL) { + err = -ENOMEM; @@ -632,7 +633,7 @@ Index: iam/fs/ext3/namei.c * transaction... */ for (frame = safe + 1, i = 0; i < nr_splet; ++i, ++frame) { bh_new[i] = ext3_append (handle, dir, &newblock[i], &err); -@@ -1553,6 +1860,11 @@ int split_index_node(handle_t *handle, s +@@ -1553,6 +1861,11 @@ int split_index_node(handle_t *handle, s descr->id_ops->id_node_init(path->ip_container, bh_new[i], 0) != 0) goto cleanup; @@ -644,7 +645,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) -@@ -1602,9 +1914,11 @@ int split_index_node(handle_t *handle, s +@@ -1602,9 +1915,11 @@ int split_index_node(handle_t *handle, s dx_set_limit(entries2, dx_node_limit(path)); /* Set up root */ @@ -656,7 +657,7 @@ Index: iam/fs/ext3/namei.c /* Shift frames in the path */ memmove(frames + 2, frames + 1, -@@ -1635,6 +1949,7 @@ int split_index_node(handle_t *handle, s +@@ -1635,6 +1950,7 @@ int split_index_node(handle_t *handle, s idx - count + d); frame->entries = entries = entries2; swap(frame->bh, bh2); @@ -664,7 +665,7 @@ Index: iam/fs/ext3/namei.c bh_new[i] = bh2; parent->at = iam_entry_shift(path, parent->at, +1); -@@ -1662,6 +1977,8 @@ int split_index_node(handle_t *handle, s +@@ -1662,6 +1978,8 @@ int split_index_node(handle_t *handle, s dx_get_limit(path->ip_frame->entries)); } if (nr_splet > 0) { @@ -673,7 +674,7 @@ Index: iam/fs/ext3/namei.c /* * Log ->i_size modification. */ -@@ -1674,6 +1991,9 @@ journal_error: +@@ -1674,6 +1992,9 @@ journal_error: ext3_std_error(dir->i_sb, err); cleanup: @@ -683,7 +684,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 +2015,18 @@ static int ext3_dx_add_entry(handle_t *h +@@ -1695,18 +2016,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; @@ -704,7 +705,7 @@ Index: iam/fs/ext3/namei.c isize = dir->i_size; err = param->id_ops->id_node_read(path->ip_container, -@@ -1726,7 +2046,7 @@ static int ext3_dx_add_entry(handle_t *h +@@ -1726,7 +2047,7 @@ static int ext3_dx_add_entry(handle_t *h goto cleanup; } @@ -713,7 +714,7 @@ Index: iam/fs/ext3/namei.c if (err) goto cleanup; -@@ -1742,6 +2062,7 @@ static int ext3_dx_add_entry(handle_t *h +@@ -1742,6 +2063,7 @@ static int ext3_dx_add_entry(handle_t *h journal_error: ext3_std_error(dir->i_sb, err); cleanup: