Skip to content

Commit

Permalink
reiserfs: locking, handle nested locks properly
Browse files Browse the repository at this point in the history
The reiserfs write lock replaced the BKL and uses similar semantics.

Frederic's locking code makes a distinction between when the lock is nested
and when it's being acquired/released, but I don't think that's the right
distinction to make.

The right distinction is between the lock being released at end-of-use and
the lock being released for a schedule. The unlock should return the depth
and the lock should restore it, rather than the other way around as it is now.

This patch implements that and adds a number of places where the lock
should be dropped.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
  • Loading branch information
Jeff Mahoney authored and Jeff Mahoney committed Aug 8, 2013
1 parent 4c05141 commit 278f667
Show file tree
Hide file tree
Showing 13 changed files with 201 additions and 194 deletions.
5 changes: 3 additions & 2 deletions fs/reiserfs/bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1340,10 +1340,11 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
"reading failed", __func__, block);
else {
if (buffer_locked(bh)) {
int depth;
PROC_INFO_INC(sb, scan_bitmap.wait);
reiserfs_write_unlock(sb);
depth = reiserfs_write_unlock_nested(sb);
__wait_on_buffer(bh);
reiserfs_write_lock(sb);
reiserfs_write_lock_nested(sb, depth);
}
BUG_ON(!buffer_uptodate(bh));
BUG_ON(atomic_read(&bh->b_count) == 0);
Expand Down
7 changes: 4 additions & 3 deletions fs/reiserfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx)
char small_buf[32]; /* avoid kmalloc if we can */
struct reiserfs_dir_entry de;
int ret = 0;
int depth;

reiserfs_write_lock(inode->i_sb);

Expand Down Expand Up @@ -181,17 +182,17 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx)
* Since filldir might sleep, we can release
* the write lock here for other waiters
*/
reiserfs_write_unlock(inode->i_sb);
depth = reiserfs_write_unlock_nested(inode->i_sb);
if (!dir_emit
(ctx, local_buf, d_reclen, d_ino,
DT_UNKNOWN)) {
reiserfs_write_lock(inode->i_sb);
reiserfs_write_lock_nested(inode->i_sb, depth);
if (local_buf != small_buf) {
kfree(local_buf);
}
goto end;
}
reiserfs_write_lock(inode->i_sb);
reiserfs_write_lock_nested(inode->i_sb, depth);
if (local_buf != small_buf) {
kfree(local_buf);
}
Expand Down
26 changes: 14 additions & 12 deletions fs/reiserfs/fix_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,9 +1022,9 @@ static int get_far_parent(struct tree_balance *tb,
if (buffer_locked(*pcom_father)) {

/* Release the write lock while the buffer is busy */
reiserfs_write_unlock(tb->tb_sb);
int depth = reiserfs_write_unlock_nested(tb->tb_sb);
__wait_on_buffer(*pcom_father);
reiserfs_write_lock(tb->tb_sb);
reiserfs_write_lock_nested(tb->tb_sb, depth);
if (FILESYSTEM_CHANGED_TB(tb)) {
brelse(*pcom_father);
return REPEAT_SEARCH;
Expand Down Expand Up @@ -1929,9 +1929,9 @@ static int get_direct_parent(struct tree_balance *tb, int h)
return REPEAT_SEARCH;

if (buffer_locked(bh)) {
reiserfs_write_unlock(tb->tb_sb);
int depth = reiserfs_write_unlock_nested(tb->tb_sb);
__wait_on_buffer(bh);
reiserfs_write_lock(tb->tb_sb);
reiserfs_write_lock_nested(tb->tb_sb, depth);
if (FILESYSTEM_CHANGED_TB(tb))
return REPEAT_SEARCH;
}
Expand All @@ -1952,6 +1952,7 @@ static int get_neighbors(struct tree_balance *tb, int h)
unsigned long son_number;
struct super_block *sb = tb->tb_sb;
struct buffer_head *bh;
int depth;

PROC_INFO_INC(sb, get_neighbors[h]);

Expand All @@ -1969,9 +1970,9 @@ static int get_neighbors(struct tree_balance *tb, int h)
tb->FL[h]) ? tb->lkey[h] : B_NR_ITEMS(tb->
FL[h]);
son_number = B_N_CHILD_NUM(tb->FL[h], child_position);
reiserfs_write_unlock(sb);
depth = reiserfs_write_unlock_nested(tb->tb_sb);
bh = sb_bread(sb, son_number);
reiserfs_write_lock(sb);
reiserfs_write_lock_nested(tb->tb_sb, depth);
if (!bh)
return IO_ERROR;
if (FILESYSTEM_CHANGED_TB(tb)) {
Expand Down Expand Up @@ -2009,9 +2010,9 @@ static int get_neighbors(struct tree_balance *tb, int h)
child_position =
(bh == tb->FR[h]) ? tb->rkey[h] + 1 : 0;
son_number = B_N_CHILD_NUM(tb->FR[h], child_position);
reiserfs_write_unlock(sb);
depth = reiserfs_write_unlock_nested(tb->tb_sb);
bh = sb_bread(sb, son_number);
reiserfs_write_lock(sb);
reiserfs_write_lock_nested(tb->tb_sb, depth);
if (!bh)
return IO_ERROR;
if (FILESYSTEM_CHANGED_TB(tb)) {
Expand Down Expand Up @@ -2272,6 +2273,7 @@ static int wait_tb_buffers_until_unlocked(struct tree_balance *tb)
}

if (locked) {
int depth;
#ifdef CONFIG_REISERFS_CHECK
repeat_counter++;
if ((repeat_counter % 10000) == 0) {
Expand All @@ -2286,9 +2288,9 @@ static int wait_tb_buffers_until_unlocked(struct tree_balance *tb)
REPEAT_SEARCH : CARRY_ON;
}
#endif
reiserfs_write_unlock(tb->tb_sb);
depth = reiserfs_write_unlock_nested(tb->tb_sb);
__wait_on_buffer(locked);
reiserfs_write_lock(tb->tb_sb);
reiserfs_write_lock_nested(tb->tb_sb, depth);
if (FILESYSTEM_CHANGED_TB(tb))
return REPEAT_SEARCH;
}
Expand Down Expand Up @@ -2359,9 +2361,9 @@ int fix_nodes(int op_mode, struct tree_balance *tb,

/* if it possible in indirect_to_direct conversion */
if (buffer_locked(tbS0)) {
reiserfs_write_unlock(tb->tb_sb);
int depth = reiserfs_write_unlock_nested(tb->tb_sb);
__wait_on_buffer(tbS0);
reiserfs_write_lock(tb->tb_sb);
reiserfs_write_lock_nested(tb->tb_sb, depth);
if (FILESYSTEM_CHANGED_TB(tb))
return REPEAT_SEARCH;
}
Expand Down
Loading

0 comments on commit 278f667

Please sign in to comment.