diff options
author | Ming Lei <tom.leiming@gmail.com> | 2016-11-11 07:05:35 -0500 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2016-11-21 09:51:57 -0500 |
commit | cacc7b0556739bd6018252731c0237c071ba51da (patch) | |
tree | 8c5cb13d6cb60a9f79616f3887318b9743202c56 /drivers/md/dm-io.c | |
parent | 4f9c74c6043891d415730bcb153c579be35c352f (diff) |
dm io: use bvec iterator helpers to implement .get_page and .next_page
Firstly we have mature bvec/bio iterator helper for iterate each
page in one bio, not necessary to reinvent a wheel to do that.
Secondly the coming multipage bvecs requires this patch.
Also add comments about the direct access to bvec table.
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-io.c')
-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 | /* |