Re: [PATCH v2 1/2] xfs: cap longest free extent to maximum allocatable

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

 



On Mon, Oct 21, 2019 at 08:13:21AM -0400, Brian Foster wrote:
> From: Dave Chinner <dchinner@xxxxxxxxxx>
> 
> Cap longest extent to the largest we can allocate based on limits
> calculated at mount time. Dynamic state (such as finobt blocks)
> can result in the longest free extent exceeding the size we can
> allocate, and that results in failure to align full AG allocations
> when the AG is empty.
> 
> Result:
> 
> xfs_io-4413  [003]   426.412459: xfs_alloc_vextent_loopfailed: dev 8:96 agno 0 agbno 32 minlen 243968 maxlen 244000 mod 0 prod 1 minleft 1 total 262148 alignment 32 minalignslop 0 len 0 type NEAR_BNO otype START_BNO wasdel 0 wasfromfl 0 resv 0 datatype 0x5 firstblock 0xffffffffffffffff
> 
> minlen and maxlen are now separated by the alignment size, and
> allocation fails because args.total > free space in the AG.
> 
> [bfoster: Added xfs_bmap_btalloc() changes.]
> 
> Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
> Signed-off-by: Carlos Maiolino <cmaiolino@xxxxxxxxxx>
> Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx>

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

--D

> ---
>  fs/xfs/libxfs/xfs_alloc.c |  3 ++-
>  fs/xfs/libxfs/xfs_bmap.c  | 18 +++++++++---------
>  2 files changed, 11 insertions(+), 10 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index 533b04aaf6f6..9dead25d2e70 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -1989,7 +1989,8 @@ xfs_alloc_longest_free_extent(
>  	 * reservations and AGFL rules in place, we can return this extent.
>  	 */
>  	if (pag->pagf_longest > delta)
> -		return pag->pagf_longest - delta;
> +		return min_t(xfs_extlen_t, pag->pag_mount->m_ag_max_usable,
> +				pag->pagf_longest - delta);
>  
>  	/* Otherwise, let the caller try for 1 block if there's space. */
>  	return pag->pagf_flcount > 0 || pag->pagf_longest > 0;
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index 02469d59c787..c118577deaa9 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -3500,13 +3500,11 @@ xfs_bmap_btalloc(
>  			args.mod = args.prod - args.mod;
>  	}
>  	/*
> -	 * If we are not low on available data blocks, and the
> -	 * underlying logical volume manager is a stripe, and
> -	 * the file offset is zero then try to allocate data
> -	 * blocks on stripe unit boundary.
> -	 * NOTE: ap->aeof is only set if the allocation length
> -	 * is >= the stripe unit and the allocation offset is
> -	 * at the end of file.
> +	 * If we are not low on available data blocks, and the underlying
> +	 * logical volume manager is a stripe, and the file offset is zero then
> +	 * try to allocate data blocks on stripe unit boundary. NOTE: ap->aeof
> +	 * is only set if the allocation length is >= the stripe unit and the
> +	 * allocation offset is at the end of file.
>  	 */
>  	if (!(ap->tp->t_flags & XFS_TRANS_LOWMODE) && ap->aeof) {
>  		if (!ap->offset) {
> @@ -3514,9 +3512,11 @@ xfs_bmap_btalloc(
>  			atype = args.type;
>  			isaligned = 1;
>  			/*
> -			 * Adjust for alignment
> +			 * Adjust minlen to try and preserve alignment if we
> +			 * can't guarantee an aligned maxlen extent.
>  			 */
> -			if (blen > args.alignment && blen <= args.maxlen)
> +			if (blen > args.alignment &&
> +			    blen <= args.maxlen + args.alignment)
>  				args.minlen = blen - args.alignment;
>  			args.minalignslop = 0;
>  		} else {
> -- 
> 2.20.1
> 



[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