blk-merge: don't compute bi_phys_segments from bi_vcnt for cloned bio
authorMing Lei <ming.lei@canonical.com>
Thu, 9 Oct 2014 15:17:35 +0000 (23:17 +0800)
committerJens Axboe <axboe@fb.com>
Thu, 9 Oct 2014 19:11:44 +0000 (13:11 -0600)
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>
block/blk-merge.c

index f71bad35b4cc0f20938977b9a5c15cf205979a0e..ba99351c0f58898cb83bd336299c773230e9e73f 100644 (file)
@@ -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;
        }