• Brian Foster's avatar
    xfs: log local to remote symlink conversions correctly on v5 supers · b7cdc66b
    Brian Foster authored
    A local format symlink inode is converted to extent format when an
    extended attribute is set on an inode as part of the attribute fork
    creation. This means a block is allocated, the local symlink target name
    is copied to the block and the block is logged. Currently,
    xfs_bmap_local_to_extents() handles logging the remote block data based
    on the size of the data fork prior to the conversion. This is not
    correct on v5 superblock filesystems, which add an additional header to
    remote symlink blocks that is nonexistent in local format inodes.
    
    As a result, the full length of the remote symlink block content is not
    logged. This can lead to corruption should a crash occur and log
    recovery replay this transaction.
    
    Since a callout is already used to initialize the new remote symlink
    block, update the local-to-extents conversion mechanism to make the
    callout also responsible for logging the block. It is already required
    to set the log buffer type and format the block appropriately based on
    the superblock version. This ensures the remote symlink is always logged
    correctly. Note that xfs_bmap_local_to_extents() is only called for
    symlinks so there are no other callouts that require modification.
    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>
    b7cdc66b
xfs_bmap.c 170 KB