aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorMing Lei <ming.lei@canonical.com>2014-10-09 11:17:35 -0400
committerJens Axboe <axboe@fb.com>2014-10-09 15:11:44 -0400
commit764f612c6c3c231b9c12cfae7c328ccc9c453258 (patch)
treef07edb7a3ed883c1ac66e8ede65a9aa6681cb378 /block
parentb8839b8c55f3fdd60dc36abcda7e0266aff7985c (diff)
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>
Diffstat (limited to 'block')
-rw-r--r--block/blk-merge.c8
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)
97 97
98void blk_recount_segments(struct request_queue *q, struct bio *bio) 98void blk_recount_segments(struct request_queue *q, struct bio *bio)
99{ 99{
100 if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) && 100 bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE,
101 &q->queue_flags);
102
103 if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) &&
101 bio->bi_vcnt < queue_max_segments(q)) 104 bio->bi_vcnt < queue_max_segments(q))
102 bio->bi_phys_segments = bio->bi_vcnt; 105 bio->bi_phys_segments = bio->bi_vcnt;
103 else { 106 else {
104 struct bio *nxt = bio->bi_next; 107 struct bio *nxt = bio->bi_next;
105 108
106 bio->bi_next = NULL; 109 bio->bi_next = NULL;
107 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false); 110 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio,
111 no_sg_merge);
108 bio->bi_next = nxt; 112 bio->bi_next = nxt;
109 } 113 }
110 114