Message ID | 1480628704-18216-1-git-send-email-bo.li.liu@oracle.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
On Thu, Dec 1, 2016 at 9:45 PM, Liu Bo <bo.li.liu@oracle.com> wrote: > 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. > > Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Reviewed-by: Filipe Manana <fdmanana@suse.com> Thanks, it works and it's simple. > --- > fs/btrfs/tree-log.c | 12 +++++++++--- > 1 file changed, 9 insertions(+), 3 deletions(-) > > diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c > index 3d33c4e..e961451 100644 > --- a/fs/btrfs/tree-log.c > +++ b/fs/btrfs/tree-log.c > @@ -37,6 +37,7 @@ > */ > #define LOG_INODE_ALL 0 > #define LOG_INODE_EXISTS 1 > +#define LOG_OTHER_INODE 2 > > /* > * directory trouble cases > @@ -4624,7 +4625,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, > if (S_ISDIR(inode->i_mode) || > (!test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, > &BTRFS_I(inode)->runtime_flags) && > - inode_only == LOG_INODE_EXISTS)) > + inode_only >= LOG_INODE_EXISTS)) > max_key.type = BTRFS_XATTR_ITEM_KEY; > else > max_key.type = (u8)-1; > @@ -4648,7 +4649,12 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, > 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, 1); > + } else { > + mutex_lock(&BTRFS_I(inode)->log_mutex); > + } > > /* > * a brute force approach to making sure we get the most uptodate > @@ -4800,7 +4806,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, > * unpin it. > */ > err = btrfs_log_inode(trans, root, other_inode, > - LOG_INODE_EXISTS, > + LOG_OTHER_INODE, > 0, LLONG_MAX, ctx); > iput(other_inode); > if (err) > -- > 2.5.5 >
On Thu, Dec 01, 2016 at 01:45:04PM -0800, Liu Bo wrote:
> + mutex_lock_nested(&BTRFS_I(inode)->log_mutex, 1);
Please also use SINGLE_DEPTH_NESTING here.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 3d33c4e..e961451 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -37,6 +37,7 @@ */ #define LOG_INODE_ALL 0 #define LOG_INODE_EXISTS 1 +#define LOG_OTHER_INODE 2 /* * directory trouble cases @@ -4624,7 +4625,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, if (S_ISDIR(inode->i_mode) || (!test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags) && - inode_only == LOG_INODE_EXISTS)) + inode_only >= LOG_INODE_EXISTS)) max_key.type = BTRFS_XATTR_ITEM_KEY; else max_key.type = (u8)-1; @@ -4648,7 +4649,12 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, 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, 1); + } else { + mutex_lock(&BTRFS_I(inode)->log_mutex); + } /* * a brute force approach to making sure we get the most uptodate @@ -4800,7 +4806,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, * unpin it. */ err = btrfs_log_inode(trans, root, other_inode, - LOG_INODE_EXISTS, + LOG_OTHER_INODE, 0, LLONG_MAX, ctx); iput(other_inode); if (err)
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. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> --- fs/btrfs/tree-log.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)