aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-04-30 19:10:52 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2009-09-14 01:18:10 -0400
commit148d3504c1d9f964cf14fafc46d2b7d1f0bed2b1 (patch)
tree6b17f1361099e8b579d10e892a8d919eae037354 /fs
parent5e69e3a4492ea5abfd2e8ddc575448becf28e4d9 (diff)
kill-the-BKL/reiserfs: release the write lock inside get_neighbors()
get_neighbors() is used to get the left and/or right blocks against a given one in order to balance a tree. sb_bread() is used to read the buffer of these neighors blocks and while it waits for this operation, it might sleep. The bkl was released at this point, and then we can also release the write lock before calling sb_bread(). This is safe because if the filesystem is changed after this lock release, the function returns REPEAT_SEARCH (aka SCHEDULE_OCCURRED in the function header comments) in order to repeat the neighbhor research. [ Impact: release the reiserfs write lock when it is not needed ] Cc: Jeff Mahoney <jeffm@suse.com> Cc: Chris Mason <chris.mason@oracle.com> Cc: Alexander Beregalov <a.beregalov@gmail.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/reiserfs/fix_node.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index bf5f2cbdb063..3a685e3f754f 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -1971,7 +1971,9 @@ static int get_neighbors(struct tree_balance *tb, int h)
1971 tb->FL[h]) ? tb->lkey[h] : B_NR_ITEMS(tb-> 1971 tb->FL[h]) ? tb->lkey[h] : B_NR_ITEMS(tb->
1972 FL[h]); 1972 FL[h]);
1973 son_number = B_N_CHILD_NUM(tb->FL[h], child_position); 1973 son_number = B_N_CHILD_NUM(tb->FL[h], child_position);
1974 reiserfs_write_unlock(sb);
1974 bh = sb_bread(sb, son_number); 1975 bh = sb_bread(sb, son_number);
1976 reiserfs_write_lock(sb);
1975 if (!bh) 1977 if (!bh)
1976 return IO_ERROR; 1978 return IO_ERROR;
1977 if (FILESYSTEM_CHANGED_TB(tb)) { 1979 if (FILESYSTEM_CHANGED_TB(tb)) {
@@ -2009,7 +2011,9 @@ static int get_neighbors(struct tree_balance *tb, int h)
2009 child_position = 2011 child_position =
2010 (bh == tb->FR[h]) ? tb->rkey[h] + 1 : 0; 2012 (bh == tb->FR[h]) ? tb->rkey[h] + 1 : 0;
2011 son_number = B_N_CHILD_NUM(tb->FR[h], child_position); 2013 son_number = B_N_CHILD_NUM(tb->FR[h], child_position);
2014 reiserfs_write_unlock(sb);
2012 bh = sb_bread(sb, son_number); 2015 bh = sb_bread(sb, son_number);
2016 reiserfs_write_lock(sb);
2013 if (!bh) 2017 if (!bh)
2014 return IO_ERROR; 2018 return IO_ERROR;
2015 if (FILESYSTEM_CHANGED_TB(tb)) { 2019 if (FILESYSTEM_CHANGED_TB(tb)) {