diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-io.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 0bf1a12e35fe..03940bf36f6c 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
@@ -162,7 +162,10 @@ struct dpages { | |||
162 | struct page **p, unsigned long *len, unsigned *offset); | 162 | struct page **p, unsigned long *len, unsigned *offset); |
163 | void (*next_page)(struct dpages *dp); | 163 | void (*next_page)(struct dpages *dp); |
164 | 164 | ||
165 | unsigned context_u; | 165 | union { |
166 | unsigned context_u; | ||
167 | struct bvec_iter context_bi; | ||
168 | }; | ||
166 | void *context_ptr; | 169 | void *context_ptr; |
167 | 170 | ||
168 | void *vma_invalidate_address; | 171 | void *vma_invalidate_address; |
@@ -204,25 +207,36 @@ static void list_dp_init(struct dpages *dp, struct page_list *pl, unsigned offse | |||
204 | static void bio_get_page(struct dpages *dp, struct page **p, | 207 | static void bio_get_page(struct dpages *dp, struct page **p, |
205 | unsigned long *len, unsigned *offset) | 208 | unsigned long *len, unsigned *offset) |
206 | { | 209 | { |
207 | struct bio_vec *bvec = dp->context_ptr; | 210 | struct bio_vec bvec = bvec_iter_bvec((struct bio_vec *)dp->context_ptr, |
208 | *p = bvec->bv_page; | 211 | dp->context_bi); |
209 | *len = bvec->bv_len - dp->context_u; | 212 | |
210 | *offset = bvec->bv_offset + dp->context_u; | 213 | *p = bvec.bv_page; |
214 | *len = bvec.bv_len; | ||
215 | *offset = bvec.bv_offset; | ||
216 | |||
217 | /* avoid figuring it out again in bio_next_page() */ | ||
218 | dp->context_bi.bi_sector = (sector_t)bvec.bv_len; | ||
211 | } | 219 | } |
212 | 220 | ||
213 | static void bio_next_page(struct dpages *dp) | 221 | static void bio_next_page(struct dpages *dp) |
214 | { | 222 | { |
215 | struct bio_vec *bvec = dp->context_ptr; | 223 | unsigned int len = (unsigned int)dp->context_bi.bi_sector; |
216 | dp->context_ptr = bvec + 1; | 224 | |
217 | dp->context_u = 0; | 225 | bvec_iter_advance((struct bio_vec *)dp->context_ptr, |
226 | &dp->context_bi, len); | ||
218 | } | 227 | } |
219 | 228 | ||
220 | static void bio_dp_init(struct dpages *dp, struct bio *bio) | 229 | static void bio_dp_init(struct dpages *dp, struct bio *bio) |
221 | { | 230 | { |
222 | dp->get_page = bio_get_page; | 231 | dp->get_page = bio_get_page; |
223 | dp->next_page = bio_next_page; | 232 | dp->next_page = bio_next_page; |
224 | dp->context_ptr = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter); | 233 | |
225 | dp->context_u = bio->bi_iter.bi_bvec_done; | 234 | /* |
235 | * We just use bvec iterator to retrieve pages, so it is ok to | ||
236 | * access the bvec table directly here | ||
237 | */ | ||
238 | dp->context_ptr = bio->bi_io_vec; | ||
239 | dp->context_bi = bio->bi_iter; | ||
226 | } | 240 | } |
227 | 241 | ||
228 | /* | 242 | /* |