diff options
-rw-r--r-- | drivers/md/dm-io.c | 15 |
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 | *---------------------------------------------------------------*/ |
93 | static inline void bio_set_region(struct bio *bio, unsigned region) | 93 | static 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 | ||
98 | static inline unsigned bio_get_region(struct bio *bio) | 98 | static 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); |