]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - block/blk-merge.c
block: split bios to max possible length
[karo-tx-linux.git] / block / blk-merge.c
index 0e5643a5d1c35a5973c39b35eb6c2e3f4336c8d6..237b087d35299ad9aeb4295556f8f1995118f2b6 100644 (file)
@@ -83,9 +83,6 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
        struct bio *new = NULL;
 
        bio_for_each_segment(bv, bio, iter) {
-               if (sectors + (bv.bv_len >> 9) > queue_max_sectors(q))
-                       goto split;
-
                /*
                 * If the queue doesn't support SG gaps and adding this
                 * offset would create a gap, disallow it.
@@ -93,6 +90,22 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
                if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset))
                        goto split;
 
+               if (sectors + (bv.bv_len >> 9) >
+                               blk_max_size_offset(q, bio->bi_iter.bi_sector)) {
+                       /*
+                        * Consider this a new segment if we're splitting in
+                        * the middle of this vector.
+                        */
+                       if (nsegs < queue_max_segments(q) &&
+                           sectors < blk_max_size_offset(q,
+                                               bio->bi_iter.bi_sector)) {
+                               nsegs++;
+                               sectors = blk_max_size_offset(q,
+                                               bio->bi_iter.bi_sector);
+                       }
+                       goto split;
+               }
+
                if (bvprvp && blk_queue_cluster(q)) {
                        if (seg_size + bv.bv_len > queue_max_segment_size(q))
                                goto new_segment;