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@xxxxxx> --- 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