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 | |
| 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>
| -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 | ||
