Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

block: factor out a helper bio_submit_split_bioset()

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>

authored by

Yu Kuai and committed by
Jens Axboe
e37b5596 06d712d2

+42 -19
+40 -19
block/blk-merge.c
··· 104 104 return round_down(UINT_MAX, lim->logical_block_size) >> SECTOR_SHIFT; 105 105 } 106 106 107 + /* 108 + * bio_submit_split_bioset - Submit a bio, splitting it at a designated sector 109 + * @bio: the original bio to be submitted and split 110 + * @split_sectors: the sector count at which to split 111 + * @bs: the bio set used for allocating the new split bio 112 + * 113 + * The original bio is modified to contain the remaining sectors and submitted. 114 + * The caller is responsible for submitting the returned bio. 115 + * 116 + * If succeed, the newly allocated bio representing the initial part will be 117 + * returned, on failure NULL will be returned and original bio will fail. 118 + */ 119 + struct bio *bio_submit_split_bioset(struct bio *bio, unsigned int split_sectors, 120 + struct bio_set *bs) 121 + { 122 + struct bio *split = bio_split(bio, split_sectors, GFP_NOIO, bs); 123 + 124 + if (IS_ERR(split)) { 125 + bio->bi_status = errno_to_blk_status(PTR_ERR(split)); 126 + bio_endio(bio); 127 + return NULL; 128 + } 129 + 130 + bio_chain(split, bio); 131 + trace_block_split(split, bio->bi_iter.bi_sector); 132 + WARN_ON_ONCE(bio_zone_write_plugging(bio)); 133 + submit_bio_noacct(bio); 134 + 135 + return split; 136 + } 137 + EXPORT_SYMBOL_GPL(bio_submit_split_bioset); 138 + 107 139 static struct bio *bio_submit_split(struct bio *bio, int split_sectors) 108 140 { 109 - if (unlikely(split_sectors < 0)) 110 - goto error; 141 + if (unlikely(split_sectors < 0)) { 142 + bio->bi_status = errno_to_blk_status(split_sectors); 143 + bio_endio(bio); 144 + return NULL; 145 + } 111 146 112 147 if (split_sectors) { 113 - struct bio *split; 114 - 115 - split = bio_split(bio, split_sectors, GFP_NOIO, 148 + bio = bio_submit_split_bioset(bio, split_sectors, 116 149 &bio->bi_bdev->bd_disk->bio_split); 117 - if (IS_ERR(split)) { 118 - split_sectors = PTR_ERR(split); 119 - goto error; 120 - } 121 - split->bi_opf |= REQ_NOMERGE; 122 - bio_chain(split, bio); 123 - trace_block_split(split, bio->bi_iter.bi_sector); 124 - WARN_ON_ONCE(bio_zone_write_plugging(bio)); 125 - submit_bio_noacct(bio); 126 - return split; 150 + if (bio) 151 + bio->bi_opf |= REQ_NOMERGE; 127 152 } 128 153 129 154 return bio; 130 - error: 131 - bio->bi_status = errno_to_blk_status(split_sectors); 132 - bio_endio(bio); 133 - return NULL; 134 155 } 135 156 136 157 struct bio *bio_split_discard(struct bio *bio, const struct queue_limits *lim,
+2
include/linux/blkdev.h
··· 1000 1000 extern void blk_unregister_queue(struct gendisk *disk); 1001 1001 void submit_bio_noacct(struct bio *bio); 1002 1002 struct bio *bio_split_to_limits(struct bio *bio); 1003 + struct bio *bio_submit_split_bioset(struct bio *bio, unsigned int split_sectors, 1004 + struct bio_set *bs); 1003 1005 1004 1006 extern int blk_lld_busy(struct request_queue *q); 1005 1007 extern int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags);