Skip to content
  • Dave Chinner's avatar
    xfs: zero length symlinks are not valid · 43feeea8
    Dave Chinner authored
    
    
    A log recovery failure has been reproduced where a symlink inode has
    a zero length in extent form. It was caused by a shutdown during a
    combined fstress+fsmark workload.
    
    The underlying problem is the issue in xfs_inactive_symlink(): the
    inode is unlocked between the symlink inactivation/truncation and
    the inode being freed. This opens a window for the inode to be
    written to disk before it xfs_ifree() removes it from the unlinked
    list, marks it free in the inobt and zeros the mode.
    
    For shortform inodes, the fix is simple. xfs_ifree() clears the data
    fork state, so there's no need to do it in xfs_inactive_symlink().
    This means the shortform fork verifier will not see a zero length
    data fork as it mirrors the inode size through to xfs_ifree()), and
    hence if the inode gets written back and the fork verifiers are run
    they will still see a fork that matches the on-disk inode size.
    
    For extent form (remote) symlinks, it is a little more tricky. Here
    we explicitly set the inode size to zero, so the above race can lead
    to zero length symlinks on disk. Because the inode is unlinked at
    this point (i.e. on the unlinked list) and unreferenced, it can
    never be seen again by a user. Hence when we set the inode size to
    zeor, also change the type to S_IFREG. xfs_ifree() expects S_IFREG
    inodes to be of zero length, and so this avoids all the problems of
    zero length symlinks ever hitting the disk. It also avoids the
    problem of needing to handle zero length symlink inodes in log
    recovery to replay the extent free intents and the remaining
    deferops to free the extents the symlink used.
    
    Also add a couple of asserts to warn us if zero length symlinks end
    up in either the symlink create or inactivation paths.
    
    Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
    Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    43feeea8