Re: [PATCH 15/19] xfs: simplify xfs_buf_submit_bio

"Darrick J. Wong" <[email protected]>
Newsgroups org.kernel.vger.linux-bcache,dev.linux.lists.dm-devel,dev.linux.lists.gfs2,org.kernel.vger.linux-block,org.kernel.vger.linux-btrfs,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-pm,org.kernel.vger.linux-xfs
Message-ID <20250501195103.GD25675@frogsfrogsfrogs>
On Wed, Apr 30, 2025 at 04:21:45PM -0500, Christoph Hellwig wrote:
> Convert the __bio_add_page(..., virt_to_page(), ...) pattern to the
> bio_add_virt_nofail helper implementing it and use bio_add_vmalloc
> to insulate xfs from the details of adding vmalloc memory to a bio.
> 
> Signed-off-by: Christoph Hellwig <[email protected]>
> ---
>  fs/xfs/xfs_buf.c | 43 ++++++++-----------------------------------
>  1 file changed, 8 insertions(+), 35 deletions(-)
> 
> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
> index 1a2b3f06fa71..f2d00774a84f 100644
> --- a/fs/xfs/xfs_buf.c
> +++ b/fs/xfs/xfs_buf.c
> @@ -1333,45 +1333,18 @@ static void
>  xfs_buf_submit_bio(
>  	struct xfs_buf		*bp)
>  {
> +	unsigned int		len = BBTOB(bp->b_length);
> +	unsigned int		nr_vecs = bio_add_max_vecs(bp->b_addr, len);
>  	unsigned int		map = 0;
>  	struct blk_plug		plug;
>  	struct bio		*bio;
>  
> -	if (is_vmalloc_addr(bp->b_addr)) {
> -		unsigned int	size = BBTOB(bp->b_length);
> -		unsigned int	alloc_size = roundup(size, PAGE_SIZE);
> -		void		*data = bp->b_addr;
> -
> -		bio = bio_alloc(bp->b_target->bt_bdev, alloc_size >> PAGE_SHIFT,
> -				xfs_buf_bio_op(bp), GFP_NOIO);
> -
> -		do {
> -			unsigned int	len = min(size, PAGE_SIZE);
> -
> -			ASSERT(offset_in_page(data) == 0);
> -			__bio_add_page(bio, vmalloc_to_page(data), len, 0);
> -			data += len;
> -			size -= len;
> -		} while (size);
> -
> -		flush_kernel_vmap_range(bp->b_addr, alloc_size);
> -	} else {
> -		/*
> -		 * Single folio or slab allocation.  Must be contiguous and thus
> -		 * only a single bvec is needed.
> -		 *
> -		 * This uses the page based bio add helper for now as that is
> -		 * the lowest common denominator between folios and slab
> -		 * allocations.  To be replaced with a better block layer
> -		 * helper soon (hopefully).
> -		 */
> -		bio = bio_alloc(bp->b_target->bt_bdev, 1, xfs_buf_bio_op(bp),
> -				GFP_NOIO);
> -		__bio_add_page(bio, virt_to_page(bp->b_addr),
> -				BBTOB(bp->b_length),
> -				offset_in_page(bp->b_addr));
> -	}
> -
> +	bio = bio_alloc(bp->b_target->bt_bdev, nr_vecs, xfs_buf_bio_op(bp),
> +			GFP_NOIO);
> +	if (is_vmalloc_addr(bp->b_addr))
> +		bio_add_vmalloc(bio, bp->b_addr, len);

I wonder, do we need a debug assertion on the return value?  AFAICT,
bio_add_max_vecs should result in a bio that's big enough to handle the
vmalloc area, but those could be famous last words. :P

Other than that, the code is much cleaner than before. :)

--D

> +	else
> +		bio_add_virt_nofail(bio, bp->b_addr, len);
>  	bio->bi_private = bp;
>  	bio->bi_end_io = xfs_buf_bio_end_io;
>  
> -- 
> 2.47.2
> 
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.