Re: [PATCH v2] xfs: handle nimaps=0 from xfs_bmapi_write in xfs_alloc_file_space

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

 



On Wed, Oct 11, 2023 at 07:16:26AM +0200, Christoph Hellwig wrote:
> If xfs_bmapi_write finds a delalloc extent at the requested range, it
> tries to convert the entire delalloc extent to a real allocation.
> 
> But if the allocator cannot find a single free extent large enough to
> cover the start block of the requested range, xfs_bmapi_write will
> return 0 but leave *nimaps set to 0.
> 
> In that case we simply need to keep looping with the same startoffset_fsb
> so that one of the following allocations will eventually reach the
> requested range.
> 
> Note that this could affect any caller of xfs_bmapi_write that covers
> an existing delayed allocation.  As far as I can tell we do not have
> any other such caller, though - the regular writeback path uses
> xfs_bmapi_convert_delalloc to convert delayed allocations to real ones,
> and direct I/O invalidates the page cache first.
> 
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>

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

--D

> ---
> 
> Changes since v1:
>  - update comments and the commit log
> 
>  fs/xfs/xfs_bmap_util.c | 24 +++++++++++++-----------
>  1 file changed, 13 insertions(+), 11 deletions(-)
> 
> diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
> index d85580b101ad8a..2458be8532c7aa 100644
> --- a/fs/xfs/xfs_bmap_util.c
> +++ b/fs/xfs/xfs_bmap_util.c
> @@ -814,12 +814,10 @@ xfs_alloc_file_space(
>  {
>  	xfs_mount_t		*mp = ip->i_mount;
>  	xfs_off_t		count;
> -	xfs_filblks_t		allocated_fsb;
>  	xfs_filblks_t		allocatesize_fsb;
>  	xfs_extlen_t		extsz, temp;
>  	xfs_fileoff_t		startoffset_fsb;
>  	xfs_fileoff_t		endoffset_fsb;
> -	int			nimaps;
>  	int			rt;
>  	xfs_trans_t		*tp;
>  	xfs_bmbt_irec_t		imaps[1], *imapp;
> @@ -842,7 +840,6 @@ xfs_alloc_file_space(
>  
>  	count = len;
>  	imapp = &imaps[0];
> -	nimaps = 1;
>  	startoffset_fsb	= XFS_B_TO_FSBT(mp, offset);
>  	endoffset_fsb = XFS_B_TO_FSB(mp, offset + count);
>  	allocatesize_fsb = endoffset_fsb - startoffset_fsb;
> @@ -853,6 +850,7 @@ xfs_alloc_file_space(
>  	while (allocatesize_fsb && !error) {
>  		xfs_fileoff_t	s, e;
>  		unsigned int	dblocks, rblocks, resblks;
> +		int		nimaps = 1;
>  
>  		/*
>  		 * Determine space reservations for data/realtime.
> @@ -918,15 +916,19 @@ xfs_alloc_file_space(
>  		if (error)
>  			break;
>  
> -		allocated_fsb = imapp->br_blockcount;
> -
> -		if (nimaps == 0) {
> -			error = -ENOSPC;
> -			break;
> +		/*
> +		 * If the allocator cannot find a single free extent large
> +		 * enough to cover the start block of the requested range,
> +		 * xfs_bmapi_write will return 0 but leave *nimaps set to 0.
> +		 *
> +		 * In that case we simply need to keep looping with the same
> +		 * startoffset_fsb so that one of the following allocations
> +		 * will eventually reach the requested range.
> +		 */
> +		if (nimaps) {
> +			startoffset_fsb += imapp->br_blockcount;
> +			allocatesize_fsb -= imapp->br_blockcount;
>  		}
> -
> -		startoffset_fsb += allocated_fsb;
> -		allocatesize_fsb -= allocated_fsb;
>  	}
>  
>  	return error;
> -- 
> 2.39.2
> 



[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