History

block: fix bio splitting on max sectors

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.

Ming Lei committed 10 years ago

Commit d0e5fbb1 parent b82dde01 file · +19 −7Browse files

Unified · Split

block/blk-merge.c+19−7
@@ -70,6 +70,18 @@ static struct bio *blk_bio_write_same_split(struct request_queue *q, · 69 unmodified lines
7070 return bio_split(bio, q->limits.max_write_same_sectors, GFP_NOIO, bs);
7171 }
7272
73+static inline unsigned get_max_io_size(struct request_queue *q,
74+ struct bio *bio)
75+{
76+ unsigned sectors = blk_max_size_offset(q, bio->bi_iter.bi_sector);
77+ unsigned mask = queue_logical_block_size(q) - 1;
78+
79+ /* aligned to logical block size */
80+ sectors &= ~(mask >> 9);
81+
82+ return sectors;
83+}
84+
7385 static struct bio *blk_bio_segment_split(struct request_queue *q,
7486 struct bio *bio,
7587 struct bio_set *bs,
@@ -81,6 +93,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, · 5 unmodified lines
8193 unsigned front_seg_size = bio->bi_seg_front_size;
8294 bool do_split = true;
8395 struct bio *new = NULL;
96+ const unsigned max_sectors = get_max_io_size(q, bio);
8497
8598 bio_for_each_segment(bv, bio, iter) {
8699 /*
@@ -90,20 +103,19 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, · 3 unmodified lines
90103 if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset))
91104 goto split;
92105
93− if (sectors + (bv.bv_len >> 9) >
94− blk_max_size_offset(q, bio->bi_iter.bi_sector)) {
106+ if (sectors + (bv.bv_len >> 9) > max_sectors) {
95107 /*
96108 * Consider this a new segment if we're splitting in
97109 * the middle of this vector.
98110 */
99111 if (nsegs < queue_max_segments(q) &&
100− sectors < blk_max_size_offset(q,
101− bio->bi_iter.bi_sector)) {
112+ sectors < max_sectors) {
102113 nsegs++;
103− sectors = blk_max_size_offset(q,
104− bio->bi_iter.bi_sector);
114+ sectors = max_sectors;
105115 }
106− goto split;
116+ if (sectors)
117+ goto split;
118+ /* Make this single bvec as the 1st segment */
107119 }
108120
109121 if (bvprvp && blk_queue_cluster(q)) {