]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
block: factor out a helper bio_submit_split_bioset()
authorYu Kuai <yukuai3@huawei.com>
Wed, 10 Sep 2025 06:30:46 +0000 (14:30 +0800)
committerJens Axboe <axboe@kernel.dk>
Wed, 10 Sep 2025 11:23:45 +0000 (05:23 -0600)
No functional changes are intended, some drivers like mdraid will split
bio by internal processing, prepare to unify bio split codes.

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-merge.c
include/linux/blkdev.h

index 354a3070e6a189b9f62f252c1e737c1e8661b56d..f680ccf8186456778ffcb11534ba59d27b3c8a8a 100644 (file)
@@ -104,33 +104,54 @@ static unsigned int bio_allowed_max_sectors(const struct queue_limits *lim)
        return round_down(UINT_MAX, lim->logical_block_size) >> SECTOR_SHIFT;
 }
 
+/*
+ * bio_submit_split_bioset - Submit a bio, splitting it at a designated sector
+ * @bio:               the original bio to be submitted and split
+ * @split_sectors:     the sector count at which to split
+ * @bs:                        the bio set used for allocating the new split bio
+ *
+ * The original bio is modified to contain the remaining sectors and submitted.
+ * The caller is responsible for submitting the returned bio.
+ *
+ * If succeed, the newly allocated bio representing the initial part will be
+ * returned, on failure NULL will be returned and original bio will fail.
+ */
+struct bio *bio_submit_split_bioset(struct bio *bio, unsigned int split_sectors,
+                                   struct bio_set *bs)
+{
+       struct bio *split = bio_split(bio, split_sectors, GFP_NOIO, bs);
+
+       if (IS_ERR(split)) {
+               bio->bi_status = errno_to_blk_status(PTR_ERR(split));
+               bio_endio(bio);
+               return NULL;
+       }
+
+       bio_chain(split, bio);
+       trace_block_split(split, bio->bi_iter.bi_sector);
+       WARN_ON_ONCE(bio_zone_write_plugging(bio));
+       submit_bio_noacct(bio);
+
+       return split;
+}
+EXPORT_SYMBOL_GPL(bio_submit_split_bioset);
+
 static struct bio *bio_submit_split(struct bio *bio, int split_sectors)
 {
-       if (unlikely(split_sectors < 0))
-               goto error;
+       if (unlikely(split_sectors < 0)) {
+               bio->bi_status = errno_to_blk_status(split_sectors);
+               bio_endio(bio);
+               return NULL;
+       }
 
        if (split_sectors) {
-               struct bio *split;
-
-               split = bio_split(bio, split_sectors, GFP_NOIO,
+               bio = bio_submit_split_bioset(bio, split_sectors,
                                &bio->bi_bdev->bd_disk->bio_split);
-               if (IS_ERR(split)) {
-                       split_sectors = PTR_ERR(split);
-                       goto error;
-               }
-               split->bi_opf |= REQ_NOMERGE;
-               bio_chain(split, bio);
-               trace_block_split(split, bio->bi_iter.bi_sector);
-               WARN_ON_ONCE(bio_zone_write_plugging(bio));
-               submit_bio_noacct(bio);
-               return split;
+               if (bio)
+                       bio->bi_opf |= REQ_NOMERGE;
        }
 
        return bio;
-error:
-       bio->bi_status = errno_to_blk_status(split_sectors);
-       bio_endio(bio);
-       return NULL;
 }
 
 struct bio *bio_split_discard(struct bio *bio, const struct queue_limits *lim,
index 7c542b1851fa863d64b732c1425059a40d3c8718..066e5309bd456ff7b56179b546bacd15338b439e 100644 (file)
@@ -1000,6 +1000,8 @@ extern int blk_register_queue(struct gendisk *disk);
 extern void blk_unregister_queue(struct gendisk *disk);
 void submit_bio_noacct(struct bio *bio);
 struct bio *bio_split_to_limits(struct bio *bio);
+struct bio *bio_submit_split_bioset(struct bio *bio, unsigned int split_sectors,
+                                   struct bio_set *bs);
 
 extern int blk_lld_busy(struct request_queue *q);
 extern int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags);