diff options
author | Ming Lei <ming.lei@canonical.com> | 2014-10-09 11:17:35 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-10-09 15:11:44 -0400 |
commit | 764f612c6c3c231b9c12cfae7c328ccc9c453258 (patch) | |
tree | f07edb7a3ed883c1ac66e8ede65a9aa6681cb378 /block | |
parent | b8839b8c55f3fdd60dc36abcda7e0266aff7985c (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.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) | |||
97 | 97 | ||
98 | void blk_recount_segments(struct request_queue *q, struct bio *bio) | 98 | void 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 | ||