Re: [PATCH 01/17] block: export bio_split_rw

Qu Wenruo
2022-09-01T08:55:06Z

On 2022/9/1 15:42, Christoph Hellwig wrote:
> bio_split_rw can be used by file systems to split and incoming write
> bio into multiple bios fitting the hardware limit for use as ZONE_APPEND
> bios. Export it for initial use in btrfs.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> block/blk-merge.c | 3 ++-
> include/linux/bio.h | 4 ++++
> 2 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/block/blk-merge.c b/block/blk-merge.c
> index ff04e9290715a..e68295462977b 100644
> --- a/block/blk-merge.c
> +++ b/block/blk-merge.c
> @@ -267,7 +267,7 @@ static bool bvec_split_segs(struct queue_limits *lim, const struct bio_vec *bv,
> * responsible for ensuring that @bs is only destroyed after processing of the
> * split bio has finished.
> */
> -static struct bio *bio_split_rw(struct bio *bio, struct queue_limits *lim,
> +struct bio *bio_split_rw(struct bio *bio, struct queue_limits *lim,

I found the queue_limits structure pretty scary, while we only have very
limited members used in this case:

- lim->virt_boundary_mask
Used in bvec_gap_to_prev()

- lim->max_segments

- lim->seg_boundary_mask
- lim->max_segment_size
Used in bvec_split_segs()

- lim->logical_block_size

Not familiar with block layer, thus I'm wondering do btrfs really need a
full queue_limits structure to call bio_split_rw().

Or can we have a simplified wrapper?

IIRC inside btrfs we only need two cases for bio split:

- Split for stripe boundary

- Split for OE/zoned boundary

Thanks,
Qu

> unsigned *segs, struct bio_set *bs, unsigned max_bytes)
> {
> struct bio_vec bv, bvprv, *bvprvp = NULL;
> @@ -317,6 +317,7 @@ static struct bio *bio_split_rw(struct bio *bio, struct queue_limits *lim,
> bio_clear_polled(bio);
> return bio_split(bio, bytes >> SECTOR_SHIFT, GFP_NOIO, bs);
> }
> +EXPORT_SYMBOL_GPL(bio_split_rw);
>
> /**
> * __bio_split_to_limits - split a bio to fit the queue limits
> diff --git a/include/linux/bio.h b/include/linux/bio.h
> index ca22b06700a94..46890f8235401 100644
> --- a/include/linux/bio.h
> +++ b/include/linux/bio.h
> @@ -12,6 +12,8 @@
>
> #define BIO_MAX_VECS 256U
>
> +struct queue_limits;
> +
> static inline unsigned int bio_max_segs(unsigned int nr_segs)
> {
> return min(nr_segs, BIO_MAX_VECS);
> @@ -375,6 +377,8 @@ static inline void bip_set_seed(struct bio_integrity_payload *bip,
> void bio_trim(struct bio *bio, sector_t offset, sector_t size);
> extern struct bio *bio_split(struct bio *bio, int sectors,
> gfp_t gfp, struct bio_set *bs);
> +struct bio *bio_split_rw(struct bio *bio, struct queue_limits *lim,
> + unsigned *segs, struct bio_set *bs, unsigned max_bytes);
>
> /**
> * bio_next_split - get next @sectors from a bio, splitting if necessary