lkml.org 
[lkml]   [2017]   [Jul]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH for v4.9 LTS 35/87] Btrfs: fix lockdep warning about log_mutex
    Date
    From: Liu Bo <bo.li.liu@oracle.com>

    [ Upstream commit 781feef7e6befafd4d9787d1f7ada1f9ccd504e4 ]

    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: Filipe Manana <fdmanana@suse.com>
    Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
    Signed-off-by: David Sterba <dsterba@suse.com>
    Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
    ---
    fs/btrfs/tree-log.c | 13 ++++++++++---
    1 file changed, 10 insertions(+), 3 deletions(-)

    diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
    index b89004513c09..309313b71617 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
    @@ -4623,7 +4624,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;
    @@ -4647,7 +4648,13 @@ 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,
    + SINGLE_DEPTH_NESTING);
    + } else {
    + mutex_lock(&BTRFS_I(inode)->log_mutex);
    + }

    /*
    * a brute force approach to making sure we get the most uptodate
    @@ -4799,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.11.0
    \
     
     \ /
      Last update: 2017-07-15 03:39    [W:3.131 / U:0.596 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site