]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - block/blk-merge.c
[SCSI] 3w-xxxx: remove unnecessary local_irq_save/restore for scsi sg copy API
[linux-2.6-omap-h63xx.git] / block / blk-merge.c
index 908d3e11ac523e032f3f73a91932eb49f1a5994a..8681cd6f9911427419b41b99f678e9eb623bbf5e 100644 (file)
@@ -77,12 +77,20 @@ void blk_recalc_rq_segments(struct request *rq)
                        continue;
                }
 new_segment:
+               if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
+                       rq->bio->bi_seg_front_size = seg_size;
+
                nr_phys_segs++;
                bvprv = bv;
                seg_size = bv->bv_len;
                highprv = high;
        }
 
+       if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
+               rq->bio->bi_seg_front_size = seg_size;
+       if (seg_size > rq->biotail->bi_seg_back_size)
+               rq->biotail->bi_seg_back_size = seg_size;
+
        rq->nr_phys_segments = nr_phys_segs;
 }
 
@@ -106,7 +114,8 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
        if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
                return 0;
 
-       if (bio->bi_size + nxt->bi_size > q->max_segment_size)
+       if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
+           q->max_segment_size)
                return 0;
 
        if (!bio_has_data(bio))
@@ -309,6 +318,8 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
                                struct request *next)
 {
        int total_phys_segments;
+       unsigned int seg_size =
+               req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;
 
        /*
         * 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,
                return 0;
 
        total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
-       if (blk_phys_contig_segment(q, req->biotail, next->bio))
+       if (blk_phys_contig_segment(q, req->biotail, next->bio)) {
+               if (req->nr_phys_segments == 1)
+                       req->bio->bi_seg_front_size = seg_size;
+               if (next->nr_phys_segments == 1)
+                       next->biotail->bi_seg_back_size = seg_size;
                total_phys_segments--;
+       }
 
        if (total_phys_segments > q->max_phys_segments)
                return 0;