aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorMing Lei <tom.leiming@gmail.com>2014-10-21 20:30:30 -0400
committerJens Axboe <axboe@fb.com>2014-10-21 21:00:32 -0400
commit76d8137a31139f0d69ecc4177497ad6b8d4f016c (patch)
tree194c64bc760ff1aff6c21f29b9519725b1c2fc1a /block
parent432f16e64f50fd4999a476543d04dd52f7a2d753 (diff)
blk-merge: recaculate segment if it isn't less than max segments
The problem is introduced by commit 764f612c6c3c231b(blk-merge: don't compute bi_phys_segments from bi_vcnt for cloned bio), and merge is needed if number of current segment isn't less than max segments. Strictly speaking, bio->bi_vcnt shouldn't be used here since it may not be accurate in cases of both cloned bio or bio cloned from, but bio_segments() is a bit expensive, and bi_vcnt is still the biggest number, so the approach should work. Signed-off-by: Ming Lei <tom.leiming@gmail.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block')
-rw-r--r--block/blk-merge.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c
index ba99351c0f58..b3ac40aef46b 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -99,16 +99,17 @@ void blk_recount_segments(struct request_queue *q, struct bio *bio)
99{ 99{
100 bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE, 100 bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE,
101 &q->queue_flags); 101 &q->queue_flags);
102 bool merge_not_need = bio->bi_vcnt < queue_max_segments(q);
102 103
103 if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) && 104 if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) &&
104 bio->bi_vcnt < queue_max_segments(q)) 105 merge_not_need)
105 bio->bi_phys_segments = bio->bi_vcnt; 106 bio->bi_phys_segments = bio->bi_vcnt;
106 else { 107 else {
107 struct bio *nxt = bio->bi_next; 108 struct bio *nxt = bio->bi_next;
108 109
109 bio->bi_next = NULL; 110 bio->bi_next = NULL;
110 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, 111 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio,
111 no_sg_merge); 112 no_sg_merge && merge_not_need);
112 bio->bi_next = nxt; 113 bio->bi_next = nxt;
113 } 114 }
114 115