aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-merge.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/blk-merge.c')
-rw-r--r--block/blk-merge.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 54535831f1e1..77881798f793 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -10,10 +10,11 @@
10#include "blk.h" 10#include "blk.h"
11 11
12static unsigned int __blk_recalc_rq_segments(struct request_queue *q, 12static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
13 struct bio *bio) 13 struct bio *bio,
14 bool no_sg_merge)
14{ 15{
15 struct bio_vec bv, bvprv = { NULL }; 16 struct bio_vec bv, bvprv = { NULL };
16 int cluster, high, highprv = 1, no_sg_merge; 17 int cluster, high, highprv = 1;
17 unsigned int seg_size, nr_phys_segs; 18 unsigned int seg_size, nr_phys_segs;
18 struct bio *fbio, *bbio; 19 struct bio *fbio, *bbio;
19 struct bvec_iter iter; 20 struct bvec_iter iter;
@@ -35,7 +36,6 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
35 cluster = blk_queue_cluster(q); 36 cluster = blk_queue_cluster(q);
36 seg_size = 0; 37 seg_size = 0;
37 nr_phys_segs = 0; 38 nr_phys_segs = 0;
38 no_sg_merge = test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags);
39 high = 0; 39 high = 0;
40 for_each_bio(bio) { 40 for_each_bio(bio) {
41 bio_for_each_segment(bv, bio, iter) { 41 bio_for_each_segment(bv, bio, iter) {
@@ -88,18 +88,23 @@ new_segment:
88 88
89void blk_recalc_rq_segments(struct request *rq) 89void blk_recalc_rq_segments(struct request *rq)
90{ 90{
91 rq->nr_phys_segments = __blk_recalc_rq_segments(rq->q, rq->bio); 91 bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE,
92 &rq->q->queue_flags);
93
94 rq->nr_phys_segments = __blk_recalc_rq_segments(rq->q, rq->bio,
95 no_sg_merge);
92} 96}
93 97
94void blk_recount_segments(struct request_queue *q, struct bio *bio) 98void blk_recount_segments(struct request_queue *q, struct bio *bio)
95{ 99{
96 if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags)) 100 if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) &&
101 bio->bi_vcnt < queue_max_segments(q))
97 bio->bi_phys_segments = bio->bi_vcnt; 102 bio->bi_phys_segments = bio->bi_vcnt;
98 else { 103 else {
99 struct bio *nxt = bio->bi_next; 104 struct bio *nxt = bio->bi_next;
100 105
101 bio->bi_next = NULL; 106 bio->bi_next = NULL;
102 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio); 107 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false);
103 bio->bi_next = nxt; 108 bio->bi_next = nxt;
104 } 109 }
105 110