Commit 781feef7 authored by Liu Bo's avatar Liu Bo Committed by David Sterba

Btrfs: fix lockdep warning about log_mutex

While checking INODE_REF/INODE_EXTREF for a corner case, we may acquire a
different inode's log_mutex with holding the current inode's log_mutex, and
lockdep has complained this with a possilble deadlock warning.

Fix this by using mutex_lock_nested() when processing the other inode's
log_mutex.
Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent e321f8a8
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
*/ */
#define LOG_INODE_ALL 0 #define LOG_INODE_ALL 0
#define LOG_INODE_EXISTS 1 #define LOG_INODE_EXISTS 1
#define LOG_OTHER_INODE 2
/* /*
* directory trouble cases * directory trouble cases
...@@ -4641,7 +4642,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, ...@@ -4641,7 +4642,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
if (S_ISDIR(inode->i_mode) || if (S_ISDIR(inode->i_mode) ||
(!test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, (!test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
&BTRFS_I(inode)->runtime_flags) && &BTRFS_I(inode)->runtime_flags) &&
inode_only == LOG_INODE_EXISTS)) inode_only >= LOG_INODE_EXISTS))
max_key.type = BTRFS_XATTR_ITEM_KEY; max_key.type = BTRFS_XATTR_ITEM_KEY;
else else
max_key.type = (u8)-1; max_key.type = (u8)-1;
...@@ -4665,7 +4666,13 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, ...@@ -4665,7 +4666,13 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
return ret; return ret;
} }
mutex_lock(&BTRFS_I(inode)->log_mutex); if (inode_only == LOG_OTHER_INODE) {
inode_only = LOG_INODE_EXISTS;
mutex_lock_nested(&BTRFS_I(inode)->log_mutex,
SINGLE_DEPTH_NESTING);
} else {
mutex_lock(&BTRFS_I(inode)->log_mutex);
}
/* /*
* a brute force approach to making sure we get the most uptodate * a brute force approach to making sure we get the most uptodate
...@@ -4817,7 +4824,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, ...@@ -4817,7 +4824,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
* unpin it. * unpin it.
*/ */
err = btrfs_log_inode(trans, root, other_inode, err = btrfs_log_inode(trans, root, other_inode,
LOG_INODE_EXISTS, LOG_OTHER_INODE,
0, LLONG_MAX, ctx); 0, LLONG_MAX, ctx);
iput(other_inode); iput(other_inode);
if (err) if (err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment