diff options
| -rw-r--r-- | block/blk-merge.c | 17 |
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 | ||
| 12 | static unsigned int __blk_recalc_rq_segments(struct request_queue *q, | 12 | static 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 | ||
| 89 | void blk_recalc_rq_segments(struct request *rq) | 89 | void 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 | ||
| 94 | void blk_recount_segments(struct request_queue *q, struct bio *bio) | 98 | void 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 | ||
