powerpc: drop _PAGE_FILE and pte_file()-related helpers
[deliverable/linux.git] / block / blk-merge.c
index b3ac40aef46b317c5a432a92ba9b40c8e1942504..fc1ff3b1ea1f4a9ea2dcd18d6e49eea7281eb9b3 100644 (file)
@@ -97,19 +97,22 @@ void blk_recalc_rq_segments(struct request *rq)
 
 void blk_recount_segments(struct request_queue *q, struct bio *bio)
 {
-       bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE,
-                       &q->queue_flags);
-       bool merge_not_need = bio->bi_vcnt < queue_max_segments(q);
+       unsigned short seg_cnt;
+
+       /* estimate segment number by bi_vcnt for non-cloned bio */
+       if (bio_flagged(bio, BIO_CLONED))
+               seg_cnt = bio_segments(bio);
+       else
+               seg_cnt = bio->bi_vcnt;
 
-       if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) &&
-                       merge_not_need)
-               bio->bi_phys_segments = bio->bi_vcnt;
+       if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) &&
+                       (seg_cnt < queue_max_segments(q)))
+               bio->bi_phys_segments = seg_cnt;
        else {
                struct bio *nxt = bio->bi_next;
 
                bio->bi_next = NULL;
-               bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio,
-                               no_sg_merge && merge_not_need);
+               bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false);
                bio->bi_next = nxt;
        }
 
@@ -280,35 +283,6 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 }
 EXPORT_SYMBOL(blk_rq_map_sg);
 
-/**
- * blk_bio_map_sg - map a bio to a scatterlist
- * @q: request_queue in question
- * @bio: bio being mapped
- * @sglist: scatterlist being mapped
- *
- * Note:
- *    Caller must make sure sg can hold bio->bi_phys_segments entries
- *
- * Will return the number of sg entries setup
- */
-int blk_bio_map_sg(struct request_queue *q, struct bio *bio,
-                  struct scatterlist *sglist)
-{
-       struct scatterlist *sg = NULL;
-       int nsegs;
-       struct bio *next = bio->bi_next;
-       bio->bi_next = NULL;
-
-       nsegs = __blk_bios_map_sg(q, bio, sglist, &sg);
-       bio->bi_next = next;
-       if (sg)
-               sg_mark_end(sg);
-
-       BUG_ON(bio->bi_phys_segments && nsegs > bio->bi_phys_segments);
-       return nsegs;
-}
-EXPORT_SYMBOL(blk_bio_map_sg);
-
 static inline int ll_new_hw_segment(struct request_queue *q,
                                    struct request *req,
                                    struct bio *bio)
@@ -382,6 +356,14 @@ static bool req_no_special_merge(struct request *req)
        return !q->mq_ops && req->special;
 }
 
+static int req_gap_to_prev(struct request *req, struct request *next)
+{
+       struct bio *prev = req->biotail;
+
+       return bvec_gap_to_prev(&prev->bi_io_vec[prev->bi_vcnt - 1],
+                               next->bio->bi_io_vec[0].bv_offset);
+}
+
 static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
                                struct request *next)
 {
@@ -396,6 +378,10 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
        if (req_no_special_merge(req) || req_no_special_merge(next))
                return 0;
 
+       if (test_bit(QUEUE_FLAG_SG_GAPS, &q->queue_flags) &&
+           req_gap_to_prev(req, next))
+               return 0;
+
        /*
         * Will it become too large?
         */
This page took 0.027728 seconds and 5 git commands to generate.