diff options
Diffstat (limited to 'block/blk-merge.c')
-rw-r--r-- | block/blk-merge.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c index 908d3e11ac52..8681cd6f9911 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -77,12 +77,20 @@ void blk_recalc_rq_segments(struct request *rq) | |||
77 | continue; | 77 | continue; |
78 | } | 78 | } |
79 | new_segment: | 79 | new_segment: |
80 | if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) | ||
81 | rq->bio->bi_seg_front_size = seg_size; | ||
82 | |||
80 | nr_phys_segs++; | 83 | nr_phys_segs++; |
81 | bvprv = bv; | 84 | bvprv = bv; |
82 | seg_size = bv->bv_len; | 85 | seg_size = bv->bv_len; |
83 | highprv = high; | 86 | highprv = high; |
84 | } | 87 | } |
85 | 88 | ||
89 | if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) | ||
90 | rq->bio->bi_seg_front_size = seg_size; | ||
91 | if (seg_size > rq->biotail->bi_seg_back_size) | ||
92 | rq->biotail->bi_seg_back_size = seg_size; | ||
93 | |||
86 | rq->nr_phys_segments = nr_phys_segs; | 94 | rq->nr_phys_segments = nr_phys_segs; |
87 | } | 95 | } |
88 | 96 | ||
@@ -106,7 +114,8 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, | |||
106 | if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) | 114 | if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) |
107 | return 0; | 115 | return 0; |
108 | 116 | ||
109 | if (bio->bi_size + nxt->bi_size > q->max_segment_size) | 117 | if (bio->bi_seg_back_size + nxt->bi_seg_front_size > |
118 | q->max_segment_size) | ||
110 | return 0; | 119 | return 0; |
111 | 120 | ||
112 | if (!bio_has_data(bio)) | 121 | if (!bio_has_data(bio)) |
@@ -309,6 +318,8 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, | |||
309 | struct request *next) | 318 | struct request *next) |
310 | { | 319 | { |
311 | int total_phys_segments; | 320 | int total_phys_segments; |
321 | unsigned int seg_size = | ||
322 | req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size; | ||
312 | 323 | ||
313 | /* | 324 | /* |
314 | * First check if the either of the requests are re-queued | 325 | * First check if the either of the requests are re-queued |
@@ -324,8 +335,13 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, | |||
324 | return 0; | 335 | return 0; |
325 | 336 | ||
326 | total_phys_segments = req->nr_phys_segments + next->nr_phys_segments; | 337 | total_phys_segments = req->nr_phys_segments + next->nr_phys_segments; |
327 | if (blk_phys_contig_segment(q, req->biotail, next->bio)) | 338 | if (blk_phys_contig_segment(q, req->biotail, next->bio)) { |
339 | if (req->nr_phys_segments == 1) | ||
340 | req->bio->bi_seg_front_size = seg_size; | ||
341 | if (next->nr_phys_segments == 1) | ||
342 | next->biotail->bi_seg_back_size = seg_size; | ||
328 | total_phys_segments--; | 343 | total_phys_segments--; |
344 | } | ||
329 | 345 | ||
330 | if (total_phys_segments > q->max_phys_segments) | 346 | if (total_phys_segments > q->max_phys_segments) |
331 | return 0; | 347 | return 0; |