• Brian Foster's avatar
    xfs: use the latest extent at writeback delalloc conversion time · c2b31643
    Brian Foster authored
    The writeback delalloc conversion code is racy with respect to
    changes in the currently cached file mapping outside of the current
    page. This is because the ilock is cycled between the time the
    caller originally looked up the mapping and across each real
    allocation of the provided file range. This code has collected
    various hacks over the years to help combat the symptoms of these
    races (i.e., truncate race detection, allocation into hole
    detection, etc.), but none address the fundamental problem that the
    imap may not be valid at allocation time.
    
    Rather than continue to use race detection hacks, update writeback
    delalloc conversion to a model that explicitly converts the delalloc
    extent backing the current file offset being processed. The current
    file offset is the only block we can trust to remain once the ilock
    is dropped because any operation that can remove the block
    (truncate, hole punch, etc.) must flush and discard pagecache pages
    first.
    
    Modify xfs_iomap_write_allocate() to use the xfs_bmapi_delalloc()
    mechanism to request allocation of the entire delalloc extent
    backing the current offset instead of assuming the extent passed by
    the caller is unchanged. Record the range specified by the caller
    and apply it to the resulting allocated extent so previous checks by
    the caller for COW fork overlap are not lost. Finally, overload the
    bmapi delalloc flag with the range reval flag behavior since this is
    the only use case for both.
    
    This ensures that writeback always picks up the correct
    and current extent associated with the page, regardless of races
    with other extent modifying operations. If operating on a data fork
    and the COW overlap state has changed since the ilock was cycled,
    the caller revalidates against the COW fork sequence number before
    using the imap for the next block.
    Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    c2b31643
xfs_iomap.c 32.7 KB