aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/fix_node.c
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-05-16 13:10:38 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2009-09-14 01:18:25 -0400
commit08f14fc8963e585e65b71212ce8050607b9b6c36 (patch)
tree04d808f71193df2a90d485fcc0e2604bd8fe8d93 /fs/reiserfs/fix_node.c
parentc72e05756b900b3be24cd73a16de52bab80984c0 (diff)
kill-the-bkl/reiserfs: move the concurrent tree accesses checks per superblock
When do_balance() balances the tree, a trick is performed to provide the ability for other tree writers/readers to check whether do_balance() is executing concurrently (requires CONFIG_REISERFS_CHECK). This is done to protect concurrent accesses to the tree. The trick is the following: When do_balance is called, a unique global variable called cur_tb takes a pointer to the current tree to be rebalanced. Once do_balance finishes its work, cur_tb takes the NULL value. Then, concurrent tree readers/writers just have to check the value of cur_tb to ensure do_balance isn't executing concurrently. If it is, then it proves that schedule() occured on do_balance(), which then relaxed the bkl that protected the tree. Now that the bkl has be turned into a mutex, this check is still fine even though do_balance() becomes preemptible: the write lock will not be automatically released on schedule(), so the tree is still protected. But this is only fine if we have a single reiserfs mountpoint. Indeed, because the bkl is a global lock, it didn't allowed concurrent executions between a tree reader/writer in a mount point and a do_balance() on another tree from another mountpoint. So assuming all these readers/writers weren't supposed to be reentrant, the current check now sometimes detect false positives with the current per-superblock mutex which allows this reentrancy. This patch keeps the concurrent tree accesses check but moves it per superblock, so that only trees from a same mount point are checked to be not accessed concurrently. [ Impact: fix spurious panic while running several reiserfs mount-points ] Cc: Jeff Mahoney <jeffm@suse.com> Cc: Chris Mason <chris.mason@oracle.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Alexander Beregalov <a.beregalov@gmail.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'fs/reiserfs/fix_node.c')
-rw-r--r--fs/reiserfs/fix_node.c5
1 files changed, 1 insertions, 4 deletions
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index 3a685e3f754f..d2f31330dcae 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -563,9 +563,6 @@ static int get_num_ver(int mode, struct tree_balance *tb, int h,
563 return needed_nodes; 563 return needed_nodes;
564} 564}
565 565
566#ifdef CONFIG_REISERFS_CHECK
567extern struct tree_balance *cur_tb;
568#endif
569 566
570/* Set parameters for balancing. 567/* Set parameters for balancing.
571 * Performs write of results of analysis of balancing into structure tb, 568 * Performs write of results of analysis of balancing into structure tb,
@@ -2368,7 +2365,7 @@ int fix_nodes(int op_mode, struct tree_balance *tb,
2368 return REPEAT_SEARCH; 2365 return REPEAT_SEARCH;
2369 } 2366 }
2370#ifdef CONFIG_REISERFS_CHECK 2367#ifdef CONFIG_REISERFS_CHECK
2371 if (cur_tb) { 2368 if (REISERFS_SB(tb->tb_sb)->cur_tb) {
2372 print_cur_tb("fix_nodes"); 2369 print_cur_tb("fix_nodes");
2373 reiserfs_panic(tb->tb_sb, "PAP-8305", 2370 reiserfs_panic(tb->tb_sb, "PAP-8305",
2374 "there is pending do_balance"); 2371 "there is pending do_balance");