summaryrefslogtreecommitdiff
path: root/fs/reiserfs/dir.c
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2013-08-09 01:34:46 +0400
committerJeff Mahoney <jeffm@suse.de>2013-08-09 01:34:46 +0400
commit278f6679f454bf185a07d9a4ca355b153482d17a (patch)
treeffead073e67cfdc1ddfc3949ebc93c06dcaaab8f /fs/reiserfs/dir.c
parent4c05141df57f4ffc1a9a28f1925434924179bfe4 (diff)
downloadlinux-278f6679f454bf185a07d9a4ca355b153482d17a.tar.xz
reiserfs: locking, handle nested locks properly
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>
Diffstat (limited to 'fs/reiserfs/dir.c')
-rw-r--r--fs/reiserfs/dir.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 03e4ca5624d6..1fd2051109a3 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -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);
@@ -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);
}