diff options
author | Ming Lei <ming.lei@canonical.com> | 2014-10-09 17:17:35 +0200 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-10-09 21:11:44 +0200 |
commit | 764f612c6c3c231b9c12cfae7c328ccc9c453258 (patch) | |
tree | f07edb7a3ed883c1ac66e8ede65a9aa6681cb378 | |
parent | block: fix alignment_offset math that assumes io_min is a power-of-2 (diff) | |
download | linux-764f612c6c3c231b9c12cfae7c328ccc9c453258.tar.xz linux-764f612c6c3c231b9c12cfae7c328ccc9c453258.zip |
blk-merge: don't compute bi_phys_segments from bi_vcnt for cloned bio
It isn't correct to figure out req->bi_phys_segments from bio->bi_vcnt
if the bio is cloned.
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Tested-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | block/blk-merge.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c index f71bad35b4cc..ba99351c0f58 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -97,14 +97,18 @@ void blk_recalc_rq_segments(struct request *rq) void blk_recount_segments(struct request_queue *q, struct bio *bio) { - if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) && + bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE, + &q->queue_flags); + + if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) && bio->bi_vcnt < queue_max_segments(q)) bio->bi_phys_segments = bio->bi_vcnt; else { struct bio *nxt = bio->bi_next; bio->bi_next = NULL; - bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false); + bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, + no_sg_merge); bio->bi_next = nxt; } |