• Dave Chinner's avatar
    xfs: xfs_swap_extents needs to handle dynamic fork offsets · e09f9860
    Dave Chinner authored
    When swapping extents, we can corrupt inodes by swapping data forks
    that are in incompatible formats.  This is caused by the two indoes
    having different fork offsets due to the presence of an attribute
    fork on an attr2 filesystem.  xfs_fsr tries to be smart about
    setting the fork offset, but the trick it plays only works on attr1
    (old fixed format attribute fork) filesystems.
    
    Changing the way xfs_fsr sets up the attribute fork will prevent
    this situation from ever occurring, so in the kernel code we can get
    by with a preventative fix - check that the data fork in the
    defragmented inode is in a format valid for the inode it is being
    swapped into.  This will lead to files that will silently and
    potentially repeatedly fail defragmentation, so issue a warning to
    the log when this particular failure occurs to let us know that
    xfs_fsr needs updating/fixing.
    
    To help identify how to improve xfs_fsr to avoid this issue, add
    trace points for the inodes being swapped so that we can determine
    why the swap was rejected and to confirm that the code is making the
    right decisions and modifications when swapping forks.
    
    A further complication is even when the swap is allowed to proceed
    when the fork offset is different between the two inodes then value
    for the maximum number of extents the data fork can hold can be
    wrong. Make sure these are also set correctly after the swap occurs.
    Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarAlex Elder <aelder@sgi.com>
    e09f9860
xfs_dfrag.c 11.7 KB