Commit e37b5596 authored by Yu Kuai's avatar Yu Kuai Committed by Jens Axboe
Browse files

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: default avatarYu Kuai <yukuai3@huawei.com>
Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 06d712d2
Loading
Loading
Loading
Loading
+40 −19
Original line number Diff line number Diff line
@@ -104,35 +104,56 @@ static unsigned int bio_allowed_max_sectors(const struct queue_limits *lim)
	return round_down(UINT_MAX, lim->logical_block_size) >> SECTOR_SHIFT;
}

static struct bio *bio_submit_split(struct bio *bio, int split_sectors)
/*
 * 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)
{
	if (unlikely(split_sectors < 0))
		goto error;
	struct bio *split = bio_split(bio, split_sectors, GFP_NOIO, bs);

	if (split_sectors) {
		struct bio *split;

		split = bio_split(bio, split_sectors, GFP_NOIO,
				&bio->bi_bdev->bd_disk->bio_split);
	if (IS_ERR(split)) {
			split_sectors = PTR_ERR(split);
			goto error;
		bio->bi_status = errno_to_blk_status(PTR_ERR(split));
		bio_endio(bio);
		return NULL;
	}
		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;
}
EXPORT_SYMBOL_GPL(bio_submit_split_bioset);

	return bio;
error:
static struct bio *bio_submit_split(struct bio *bio, int split_sectors)
{
	if (unlikely(split_sectors < 0)) {
		bio->bi_status = errno_to_blk_status(split_sectors);
		bio_endio(bio);
		return NULL;
	}

	if (split_sectors) {
		bio = bio_submit_split_bioset(bio, split_sectors,
				&bio->bi_bdev->bd_disk->bio_split);
		if (bio)
			bio->bi_opf |= REQ_NOMERGE;
	}

	return bio;
}

struct bio *bio_split_discard(struct bio *bio, const struct queue_limits *lim,
		unsigned *nsegs)
{
+2 −0
Original line number Diff line number Diff line
@@ -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);