• Brian Foster's avatar
    xfs: fix broken i_nlink accounting for whiteout tmpfile inode · 22419ac9
    Brian Foster authored
    XFS uses the internal tmpfile() infrastructure for the whiteout inode
    used for RENAME_WHITEOUT operations. For tmpfile inodes, XFS allocates
    the inode, drops di_nlink, adds the inode to the agi unlinked list,
    calls d_tmpfile() which correspondingly drops i_nlink of the vfs inode,
    and then finishes the common inode setup (e.g., clear I_NEW and unlock).
    
    The d_tmpfile() call was originally made inxfs_create_tmpfile(), but was
    pulled up out of that function as part of the following commit to
    resolve a deadlock issue:
    
    	330033d6 xfs: fix tmpfile/selinux deadlock and initialize security
    
    As a result, callers of xfs_create_tmpfile() are responsible for either
    calling d_tmpfile() or fixing up i_nlink appropriately. The whiteout
    tmpfile allocation helper does neither. As a result, the vfs ->i_nlink
    becomes inconsistent with the on-disk ->di_nlink once xfs_rename() links
    it back into the source dentry and calls xfs_bumplink().
    
    Update the assert in xfs_rename() to help detect this problem in the
    future and update xfs_rename_alloc_whiteout() to decrement the link
    count as part of the manual tmpfile inode setup.
    Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
    Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
    Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
    
    22419ac9
xfs_inode.c 97.2 KB