Commit 13d56990 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.dk/linux-block

Pull block layer fix from Jens Axboe:
 "This just contains the fix for the split issue that we had in -rc1.

  It's been well tested at this point, so let's get it in mainline so we
  don't have the same split issue for -rc2"

* 'for-linus' of git://git.kernel.dk/linux-block:
  block: fix bio splitting on max sectors
parents b5454432 d0e5fbb0
...@@ -70,6 +70,18 @@ static struct bio *blk_bio_write_same_split(struct request_queue *q, ...@@ -70,6 +70,18 @@ static struct bio *blk_bio_write_same_split(struct request_queue *q,
return bio_split(bio, q->limits.max_write_same_sectors, GFP_NOIO, bs); 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, static struct bio *blk_bio_segment_split(struct request_queue *q,
struct bio *bio, struct bio *bio,
struct bio_set *bs, struct bio_set *bs,
...@@ -81,6 +93,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, ...@@ -81,6 +93,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
unsigned front_seg_size = bio->bi_seg_front_size; unsigned front_seg_size = bio->bi_seg_front_size;
bool do_split = true; bool do_split = true;
struct bio *new = NULL; struct bio *new = NULL;
const unsigned max_sectors = get_max_io_size(q, bio);
bio_for_each_segment(bv, bio, iter) { bio_for_each_segment(bv, bio, iter) {
/* /*
...@@ -90,20 +103,19 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, ...@@ -90,20 +103,19 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset)) if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset))
goto split; goto split;
if (sectors + (bv.bv_len >> 9) > if (sectors + (bv.bv_len >> 9) > max_sectors) {
blk_max_size_offset(q, bio->bi_iter.bi_sector)) {
/* /*
* Consider this a new segment if we're splitting in * Consider this a new segment if we're splitting in
* the middle of this vector. * the middle of this vector.
*/ */
if (nsegs < queue_max_segments(q) && if (nsegs < queue_max_segments(q) &&
sectors < blk_max_size_offset(q, sectors < max_sectors) {
bio->bi_iter.bi_sector)) {
nsegs++; nsegs++;
sectors = blk_max_size_offset(q, sectors = max_sectors;
bio->bi_iter.bi_sector);
} }
goto split; if (sectors)
goto split;
/* Make this single bvec as the 1st segment */
} }
if (bvprvp && blk_queue_cluster(q)) { if (bvprvp && blk_queue_cluster(q)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment