Commit bdced438 authored by Ming Lei's avatar Ming Lei Committed by Jens Axboe

block: setup bi_phys_segments after splitting

The number of bio->bi_phys_segments is always obtained
during bio splitting, so it is natural to setup it
just after bio splitting, then we can avoid to compute
nr_segment again during merge.
Reviewed-by: default avatarJeff Moyer <jmoyer@redhat.com>
Signed-off-by: default avatarMing Lei <ming.lei@canonical.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 0809e3ac
...@@ -11,13 +11,16 @@ ...@@ -11,13 +11,16 @@
static struct bio *blk_bio_discard_split(struct request_queue *q, static struct bio *blk_bio_discard_split(struct request_queue *q,
struct bio *bio, struct bio *bio,
struct bio_set *bs) struct bio_set *bs,
unsigned *nsegs)
{ {
unsigned int max_discard_sectors, granularity; unsigned int max_discard_sectors, granularity;
int alignment; int alignment;
sector_t tmp; sector_t tmp;
unsigned split_sectors; unsigned split_sectors;
*nsegs = 1;
/* Zero-sector (unknown) and one-sector granularities are the same. */ /* Zero-sector (unknown) and one-sector granularities are the same. */
granularity = max(q->limits.discard_granularity >> 9, 1U); granularity = max(q->limits.discard_granularity >> 9, 1U);
...@@ -51,8 +54,11 @@ static struct bio *blk_bio_discard_split(struct request_queue *q, ...@@ -51,8 +54,11 @@ static struct bio *blk_bio_discard_split(struct request_queue *q,
static struct bio *blk_bio_write_same_split(struct request_queue *q, static struct bio *blk_bio_write_same_split(struct request_queue *q,
struct bio *bio, struct bio *bio,
struct bio_set *bs) struct bio_set *bs,
unsigned *nsegs)
{ {
*nsegs = 1;
if (!q->limits.max_write_same_sectors) if (!q->limits.max_write_same_sectors)
return NULL; return NULL;
...@@ -64,7 +70,8 @@ static struct bio *blk_bio_write_same_split(struct request_queue *q, ...@@ -64,7 +70,8 @@ static struct bio *blk_bio_write_same_split(struct request_queue *q,
static struct bio *blk_bio_segment_split(struct request_queue *q, static struct bio *blk_bio_segment_split(struct request_queue *q,
struct bio *bio, struct bio *bio,
struct bio_set *bs) struct bio_set *bs,
unsigned *segs)
{ {
struct bio_vec bv, bvprv, *bvprvp = NULL; struct bio_vec bv, bvprv, *bvprvp = NULL;
struct bvec_iter iter; struct bvec_iter iter;
...@@ -106,22 +113,30 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, ...@@ -106,22 +113,30 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
sectors += bv.bv_len >> 9; sectors += bv.bv_len >> 9;
} }
*segs = nsegs;
return NULL; return NULL;
split: split:
*segs = nsegs;
return bio_split(bio, sectors, GFP_NOIO, bs); return bio_split(bio, sectors, GFP_NOIO, bs);
} }
void blk_queue_split(struct request_queue *q, struct bio **bio, void blk_queue_split(struct request_queue *q, struct bio **bio,
struct bio_set *bs) struct bio_set *bs)
{ {
struct bio *split; struct bio *split, *res;
unsigned nsegs;
if ((*bio)->bi_rw & REQ_DISCARD) if ((*bio)->bi_rw & REQ_DISCARD)
split = blk_bio_discard_split(q, *bio, bs); split = blk_bio_discard_split(q, *bio, bs, &nsegs);
else if ((*bio)->bi_rw & REQ_WRITE_SAME) else if ((*bio)->bi_rw & REQ_WRITE_SAME)
split = blk_bio_write_same_split(q, *bio, bs); split = blk_bio_write_same_split(q, *bio, bs, &nsegs);
else else
split = blk_bio_segment_split(q, *bio, q->bio_split); split = blk_bio_segment_split(q, *bio, q->bio_split, &nsegs);
/* physical segments can be figured out during splitting */
res = split ? split : *bio;
res->bi_phys_segments = nsegs;
bio_set_flag(res, BIO_SEG_VALID);
if (split) { if (split) {
bio_chain(split, *bio); bio_chain(split, *bio);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment