Re: [PATCH 06/10] xfs: fix bmap minleft calculation

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

 



On Thu, Apr 13, 2017 at 10:05:13AM +0200, Christoph Hellwig wrote:
> We need to set a proper minleft value even if we didn't do a previous
> allocation in the transaction, as we can't switch to a different AG
> after allocating the data extent.
> 

Hmm, the code currently does set minleft if we haven't done a previous
allocation (firstblock == NULLFSBLOCK). Do you mean "even if we have
done a previous allocation?"

The code seems Ok, but we also currently reserve enough blocks for a
full btree split in a write transaction and afaict only allocate a
single extent per-transaction. The current code expects to select an AG
with those additional blocks available and then not if a subsequent
allocation occurs (by setting minleft = 0), presumably because the check
was already made. So I'm wondering if this fixes a problem that has been
observed or is just cleaning up the code..?

Brian

> Signed-off-by: Christoph Hellwig <hch@xxxxxx>
> ---
>  fs/xfs/libxfs/xfs_bmap.c | 27 +++++++++++++++++----------
>  fs/xfs/libxfs/xfs_bmap.h |  1 -
>  2 files changed, 17 insertions(+), 11 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index 53f1386b1868..6faefa342748 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -3570,6 +3570,22 @@ xfs_bmap_btalloc_filestreams(
>  	return 0;
>  }
>  
> +/*
> + * Return the minimum number of blocks required for the bmap btree manipulation
> + * after adding a single extent.
> + */
> +static xfs_extlen_t
> +xfs_bmap_minleft(
> +	struct xfs_bmalloca	*ap)
> +{
> +	int			whichfork = xfs_bmapi_whichfork(ap->flags);
> +	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ap->ip, whichfork);
> +
> +	if (XFS_IFORK_FORMAT(ap->ip, whichfork) == XFS_DINODE_FMT_BTREE)
> +		return be16_to_cpu(ifp->if_broot->bb_level) + 1;
> +	return 1;
> +}
> +
>  STATIC int
>  xfs_bmap_btalloc(
>  	struct xfs_bmalloca	*ap)	/* bmap alloc argument struct */
> @@ -3738,7 +3754,7 @@ xfs_bmap_btalloc(
>  		args.alignment = 1;
>  		args.minalignslop = 0;
>  	}
> -	args.minleft = ap->minleft;
> +	args.minleft = xfs_bmap_minleft(ap);
>  	args.wasdel = ap->wasdel;
>  	args.resv = XFS_AG_RESV_NONE;
>  	args.datatype = ap->datatype;
> @@ -4493,15 +4509,6 @@ xfs_bmapi_write(
>  
>  	XFS_STATS_INC(mp, xs_blk_mapw);
>  
> -	if (*firstblock == NULLFSBLOCK) {
> -		if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
> -			bma.minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
> -		else
> -			bma.minleft = 1;
> -	} else {
> -		bma.minleft = 0;
> -	}
> -
>  	if (!(ifp->if_flags & XFS_IFEXTENTS)) {
>  		error = xfs_iread_extents(tp, ip, whichfork);
>  		if (error)
> diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
> index d9e0b1db4cdb..36a7f36f5f38 100644
> --- a/fs/xfs/libxfs/xfs_bmap.h
> +++ b/fs/xfs/libxfs/xfs_bmap.h
> @@ -48,7 +48,6 @@ struct xfs_bmalloca {
>  	int			logflags;/* flags for transaction logging */
>  
>  	xfs_extlen_t		total;	/* total blocks needed for xaction */
> -	xfs_extlen_t		minleft; /* amount must be left after alloc */
>  	bool			eof;	/* set if allocating past last extent */
>  	bool			wasdel;	/* replacing a delayed allocation */
>  	bool			aeof;	/* allocated space at eof */
> -- 
> 2.11.0
> 
> --
> 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