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: Jeff Moyer <jmoyer@redhat.com> Signed-off-by: Ming Lei <ming.lei@canonical.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
parent
0809e3ac62
commit
bdced438ac
|
@ -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,
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
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 @@ new_segment:
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue