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.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c
index b3ac40aef46b..89b97b5e0881 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -97,19 +97,22 @@ void blk_recalc_rq_segments(struct request *rq)
97 97
98void blk_recount_segments(struct request_queue *q, struct bio *bio) 98void 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 unsigned short seg_cnt;
101 &q->queue_flags); 101
102 bool merge_not_need = bio->bi_vcnt < queue_max_segments(q); 102 /* estimate segment number by bi_vcnt for non-cloned bio */
103 if (bio_flagged(bio, BIO_CLONED))
104 seg_cnt = bio_segments(bio);
105 else
106 seg_cnt = bio->bi_vcnt;
103 107
104 if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) && 108 if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) &&
105 merge_not_need) 109 (seg_cnt < queue_max_segments(q)))
106 bio->bi_phys_segments = bio->bi_vcnt; 110 bio->bi_phys_segments = seg_cnt;
107 else { 111 else {
108 struct bio *nxt = bio->bi_next; 112 struct bio *nxt = bio->bi_next;
109 113
110 bio->bi_next = NULL; 114 bio->bi_next = NULL;
111 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, 115 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false);
112 no_sg_merge && merge_not_need);
113 bio->bi_next = nxt; 116 bio->bi_next = nxt;
114 } 117 }
115 118