diff options
Diffstat (limited to 'block/blk-merge.c')
-rw-r--r-- | block/blk-merge.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c index 5efc9e7a68b7..6cf8f0c70a51 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | void blk_recalc_rq_sectors(struct request *rq, int nsect) | 12 | void blk_recalc_rq_sectors(struct request *rq, int nsect) |
13 | { | 13 | { |
14 | if (blk_fs_request(rq)) { | 14 | if (blk_fs_request(rq) || blk_discard_rq(rq)) { |
15 | rq->hard_sector += nsect; | 15 | rq->hard_sector += nsect; |
16 | rq->hard_nr_sectors -= nsect; | 16 | rq->hard_nr_sectors -= nsect; |
17 | 17 | ||
@@ -131,13 +131,17 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, | |||
131 | if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) | 131 | if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) |
132 | return 0; | 132 | return 0; |
133 | 133 | ||
134 | if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt))) | ||
135 | return 0; | ||
136 | if (bio->bi_size + nxt->bi_size > q->max_segment_size) | 134 | if (bio->bi_size + nxt->bi_size > q->max_segment_size) |
137 | return 0; | 135 | return 0; |
138 | 136 | ||
137 | if (!bio_has_data(bio)) | ||
138 | return 1; | ||
139 | |||
140 | if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt))) | ||
141 | return 0; | ||
142 | |||
139 | /* | 143 | /* |
140 | * bio and nxt are contigous in memory, check if the queue allows | 144 | * bio and nxt are contiguous in memory; check if the queue allows |
141 | * these two to be merged into one | 145 | * these two to be merged into one |
142 | */ | 146 | */ |
143 | if (BIO_SEG_BOUNDARY(q, bio, nxt)) | 147 | if (BIO_SEG_BOUNDARY(q, bio, nxt)) |
@@ -153,8 +157,9 @@ static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio, | |||
153 | blk_recount_segments(q, bio); | 157 | blk_recount_segments(q, bio); |
154 | if (!bio_flagged(nxt, BIO_SEG_VALID)) | 158 | if (!bio_flagged(nxt, BIO_SEG_VALID)) |
155 | blk_recount_segments(q, nxt); | 159 | blk_recount_segments(q, nxt); |
156 | if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) || | 160 | if (bio_has_data(bio) && |
157 | BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size)) | 161 | (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) || |
162 | BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size))) | ||
158 | return 0; | 163 | return 0; |
159 | if (bio->bi_hw_back_size + nxt->bi_hw_front_size > q->max_segment_size) | 164 | if (bio->bi_hw_back_size + nxt->bi_hw_front_size > q->max_segment_size) |
160 | return 0; | 165 | return 0; |
@@ -317,8 +322,9 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req, | |||
317 | if (!bio_flagged(bio, BIO_SEG_VALID)) | 322 | if (!bio_flagged(bio, BIO_SEG_VALID)) |
318 | blk_recount_segments(q, bio); | 323 | blk_recount_segments(q, bio); |
319 | len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size; | 324 | len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size; |
320 | if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio)) | 325 | if (!bio_has_data(bio) || |
321 | && !BIOVEC_VIRT_OVERSIZE(len)) { | 326 | (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio)) |
327 | && !BIOVEC_VIRT_OVERSIZE(len))) { | ||
322 | int mergeable = ll_new_mergeable(q, req, bio); | 328 | int mergeable = ll_new_mergeable(q, req, bio); |
323 | 329 | ||
324 | if (mergeable) { | 330 | if (mergeable) { |
@@ -356,8 +362,9 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req, | |||
356 | blk_recount_segments(q, bio); | 362 | blk_recount_segments(q, bio); |
357 | if (!bio_flagged(req->bio, BIO_SEG_VALID)) | 363 | if (!bio_flagged(req->bio, BIO_SEG_VALID)) |
358 | blk_recount_segments(q, req->bio); | 364 | blk_recount_segments(q, req->bio); |
359 | if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) && | 365 | if (!bio_has_data(bio) || |
360 | !BIOVEC_VIRT_OVERSIZE(len)) { | 366 | (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) && |
367 | !BIOVEC_VIRT_OVERSIZE(len))) { | ||
361 | int mergeable = ll_new_mergeable(q, req, bio); | 368 | int mergeable = ll_new_mergeable(q, req, bio); |
362 | 369 | ||
363 | if (mergeable) { | 370 | if (mergeable) { |