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>
This commit is contained in:

committed by
Jeff Mahoney

parent
4c05141df5
commit
278f6679f4
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user