diff options
Diffstat (limited to 'drivers/lightnvm/pblk-read.c')
-rw-r--r-- | drivers/lightnvm/pblk-read.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c index 3789185144da..0b7d5fb4548d 100644 --- a/drivers/lightnvm/pblk-read.c +++ b/drivers/lightnvm/pblk-read.c | |||
@@ -231,14 +231,14 @@ static void pblk_end_partial_read(struct nvm_rq *rqd) | |||
231 | struct pblk_sec_meta *meta; | 231 | struct pblk_sec_meta *meta; |
232 | struct bio *new_bio = rqd->bio; | 232 | struct bio *new_bio = rqd->bio; |
233 | struct bio *bio = pr_ctx->orig_bio; | 233 | struct bio *bio = pr_ctx->orig_bio; |
234 | struct bio_vec src_bv, dst_bv; | ||
235 | void *meta_list = rqd->meta_list; | 234 | void *meta_list = rqd->meta_list; |
236 | int bio_init_idx = pr_ctx->bio_init_idx; | ||
237 | unsigned long *read_bitmap = pr_ctx->bitmap; | 235 | unsigned long *read_bitmap = pr_ctx->bitmap; |
236 | struct bvec_iter orig_iter = BVEC_ITER_ALL_INIT; | ||
237 | struct bvec_iter new_iter = BVEC_ITER_ALL_INIT; | ||
238 | int nr_secs = pr_ctx->orig_nr_secs; | 238 | int nr_secs = pr_ctx->orig_nr_secs; |
239 | int nr_holes = nr_secs - bitmap_weight(read_bitmap, nr_secs); | 239 | int nr_holes = nr_secs - bitmap_weight(read_bitmap, nr_secs); |
240 | void *src_p, *dst_p; | 240 | void *src_p, *dst_p; |
241 | int hole, i; | 241 | int bit, i; |
242 | 242 | ||
243 | if (unlikely(nr_holes == 1)) { | 243 | if (unlikely(nr_holes == 1)) { |
244 | struct ppa_addr ppa; | 244 | struct ppa_addr ppa; |
@@ -257,33 +257,39 @@ static void pblk_end_partial_read(struct nvm_rq *rqd) | |||
257 | 257 | ||
258 | /* Fill the holes in the original bio */ | 258 | /* Fill the holes in the original bio */ |
259 | i = 0; | 259 | i = 0; |
260 | hole = find_first_zero_bit(read_bitmap, nr_secs); | 260 | for (bit = 0; bit < nr_secs; bit++) { |
261 | do { | 261 | if (!test_bit(bit, read_bitmap)) { |
262 | struct pblk_line *line; | 262 | struct bio_vec dst_bv, src_bv; |
263 | struct pblk_line *line; | ||
263 | 264 | ||
264 | line = pblk_ppa_to_line(pblk, rqd->ppa_list[i]); | 265 | line = pblk_ppa_to_line(pblk, rqd->ppa_list[i]); |
265 | kref_put(&line->ref, pblk_line_put); | 266 | kref_put(&line->ref, pblk_line_put); |
266 | 267 | ||
267 | meta = pblk_get_meta(pblk, meta_list, hole); | 268 | meta = pblk_get_meta(pblk, meta_list, bit); |
268 | meta->lba = cpu_to_le64(pr_ctx->lba_list_media[i]); | 269 | meta->lba = cpu_to_le64(pr_ctx->lba_list_media[i]); |
269 | 270 | ||
270 | src_bv = new_bio->bi_io_vec[i++]; | 271 | dst_bv = bio_iter_iovec(bio, orig_iter); |
271 | dst_bv = bio->bi_io_vec[bio_init_idx + hole]; | 272 | src_bv = bio_iter_iovec(new_bio, new_iter); |
272 | 273 | ||
273 | src_p = kmap_atomic(src_bv.bv_page); | 274 | src_p = kmap_atomic(src_bv.bv_page); |
274 | dst_p = kmap_atomic(dst_bv.bv_page); | 275 | dst_p = kmap_atomic(dst_bv.bv_page); |
275 | 276 | ||
276 | memcpy(dst_p + dst_bv.bv_offset, | 277 | memcpy(dst_p + dst_bv.bv_offset, |
277 | src_p + src_bv.bv_offset, | 278 | src_p + src_bv.bv_offset, |
278 | PBLK_EXPOSED_PAGE_SIZE); | 279 | PBLK_EXPOSED_PAGE_SIZE); |
279 | 280 | ||
280 | kunmap_atomic(src_p); | 281 | kunmap_atomic(src_p); |
281 | kunmap_atomic(dst_p); | 282 | kunmap_atomic(dst_p); |
282 | 283 | ||
283 | mempool_free(src_bv.bv_page, &pblk->page_bio_pool); | 284 | flush_dcache_page(dst_bv.bv_page); |
285 | mempool_free(src_bv.bv_page, &pblk->page_bio_pool); | ||
284 | 286 | ||
285 | hole = find_next_zero_bit(read_bitmap, nr_secs, hole + 1); | 287 | bio_advance_iter(new_bio, &new_iter, |
286 | } while (hole < nr_secs); | 288 | PBLK_EXPOSED_PAGE_SIZE); |
289 | i++; | ||
290 | } | ||
291 | bio_advance_iter(bio, &orig_iter, PBLK_EXPOSED_PAGE_SIZE); | ||
292 | } | ||
287 | 293 | ||
288 | bio_put(new_bio); | 294 | bio_put(new_bio); |
289 | kfree(pr_ctx); | 295 | kfree(pr_ctx); |