]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 2 Feb 2016 01:30:39 +0000 (17:30 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 2 Feb 2016 01:30:39 +0000 (17:30 -0800)
added patches:
block-fix-bio-splitting-on-max-sectors.patch

queue-4.4/block-fix-bio-splitting-on-max-sectors.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/block-fix-bio-splitting-on-max-sectors.patch b/queue-4.4/block-fix-bio-splitting-on-max-sectors.patch
new file mode 100644 (file)
index 0000000..5b70e8c
--- /dev/null
@@ -0,0 +1,85 @@
+From d0e5fbb01a67e400e82fefe4896ea40c6447ab98 Mon Sep 17 00:00:00 2001
+From: Ming Lei <tom.leiming@gmail.com>
+Date: Sat, 23 Jan 2016 08:05:33 +0800
+Subject: block: fix bio splitting on max sectors
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+commit d0e5fbb01a67e400e82fefe4896ea40c6447ab98 upstream.
+
+After commit e36f62042880(block: split bios to maxpossible length),
+bio can be splitted in the middle of a vector entry, then it
+is easy to split out one bio which size isn't aligned with block
+size, especially when the block size is bigger than 512.
+
+This patch fixes the issue by making the max io size aligned
+to logical block size.
+
+Fixes: e36f62042880(block: split bios to maxpossible length)
+Reported-by: Stefan Haberland <sth@linux.vnet.ibm.com>
+Cc: Keith Busch <keith.busch@intel.com>
+Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-merge.c |   26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -68,6 +68,18 @@ static struct bio *blk_bio_write_same_sp
+       return bio_split(bio, q->limits.max_write_same_sectors, GFP_NOIO, bs);
+ }
++static inline unsigned get_max_io_size(struct request_queue *q,
++                                     struct bio *bio)
++{
++      unsigned sectors = blk_max_size_offset(q, bio->bi_iter.bi_sector);
++      unsigned mask = queue_logical_block_size(q) - 1;
++
++      /* aligned to logical block size */
++      sectors &= ~(mask >> 9);
++
++      return sectors;
++}
++
+ static struct bio *blk_bio_segment_split(struct request_queue *q,
+                                        struct bio *bio,
+                                        struct bio_set *bs,
+@@ -79,6 +91,7 @@ static struct bio *blk_bio_segment_split
+       unsigned front_seg_size = bio->bi_seg_front_size;
+       bool do_split = true;
+       struct bio *new = NULL;
++      const unsigned max_sectors = get_max_io_size(q, bio);
+       bio_for_each_segment(bv, bio, iter) {
+               /*
+@@ -88,20 +101,19 @@ static struct bio *blk_bio_segment_split
+               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)) {
++              if (sectors + (bv.bv_len >> 9) > max_sectors) {
+                       /*
+                        * 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)) {
++                          sectors < max_sectors) {
+                               nsegs++;
+-                              sectors = blk_max_size_offset(q,
+-                                              bio->bi_iter.bi_sector);
++                              sectors = max_sectors;
+                       }
+-                      goto split;
++                      if (sectors)
++                              goto split;
++                      /* Make this single bvec as the 1st segment */
+               }
+               if (bvprvp && blk_queue_cluster(q)) {
index 9dcb7e936398819cf0f16e420de93c4dea6a13da..d97d44993c5ca38e72033bbc1804804e4f090e7c 100644 (file)
@@ -4,3 +4,4 @@ block-split-bios-to-max-possible-length.patch
 ocfs2-nfs-hangs-in-__ocfs2_cluster_lock-due-to-race-with-ocfs2_unblock_lock.patch
 hid-usbhid-fix-recursive-deadlock.patch
 base-platform-fix-platform-drivers-with-no-probe-callback.patch
+block-fix-bio-splitting-on-max-sectors.patch