• Brian Foster's avatar
    xfs: fix indlen accounting error on partial delalloc conversion · 0daaecac
    Brian Foster authored
    The delalloc -> real block conversion path uses an incorrect
    calculation in the case where the middle part of a delalloc extent
    is being converted. This is documented as a rare situation because
    XFS generally attempts to maximize contiguity by converting as much
    of a delalloc extent as possible.
    
    If this situation does occur, the indlen reservation for the two new
    delalloc extents left behind by the conversion of the middle range
    is calculated and compared with the original reservation. If more
    blocks are required, the delta is allocated from the global block
    pool. This delta value can be characterized as the difference
    between the new total requirement (temp + temp2) and the currently
    available reservation minus those blocks that have already been
    allocated (startblockval(PREV.br_startblock) - allocated).
    
    The problem is that the current code does not account for previously
    allocated blocks correctly. It subtracts the current allocation
    count from the (new - old) delta rather than the old indlen
    reservation. This means that more indlen blocks than have been
    allocated end up stashed in the remaining extents and free space
    accounting is broken as a result.
    
    Fix up the calculation to subtract the allocated block count from
    the original extent indlen and thus correctly allocate the
    reservation delta based on the difference between the new total
    requirement and the unused blocks from the original reservation.
    Also remove a bogus assert that contradicts the fact that the new
    indlen reservation can be larger than the original indlen
    reservation.
    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>
    0daaecac
xfs_bmap.c 184 KB