• Brian Foster's avatar
    xfs: handle indlen shortage on delalloc extent merge · 0e339ef8
    Brian Foster authored
    When a delalloc extent is created, it can be merged with pre-existing,
    contiguous, delalloc extents. When this occurs,
    xfs_bmap_add_extent_hole_delay() merges the extents along with the
    associated indirect block reservations. The expectation here is that the
    combined worst case indlen reservation is always less than or equal to
    the indlen reservation for the individual extents.
    
    This is not always the case, however, as existing extents can less than
    the expected indlen reservation if the extent was previously split due
    to a hole punch. If a new extent merges with such an extent, the total
    indlen requirement may be larger than the sum of the indlen reservations
    held by both extents.
    
    xfs_bmap_add_extent_hole_delay() assumes that the worst case indlen
    reservation is always available and assigns it to the merged extent
    without consideration for the indlen held by the pre-existing extent. As
    a result, the subsequent xfs_mod_fdblocks() call can attempt an
    unintentional allocation rather than a free (indicated by an ASSERT()
    failure). Further, if the allocation happens to fail in this context,
    the failure goes unhandled and creates a filesystem wide block
    accounting inconsistency.
    
    Fix xfs_bmap_add_extent_hole_delay() to function as designed. Cap the
    indlen reservation assigned to the merged extent to the sum of the
    indlen reservations held by each of the individual extents.
    Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
    Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    0e339ef8
xfs_bmap.c 185 KB