• Eric Biggers's avatar
    ext4: avoid lockdep warning when inheriting encryption context · 2f8f5e76
    Eric Biggers authored
    On a lockdep-enabled kernel, xfstests generic/027 fails due to a lockdep
    warning when run on ext4 mounted with -o test_dummy_encryption:
    
        xfs_io/4594 is trying to acquire lock:
         (jbd2_handle
        ){++++.+}, at:
        [<ffffffff813096ef>] jbd2_log_wait_commit+0x5/0x11b
    
        but task is already holding lock:
         (jbd2_handle
        ){++++.+}, at:
        [<ffffffff813000de>] start_this_handle+0x354/0x3d8
    
    The abbreviated call stack is:
    
     [<ffffffff813096ef>] ? jbd2_log_wait_commit+0x5/0x11b
     [<ffffffff8130972a>] jbd2_log_wait_commit+0x40/0x11b
     [<ffffffff813096ef>] ? jbd2_log_wait_commit+0x5/0x11b
     [<ffffffff8130987b>] ? __jbd2_journal_force_commit+0x76/0xa6
     [<ffffffff81309896>] __jbd2_journal_force_commit+0x91/0xa6
     [<ffffffff813098b9>] jbd2_journal_force_commit_nested+0xe/0x18
     [<ffffffff812a6049>] ext4_should_retry_alloc+0x72/0x79
     [<ffffffff812f0c1f>] ext4_xattr_set+0xef/0x11f
     [<ffffffff812cc35b>] ext4_set_context+0x3a/0x16b
     [<ffffffff81258123>] fscrypt_inherit_context+0xe3/0x103
     [<ffffffff812ab611>] __ext4_new_inode+0x12dc/0x153a
     [<ffffffff812bd371>] ext4_create+0xb7/0x161
    
    When a file is created in an encrypted directory, ext4_set_context() is
    called to set an encryption context on the new file.  This calls
    ext4_xattr_set(), which contains a retry loop where the journal is
    forced to commit if an ENOSPC error is encountered.
    
    If the task actually were to wait for the journal to commit in this
    case, then it would deadlock because a handle remains open from
    __ext4_new_inode(), so the running transaction can't be committed yet.
    Fortunately, __jbd2_journal_force_commit() avoids the deadlock by not
    allowing the running transaction to be committed while the current task
    has it open.  However, the above lockdep warning is still triggered.
    
    This was a false positive which was introduced by: 1eaa566d: jbd2:
    track more dependencies on transaction commit
    
    Fix the problem by passing the handle through the 'fs_data' argument to
    ext4_set_context(), then using ext4_xattr_set_handle() instead of
    ext4_xattr_set().  And in the case where no journal handle is specified
    and ext4_set_context() has to open one, add an ENOSPC retry loop since
    in that case it is the outermost transaction.
    Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
    2f8f5e76
ialloc.c 38.3 KB