Re: [PATCH 1/9] xfs: split xfs_bmap_btalloc_at_eof()

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

 



On Wed, Oct 04, 2023 at 11:19:35AM +1100, Dave Chinner wrote:
> From: Dave Chinner <dchinner@xxxxxxxxxx>
> 
> This function is really implementing two policies. The first is
> trying to create contiguous extents at file extension. Failing that,
> it attempts to perform aligned allocation. These are really two
> separate policies, and it is further complicated by filestream
> allocation having different aligned allocation constraints than
> the normal bmap allocation.
> 
> Split xfs_bmap_btalloc_at_eof() into two parts so we can start to
> align the two different allocator policies more closely.
> 
> Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
> ---
>  fs/xfs/libxfs/xfs_bmap.c | 147 +++++++++++++++++++++------------------
>  1 file changed, 80 insertions(+), 67 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index 30c931b38853..e14671414afb 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -3451,81 +3451,81 @@ xfs_bmap_exact_minlen_extent_alloc(
>  
>  #endif
>  
> -/*
> - * If we are not low on available data blocks and we are allocating at
> - * EOF, optimise allocation for contiguous file extension and/or stripe
> - * alignment of the new extent.
> - *
> - * NOTE: ap->aeof is only set if the allocation length is >= the
> - * stripe unit and the allocation offset is at the end of file.
> - */
> + /*
> + * Attempt contiguous allocation for file extension.
> +  */
> + static int
> + xfs_bmap_btalloc_at_eof(
> +	struct xfs_bmalloca	*ap,
> +	struct xfs_alloc_arg	*args,
> +	xfs_extlen_t		blen,
> +	int			stripe_align)
> +{
> +	struct xfs_mount	*mp = args->mp;
> +	struct xfs_perag        *caller_pag = args->pag;
> +	xfs_extlen_t		nextminlen = 0;
> +	int			error;
> +
> +	/*
> +	 * Compute the minlen+alignment for the next case.  Set slop so
> +	 * that the value of minlen+alignment+slop doesn't go up between
> +	 * the calls.
> +	 */
> +	args->alignment = 1;
> +	if (blen > stripe_align && blen <= args->maxlen)
> +		nextminlen = blen - stripe_align;
> +	else
> +		nextminlen = args->minlen;
> +	if (nextminlen + stripe_align > args->minlen + 1)
> +		args->minalignslop = nextminlen + stripe_align -
> +				args->minlen - 1;
> +	else
> +		args->minalignslop = 0;
> +
> +	if (!caller_pag)
> +		args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno));
> +	error = xfs_alloc_vextent_exact_bno(args, ap->blkno);
> +	if (!caller_pag) {
> +		xfs_perag_put(args->pag);
> +		args->pag = NULL;

Splitting these two if cases into two less ambitious functions makes it
easier for me to regrok what this code was doing.  Thank you,

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

--D

> +	}
> +	if (error)
> +		return error;
> +
> +	if (args->fsbno != NULLFSBLOCK)
> +		return 0;
> +	/*
> +	 * Exact allocation failed. Reset to try an aligned allocation
> +	 * according to the original allocation specification.
> +	 */
> +	args->minlen = nextminlen;
> +	return 0;
> +}
> +
>  static int
> -xfs_bmap_btalloc_at_eof(
> +xfs_bmap_btalloc_aligned(
>  	struct xfs_bmalloca	*ap,
>  	struct xfs_alloc_arg	*args,
>  	xfs_extlen_t		blen,
>  	int			stripe_align,
>  	bool			ag_only)
>  {
> -	struct xfs_mount	*mp = args->mp;
> -	struct xfs_perag	*caller_pag = args->pag;
> +	struct xfs_perag        *caller_pag = args->pag;
>  	int			error;
>  
>  	/*
> -	 * If there are already extents in the file, try an exact EOF block
> -	 * allocation to extend the file as a contiguous extent. If that fails,
> -	 * or it's the first allocation in a file, just try for a stripe aligned
> -	 * allocation.
> +	 * If we failed an exact EOF allocation already, stripe
> +	 * alignment will have already been taken into account in
> +	 * args->minlen. Hence we only adjust minlen to try to preserve
> +	 * alignment if no slop has been reserved for alignment
>  	 */
> -	if (ap->offset) {
> -		xfs_extlen_t	nextminlen = 0;
> -
> -		/*
> -		 * Compute the minlen+alignment for the next case.  Set slop so
> -		 * that the value of minlen+alignment+slop doesn't go up between
> -		 * the calls.
> -		 */
> -		args->alignment = 1;
> -		if (blen > stripe_align && blen <= args->maxlen)
> -			nextminlen = blen - stripe_align;
> -		else
> -			nextminlen = args->minlen;
> -		if (nextminlen + stripe_align > args->minlen + 1)
> -			args->minalignslop = nextminlen + stripe_align -
> -					args->minlen - 1;
> -		else
> -			args->minalignslop = 0;
> -
> -		if (!caller_pag)
> -			args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno));
> -		error = xfs_alloc_vextent_exact_bno(args, ap->blkno);
> -		if (!caller_pag) {
> -			xfs_perag_put(args->pag);
> -			args->pag = NULL;
> -		}
> -		if (error)
> -			return error;
> -
> -		if (args->fsbno != NULLFSBLOCK)
> -			return 0;
> -		/*
> -		 * Exact allocation failed. Reset to try an aligned allocation
> -		 * according to the original allocation specification.
> -		 */
> -		args->alignment = stripe_align;
> -		args->minlen = nextminlen;
> -		args->minalignslop = 0;
> -	} else {
> -		/*
> -		 * Adjust minlen to try and preserve alignment if we
> -		 * can't guarantee an aligned maxlen extent.
> -		 */
> -		args->alignment = stripe_align;
> -		if (blen > args->alignment &&
> -		    blen <= args->maxlen + args->alignment)
> -			args->minlen = blen - args->alignment;
> -		args->minalignslop = 0;
> +	if (args->minalignslop == 0) {
> +		if (blen > stripe_align &&
> +		    blen <= args->maxlen + stripe_align)
> +			args->minlen = blen - stripe_align;
>  	}
> +	args->alignment = stripe_align;
> +	args->minalignslop = 0;
>  
>  	if (ag_only) {
>  		error = xfs_alloc_vextent_near_bno(args, ap->blkno);
> @@ -3612,8 +3612,14 @@ xfs_bmap_btalloc_filestreams(
>  	}
>  
>  	args->minlen = xfs_bmap_select_minlen(ap, args, blen);
> +	if (ap->aeof && ap->offset)
> +		error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align);
> +
> +	if (error || args->fsbno != NULLFSBLOCK)
> +		goto out_low_space;
> +
>  	if (ap->aeof)
> -		error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align,
> +		error = xfs_bmap_btalloc_aligned(ap, args, blen, stripe_align,
>  				true);
>  
>  	if (!error && args->fsbno == NULLFSBLOCK)
> @@ -3662,13 +3668,20 @@ xfs_bmap_btalloc_best_length(
>  	 * optimal or even aligned allocations in this case, so don't waste time
>  	 * trying.
>  	 */
> -	if (ap->aeof && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) {
> -		error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align,
> -				false);
> +	if (ap->aeof && ap->offset && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) {
> +		error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align);
>  		if (error || args->fsbno != NULLFSBLOCK)
>  			return error;
>  	}
>  
> +	/* attempt aligned allocation for new EOF extents */
> +	if (ap->aeof)
> +		error = xfs_bmap_btalloc_aligned(ap, args, blen, stripe_align,
> +				false);
> +	if (error || args->fsbno != NULLFSBLOCK)
> +		return error;
> +
> +	/* attempt unaligned allocation */
>  	error = xfs_alloc_vextent_start_ag(args, ap->blkno);
>  	if (error || args->fsbno != NULLFSBLOCK)
>  		return error;
> -- 
> 2.40.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