aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-io.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index da663d2ff552..4eb73d395213 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -92,12 +92,12 @@ void dm_io_put(unsigned int num_pages)
92 *---------------------------------------------------------------*/ 92 *---------------------------------------------------------------*/
93static inline void bio_set_region(struct bio *bio, unsigned region) 93static inline void bio_set_region(struct bio *bio, unsigned region)
94{ 94{
95 bio->bi_io_vec[bio->bi_max_vecs - 1].bv_len = region; 95 bio->bi_io_vec[bio->bi_max_vecs].bv_len = region;
96} 96}
97 97
98static inline unsigned bio_get_region(struct bio *bio) 98static inline unsigned bio_get_region(struct bio *bio)
99{ 99{
100 return bio->bi_io_vec[bio->bi_max_vecs - 1].bv_len; 100 return bio->bi_io_vec[bio->bi_max_vecs].bv_len;
101} 101}
102 102
103/*----------------------------------------------------------------- 103/*-----------------------------------------------------------------
@@ -136,6 +136,7 @@ static int endio(struct bio *bio, unsigned int done, int error)
136 zero_fill_bio(bio); 136 zero_fill_bio(bio);
137 137
138 dec_count(io, bio_get_region(bio), error); 138 dec_count(io, bio_get_region(bio), error);
139 bio->bi_max_vecs++;
139 bio_put(bio); 140 bio_put(bio);
140 141
141 return 0; 142 return 0;
@@ -250,16 +251,18 @@ static void do_region(int rw, unsigned int region, struct io_region *where,
250 251
251 while (remaining) { 252 while (remaining) {
252 /* 253 /*
253 * Allocate a suitably sized bio, we add an extra 254 * Allocate a suitably sized-bio: we add an extra
254 * bvec for bio_get/set_region(). 255 * bvec for bio_get/set_region() and decrement bi_max_vecs
256 * to hide it from bio_add_page().
255 */ 257 */
256 num_bvecs = (remaining / (PAGE_SIZE >> 9)) + 2; 258 num_bvecs = (remaining / (PAGE_SIZE >> SECTOR_SHIFT)) + 2;
257 bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, _bios); 259 bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, _bios);
258 bio->bi_sector = where->sector + (where->count - remaining); 260 bio->bi_sector = where->sector + (where->count - remaining);
259 bio->bi_bdev = where->bdev; 261 bio->bi_bdev = where->bdev;
260 bio->bi_end_io = endio; 262 bio->bi_end_io = endio;
261 bio->bi_private = io; 263 bio->bi_private = io;
262 bio->bi_destructor = dm_bio_destructor; 264 bio->bi_destructor = dm_bio_destructor;
265 bio->bi_max_vecs--;
263 bio_set_region(bio, region); 266 bio_set_region(bio, region);
264 267
265 /* 268 /*
@@ -302,7 +305,7 @@ static void dispatch_io(int rw, unsigned int num_regions,
302 } 305 }
303 306
304 /* 307 /*
305 * Drop the extra refence that we were holding to avoid 308 * Drop the extra reference that we were holding to avoid
306 * the io being completed too early. 309 * the io being completed too early.
307 */ 310 */
308 dec_count(io, 0, 0); 311 dec_count(io, 0, 0);