Re: [PATCH 1/2] xfs: handle indlen shortage on delalloc extent merge

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Feb 03, 2017 at 01:34:24PM -0500, Brian Foster wrote:
> 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: Brian Foster <bfoster@xxxxxxxxxx>

Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>

--D

> ---
>  fs/xfs/libxfs/xfs_bmap.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index bfc00de..d2e48ed 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -2809,7 +2809,8 @@ xfs_bmap_add_extent_hole_delay(
>  		oldlen = startblockval(left.br_startblock) +
>  			startblockval(new->br_startblock) +
>  			startblockval(right.br_startblock);
> -		newlen = xfs_bmap_worst_indlen(ip, temp);
> +		newlen = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
> +					 oldlen);
>  		xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx),
>  			nullstartblock((int)newlen));
>  		trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
> @@ -2830,7 +2831,8 @@ xfs_bmap_add_extent_hole_delay(
>  		xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp);
>  		oldlen = startblockval(left.br_startblock) +
>  			startblockval(new->br_startblock);
> -		newlen = xfs_bmap_worst_indlen(ip, temp);
> +		newlen = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
> +					 oldlen);
>  		xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx),
>  			nullstartblock((int)newlen));
>  		trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
> @@ -2846,7 +2848,8 @@ xfs_bmap_add_extent_hole_delay(
>  		temp = new->br_blockcount + right.br_blockcount;
>  		oldlen = startblockval(new->br_startblock) +
>  			startblockval(right.br_startblock);
> -		newlen = xfs_bmap_worst_indlen(ip, temp);
> +		newlen = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
> +					 oldlen);
>  		xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx),
>  			new->br_startoff,
>  			nullstartblock((int)newlen), temp, right.br_state);
> -- 
> 2.7.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux