diff options
Diffstat (limited to 'drivers/lightnvm/pblk-recovery.c')
-rw-r--r-- | drivers/lightnvm/pblk-recovery.c | 129 |
1 files changed, 48 insertions, 81 deletions
diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c index cb556e06673e..eadb3eb5d4dc 100644 --- a/drivers/lightnvm/pblk-recovery.c +++ b/drivers/lightnvm/pblk-recovery.c | |||
@@ -34,10 +34,6 @@ void pblk_submit_rec(struct work_struct *work) | |||
34 | max_secs); | 34 | max_secs); |
35 | 35 | ||
36 | bio = bio_alloc(GFP_KERNEL, nr_rec_secs); | 36 | bio = bio_alloc(GFP_KERNEL, nr_rec_secs); |
37 | if (!bio) { | ||
38 | pr_err("pblk: not able to create recovery bio\n"); | ||
39 | return; | ||
40 | } | ||
41 | 37 | ||
42 | bio->bi_iter.bi_sector = 0; | 38 | bio->bi_iter.bi_sector = 0; |
43 | bio_set_op_attrs(bio, REQ_OP_WRITE, 0); | 39 | bio_set_op_attrs(bio, REQ_OP_WRITE, 0); |
@@ -71,7 +67,7 @@ void pblk_submit_rec(struct work_struct *work) | |||
71 | 67 | ||
72 | err: | 68 | err: |
73 | bio_put(bio); | 69 | bio_put(bio); |
74 | pblk_free_rqd(pblk, rqd, WRITE); | 70 | pblk_free_rqd(pblk, rqd, PBLK_WRITE); |
75 | } | 71 | } |
76 | 72 | ||
77 | int pblk_recov_setup_rq(struct pblk *pblk, struct pblk_c_ctx *c_ctx, | 73 | int pblk_recov_setup_rq(struct pblk *pblk, struct pblk_c_ctx *c_ctx, |
@@ -84,12 +80,7 @@ int pblk_recov_setup_rq(struct pblk *pblk, struct pblk_c_ctx *c_ctx, | |||
84 | struct pblk_c_ctx *rec_ctx; | 80 | struct pblk_c_ctx *rec_ctx; |
85 | int nr_entries = c_ctx->nr_valid + c_ctx->nr_padded; | 81 | int nr_entries = c_ctx->nr_valid + c_ctx->nr_padded; |
86 | 82 | ||
87 | rec_rqd = pblk_alloc_rqd(pblk, WRITE); | 83 | rec_rqd = pblk_alloc_rqd(pblk, PBLK_WRITE); |
88 | if (IS_ERR(rec_rqd)) { | ||
89 | pr_err("pblk: could not create recovery req.\n"); | ||
90 | return -ENOMEM; | ||
91 | } | ||
92 | |||
93 | rec_ctx = nvm_rq_to_pdu(rec_rqd); | 84 | rec_ctx = nvm_rq_to_pdu(rec_rqd); |
94 | 85 | ||
95 | /* Copy completion bitmap, but exclude the first X completed entries */ | 86 | /* Copy completion bitmap, but exclude the first X completed entries */ |
@@ -142,19 +133,19 @@ static int pblk_recov_l2p_from_emeta(struct pblk *pblk, struct pblk_line *line) | |||
142 | struct pblk_emeta *emeta = line->emeta; | 133 | struct pblk_emeta *emeta = line->emeta; |
143 | struct line_emeta *emeta_buf = emeta->buf; | 134 | struct line_emeta *emeta_buf = emeta->buf; |
144 | __le64 *lba_list; | 135 | __le64 *lba_list; |
145 | int data_start; | 136 | u64 data_start, data_end; |
146 | int nr_data_lbas, nr_valid_lbas, nr_lbas = 0; | 137 | u64 nr_valid_lbas, nr_lbas = 0; |
147 | int i; | 138 | u64 i; |
148 | 139 | ||
149 | lba_list = pblk_recov_get_lba_list(pblk, emeta_buf); | 140 | lba_list = pblk_recov_get_lba_list(pblk, emeta_buf); |
150 | if (!lba_list) | 141 | if (!lba_list) |
151 | return 1; | 142 | return 1; |
152 | 143 | ||
153 | data_start = pblk_line_smeta_start(pblk, line) + lm->smeta_sec; | 144 | data_start = pblk_line_smeta_start(pblk, line) + lm->smeta_sec; |
154 | nr_data_lbas = lm->sec_per_line - lm->emeta_sec[0]; | 145 | data_end = line->emeta_ssec; |
155 | nr_valid_lbas = le64_to_cpu(emeta_buf->nr_valid_lbas); | 146 | nr_valid_lbas = le64_to_cpu(emeta_buf->nr_valid_lbas); |
156 | 147 | ||
157 | for (i = data_start; i < nr_data_lbas && nr_lbas < nr_valid_lbas; i++) { | 148 | for (i = data_start; i < data_end; i++) { |
158 | struct ppa_addr ppa; | 149 | struct ppa_addr ppa; |
159 | int pos; | 150 | int pos; |
160 | 151 | ||
@@ -181,8 +172,8 @@ static int pblk_recov_l2p_from_emeta(struct pblk *pblk, struct pblk_line *line) | |||
181 | } | 172 | } |
182 | 173 | ||
183 | if (nr_valid_lbas != nr_lbas) | 174 | if (nr_valid_lbas != nr_lbas) |
184 | pr_err("pblk: line %d - inconsistent lba list(%llu/%d)\n", | 175 | pr_err("pblk: line %d - inconsistent lba list(%llu/%llu)\n", |
185 | line->id, emeta_buf->nr_valid_lbas, nr_lbas); | 176 | line->id, nr_valid_lbas, nr_lbas); |
186 | 177 | ||
187 | line->left_msecs = 0; | 178 | line->left_msecs = 0; |
188 | 179 | ||
@@ -225,7 +216,6 @@ static int pblk_recov_read_oob(struct pblk *pblk, struct pblk_line *line, | |||
225 | int rq_ppas, rq_len; | 216 | int rq_ppas, rq_len; |
226 | int i, j; | 217 | int i, j; |
227 | int ret = 0; | 218 | int ret = 0; |
228 | DECLARE_COMPLETION_ONSTACK(wait); | ||
229 | 219 | ||
230 | ppa_list = p.ppa_list; | 220 | ppa_list = p.ppa_list; |
231 | meta_list = p.meta_list; | 221 | meta_list = p.meta_list; |
@@ -262,8 +252,6 @@ next_read_rq: | |||
262 | rqd->ppa_list = ppa_list; | 252 | rqd->ppa_list = ppa_list; |
263 | rqd->dma_ppa_list = dma_ppa_list; | 253 | rqd->dma_ppa_list = dma_ppa_list; |
264 | rqd->dma_meta_list = dma_meta_list; | 254 | rqd->dma_meta_list = dma_meta_list; |
265 | rqd->end_io = pblk_end_io_sync; | ||
266 | rqd->private = &wait; | ||
267 | 255 | ||
268 | if (pblk_io_aligned(pblk, rq_ppas)) | 256 | if (pblk_io_aligned(pblk, rq_ppas)) |
269 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); | 257 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); |
@@ -289,19 +277,13 @@ next_read_rq: | |||
289 | } | 277 | } |
290 | 278 | ||
291 | /* If read fails, more padding is needed */ | 279 | /* If read fails, more padding is needed */ |
292 | ret = pblk_submit_io(pblk, rqd); | 280 | ret = pblk_submit_io_sync(pblk, rqd); |
293 | if (ret) { | 281 | if (ret) { |
294 | pr_err("pblk: I/O submission failed: %d\n", ret); | 282 | pr_err("pblk: I/O submission failed: %d\n", ret); |
295 | return ret; | 283 | return ret; |
296 | } | 284 | } |
297 | 285 | ||
298 | if (!wait_for_completion_io_timeout(&wait, | ||
299 | msecs_to_jiffies(PBLK_COMMAND_TIMEOUT_MS))) { | ||
300 | pr_err("pblk: L2P recovery read timed out\n"); | ||
301 | return -EINTR; | ||
302 | } | ||
303 | atomic_dec(&pblk->inflight_io); | 286 | atomic_dec(&pblk->inflight_io); |
304 | reinit_completion(&wait); | ||
305 | 287 | ||
306 | /* At this point, the read should not fail. If it does, it is a problem | 288 | /* At this point, the read should not fail. If it does, it is a problem |
307 | * we cannot recover from here. Need FTL log. | 289 | * we cannot recover from here. Need FTL log. |
@@ -338,13 +320,10 @@ static void pblk_end_io_recov(struct nvm_rq *rqd) | |||
338 | { | 320 | { |
339 | struct pblk_pad_rq *pad_rq = rqd->private; | 321 | struct pblk_pad_rq *pad_rq = rqd->private; |
340 | struct pblk *pblk = pad_rq->pblk; | 322 | struct pblk *pblk = pad_rq->pblk; |
341 | struct nvm_tgt_dev *dev = pblk->dev; | ||
342 | 323 | ||
343 | pblk_up_page(pblk, rqd->ppa_list, rqd->nr_ppas); | 324 | pblk_up_page(pblk, rqd->ppa_list, rqd->nr_ppas); |
344 | 325 | ||
345 | bio_put(rqd->bio); | 326 | pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT); |
346 | nvm_dev_dma_free(dev->parent, rqd->meta_list, rqd->dma_meta_list); | ||
347 | pblk_free_rqd(pblk, rqd, WRITE); | ||
348 | 327 | ||
349 | atomic_dec(&pblk->inflight_io); | 328 | atomic_dec(&pblk->inflight_io); |
350 | kref_put(&pad_rq->ref, pblk_recov_complete); | 329 | kref_put(&pad_rq->ref, pblk_recov_complete); |
@@ -404,25 +383,21 @@ next_pad_rq: | |||
404 | ppa_list = (void *)(meta_list) + pblk_dma_meta_size; | 383 | ppa_list = (void *)(meta_list) + pblk_dma_meta_size; |
405 | dma_ppa_list = dma_meta_list + pblk_dma_meta_size; | 384 | dma_ppa_list = dma_meta_list + pblk_dma_meta_size; |
406 | 385 | ||
407 | rqd = pblk_alloc_rqd(pblk, WRITE); | ||
408 | if (IS_ERR(rqd)) { | ||
409 | ret = PTR_ERR(rqd); | ||
410 | goto fail_free_meta; | ||
411 | } | ||
412 | |||
413 | bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len, | 386 | bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len, |
414 | PBLK_VMALLOC_META, GFP_KERNEL); | 387 | PBLK_VMALLOC_META, GFP_KERNEL); |
415 | if (IS_ERR(bio)) { | 388 | if (IS_ERR(bio)) { |
416 | ret = PTR_ERR(bio); | 389 | ret = PTR_ERR(bio); |
417 | goto fail_free_rqd; | 390 | goto fail_free_meta; |
418 | } | 391 | } |
419 | 392 | ||
420 | bio->bi_iter.bi_sector = 0; /* internal bio */ | 393 | bio->bi_iter.bi_sector = 0; /* internal bio */ |
421 | bio_set_op_attrs(bio, REQ_OP_WRITE, 0); | 394 | bio_set_op_attrs(bio, REQ_OP_WRITE, 0); |
422 | 395 | ||
396 | rqd = pblk_alloc_rqd(pblk, PBLK_WRITE_INT); | ||
397 | |||
423 | rqd->bio = bio; | 398 | rqd->bio = bio; |
424 | rqd->opcode = NVM_OP_PWRITE; | 399 | rqd->opcode = NVM_OP_PWRITE; |
425 | rqd->flags = pblk_set_progr_mode(pblk, WRITE); | 400 | rqd->flags = pblk_set_progr_mode(pblk, PBLK_WRITE); |
426 | rqd->meta_list = meta_list; | 401 | rqd->meta_list = meta_list; |
427 | rqd->nr_ppas = rq_ppas; | 402 | rqd->nr_ppas = rq_ppas; |
428 | rqd->ppa_list = ppa_list; | 403 | rqd->ppa_list = ppa_list; |
@@ -490,8 +465,6 @@ free_rq: | |||
490 | 465 | ||
491 | fail_free_bio: | 466 | fail_free_bio: |
492 | bio_put(bio); | 467 | bio_put(bio); |
493 | fail_free_rqd: | ||
494 | pblk_free_rqd(pblk, rqd, WRITE); | ||
495 | fail_free_meta: | 468 | fail_free_meta: |
496 | nvm_dev_dma_free(dev->parent, meta_list, dma_meta_list); | 469 | nvm_dev_dma_free(dev->parent, meta_list, dma_meta_list); |
497 | fail_free_pad: | 470 | fail_free_pad: |
@@ -522,7 +495,6 @@ static int pblk_recov_scan_all_oob(struct pblk *pblk, struct pblk_line *line, | |||
522 | int ret = 0; | 495 | int ret = 0; |
523 | int rec_round; | 496 | int rec_round; |
524 | int left_ppas = pblk_calc_sec_in_line(pblk, line) - line->cur_sec; | 497 | int left_ppas = pblk_calc_sec_in_line(pblk, line) - line->cur_sec; |
525 | DECLARE_COMPLETION_ONSTACK(wait); | ||
526 | 498 | ||
527 | ppa_list = p.ppa_list; | 499 | ppa_list = p.ppa_list; |
528 | meta_list = p.meta_list; | 500 | meta_list = p.meta_list; |
@@ -557,8 +529,6 @@ next_rq: | |||
557 | rqd->ppa_list = ppa_list; | 529 | rqd->ppa_list = ppa_list; |
558 | rqd->dma_ppa_list = dma_ppa_list; | 530 | rqd->dma_ppa_list = dma_ppa_list; |
559 | rqd->dma_meta_list = dma_meta_list; | 531 | rqd->dma_meta_list = dma_meta_list; |
560 | rqd->end_io = pblk_end_io_sync; | ||
561 | rqd->private = &wait; | ||
562 | 532 | ||
563 | if (pblk_io_aligned(pblk, rq_ppas)) | 533 | if (pblk_io_aligned(pblk, rq_ppas)) |
564 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); | 534 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); |
@@ -584,18 +554,13 @@ next_rq: | |||
584 | addr_to_gen_ppa(pblk, w_ptr, line->id); | 554 | addr_to_gen_ppa(pblk, w_ptr, line->id); |
585 | } | 555 | } |
586 | 556 | ||
587 | ret = pblk_submit_io(pblk, rqd); | 557 | ret = pblk_submit_io_sync(pblk, rqd); |
588 | if (ret) { | 558 | if (ret) { |
589 | pr_err("pblk: I/O submission failed: %d\n", ret); | 559 | pr_err("pblk: I/O submission failed: %d\n", ret); |
590 | return ret; | 560 | return ret; |
591 | } | 561 | } |
592 | 562 | ||
593 | if (!wait_for_completion_io_timeout(&wait, | ||
594 | msecs_to_jiffies(PBLK_COMMAND_TIMEOUT_MS))) { | ||
595 | pr_err("pblk: L2P recovery read timed out\n"); | ||
596 | } | ||
597 | atomic_dec(&pblk->inflight_io); | 563 | atomic_dec(&pblk->inflight_io); |
598 | reinit_completion(&wait); | ||
599 | 564 | ||
600 | /* This should not happen since the read failed during normal recovery, | 565 | /* This should not happen since the read failed during normal recovery, |
601 | * but the media works funny sometimes... | 566 | * but the media works funny sometimes... |
@@ -663,7 +628,6 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line, | |||
663 | int i, j; | 628 | int i, j; |
664 | int ret = 0; | 629 | int ret = 0; |
665 | int left_ppas = pblk_calc_sec_in_line(pblk, line); | 630 | int left_ppas = pblk_calc_sec_in_line(pblk, line); |
666 | DECLARE_COMPLETION_ONSTACK(wait); | ||
667 | 631 | ||
668 | ppa_list = p.ppa_list; | 632 | ppa_list = p.ppa_list; |
669 | meta_list = p.meta_list; | 633 | meta_list = p.meta_list; |
@@ -696,8 +660,6 @@ next_rq: | |||
696 | rqd->ppa_list = ppa_list; | 660 | rqd->ppa_list = ppa_list; |
697 | rqd->dma_ppa_list = dma_ppa_list; | 661 | rqd->dma_ppa_list = dma_ppa_list; |
698 | rqd->dma_meta_list = dma_meta_list; | 662 | rqd->dma_meta_list = dma_meta_list; |
699 | rqd->end_io = pblk_end_io_sync; | ||
700 | rqd->private = &wait; | ||
701 | 663 | ||
702 | if (pblk_io_aligned(pblk, rq_ppas)) | 664 | if (pblk_io_aligned(pblk, rq_ppas)) |
703 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); | 665 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); |
@@ -723,19 +685,14 @@ next_rq: | |||
723 | addr_to_gen_ppa(pblk, paddr, line->id); | 685 | addr_to_gen_ppa(pblk, paddr, line->id); |
724 | } | 686 | } |
725 | 687 | ||
726 | ret = pblk_submit_io(pblk, rqd); | 688 | ret = pblk_submit_io_sync(pblk, rqd); |
727 | if (ret) { | 689 | if (ret) { |
728 | pr_err("pblk: I/O submission failed: %d\n", ret); | 690 | pr_err("pblk: I/O submission failed: %d\n", ret); |
729 | bio_put(bio); | 691 | bio_put(bio); |
730 | return ret; | 692 | return ret; |
731 | } | 693 | } |
732 | 694 | ||
733 | if (!wait_for_completion_io_timeout(&wait, | ||
734 | msecs_to_jiffies(PBLK_COMMAND_TIMEOUT_MS))) { | ||
735 | pr_err("pblk: L2P recovery read timed out\n"); | ||
736 | } | ||
737 | atomic_dec(&pblk->inflight_io); | 695 | atomic_dec(&pblk->inflight_io); |
738 | reinit_completion(&wait); | ||
739 | 696 | ||
740 | /* Reached the end of the written line */ | 697 | /* Reached the end of the written line */ |
741 | if (rqd->error) { | 698 | if (rqd->error) { |
@@ -785,15 +742,9 @@ static int pblk_recov_l2p_from_oob(struct pblk *pblk, struct pblk_line *line) | |||
785 | dma_addr_t dma_ppa_list, dma_meta_list; | 742 | dma_addr_t dma_ppa_list, dma_meta_list; |
786 | int done, ret = 0; | 743 | int done, ret = 0; |
787 | 744 | ||
788 | rqd = pblk_alloc_rqd(pblk, READ); | ||
789 | if (IS_ERR(rqd)) | ||
790 | return PTR_ERR(rqd); | ||
791 | |||
792 | meta_list = nvm_dev_dma_alloc(dev->parent, GFP_KERNEL, &dma_meta_list); | 745 | meta_list = nvm_dev_dma_alloc(dev->parent, GFP_KERNEL, &dma_meta_list); |
793 | if (!meta_list) { | 746 | if (!meta_list) |
794 | ret = -ENOMEM; | 747 | return -ENOMEM; |
795 | goto free_rqd; | ||
796 | } | ||
797 | 748 | ||
798 | ppa_list = (void *)(meta_list) + pblk_dma_meta_size; | 749 | ppa_list = (void *)(meta_list) + pblk_dma_meta_size; |
799 | dma_ppa_list = dma_meta_list + pblk_dma_meta_size; | 750 | dma_ppa_list = dma_meta_list + pblk_dma_meta_size; |
@@ -804,6 +755,8 @@ static int pblk_recov_l2p_from_oob(struct pblk *pblk, struct pblk_line *line) | |||
804 | goto free_meta_list; | 755 | goto free_meta_list; |
805 | } | 756 | } |
806 | 757 | ||
758 | rqd = pblk_alloc_rqd(pblk, PBLK_READ); | ||
759 | |||
807 | p.ppa_list = ppa_list; | 760 | p.ppa_list = ppa_list; |
808 | p.meta_list = meta_list; | 761 | p.meta_list = meta_list; |
809 | p.rqd = rqd; | 762 | p.rqd = rqd; |
@@ -832,8 +785,6 @@ out: | |||
832 | kfree(data); | 785 | kfree(data); |
833 | free_meta_list: | 786 | free_meta_list: |
834 | nvm_dev_dma_free(dev->parent, meta_list, dma_meta_list); | 787 | nvm_dev_dma_free(dev->parent, meta_list, dma_meta_list); |
835 | free_rqd: | ||
836 | pblk_free_rqd(pblk, rqd, READ); | ||
837 | 788 | ||
838 | return ret; | 789 | return ret; |
839 | } | 790 | } |
@@ -851,11 +802,33 @@ static void pblk_recov_line_add_ordered(struct list_head *head, | |||
851 | __list_add(&line->list, t->list.prev, &t->list); | 802 | __list_add(&line->list, t->list.prev, &t->list); |
852 | } | 803 | } |
853 | 804 | ||
854 | struct pblk_line *pblk_recov_l2p(struct pblk *pblk) | 805 | static u64 pblk_line_emeta_start(struct pblk *pblk, struct pblk_line *line) |
855 | { | 806 | { |
856 | struct nvm_tgt_dev *dev = pblk->dev; | 807 | struct nvm_tgt_dev *dev = pblk->dev; |
857 | struct nvm_geo *geo = &dev->geo; | 808 | struct nvm_geo *geo = &dev->geo; |
858 | struct pblk_line_meta *lm = &pblk->lm; | 809 | struct pblk_line_meta *lm = &pblk->lm; |
810 | unsigned int emeta_secs; | ||
811 | u64 emeta_start; | ||
812 | struct ppa_addr ppa; | ||
813 | int pos; | ||
814 | |||
815 | emeta_secs = lm->emeta_sec[0]; | ||
816 | emeta_start = lm->sec_per_line; | ||
817 | |||
818 | while (emeta_secs) { | ||
819 | emeta_start--; | ||
820 | ppa = addr_to_pblk_ppa(pblk, emeta_start, line->id); | ||
821 | pos = pblk_ppa_to_pos(geo, ppa); | ||
822 | if (!test_bit(pos, line->blk_bitmap)) | ||
823 | emeta_secs--; | ||
824 | } | ||
825 | |||
826 | return emeta_start; | ||
827 | } | ||
828 | |||
829 | struct pblk_line *pblk_recov_l2p(struct pblk *pblk) | ||
830 | { | ||
831 | struct pblk_line_meta *lm = &pblk->lm; | ||
859 | struct pblk_line_mgmt *l_mg = &pblk->l_mg; | 832 | struct pblk_line_mgmt *l_mg = &pblk->l_mg; |
860 | struct pblk_line *line, *tline, *data_line = NULL; | 833 | struct pblk_line *line, *tline, *data_line = NULL; |
861 | struct pblk_smeta *smeta; | 834 | struct pblk_smeta *smeta; |
@@ -900,9 +873,9 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk) | |||
900 | if (le32_to_cpu(smeta_buf->header.identifier) != PBLK_MAGIC) | 873 | if (le32_to_cpu(smeta_buf->header.identifier) != PBLK_MAGIC) |
901 | continue; | 874 | continue; |
902 | 875 | ||
903 | if (le16_to_cpu(smeta_buf->header.version) != 1) { | 876 | if (smeta_buf->header.version != SMETA_VERSION) { |
904 | pr_err("pblk: found incompatible line version %u\n", | 877 | pr_err("pblk: found incompatible line version %u\n", |
905 | smeta_buf->header.version); | 878 | le16_to_cpu(smeta_buf->header.version)); |
906 | return ERR_PTR(-EINVAL); | 879 | return ERR_PTR(-EINVAL); |
907 | } | 880 | } |
908 | 881 | ||
@@ -954,15 +927,9 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk) | |||
954 | 927 | ||
955 | /* Verify closed blocks and recover this portion of L2P table*/ | 928 | /* Verify closed blocks and recover this portion of L2P table*/ |
956 | list_for_each_entry_safe(line, tline, &recov_list, list) { | 929 | list_for_each_entry_safe(line, tline, &recov_list, list) { |
957 | int off, nr_bb; | ||
958 | |||
959 | recovered_lines++; | 930 | recovered_lines++; |
960 | /* Calculate where emeta starts based on the line bb */ | ||
961 | off = lm->sec_per_line - lm->emeta_sec[0]; | ||
962 | nr_bb = bitmap_weight(line->blk_bitmap, lm->blk_per_line); | ||
963 | off -= nr_bb * geo->sec_per_pl; | ||
964 | 931 | ||
965 | line->emeta_ssec = off; | 932 | line->emeta_ssec = pblk_line_emeta_start(pblk, line); |
966 | line->emeta = emeta; | 933 | line->emeta = emeta; |
967 | memset(line->emeta->buf, 0, lm->emeta_len[0]); | 934 | memset(line->emeta->buf, 0, lm->emeta_len[0]); |
968 | 935 | ||
@@ -987,7 +954,7 @@ next: | |||
987 | list_move_tail(&line->list, move_list); | 954 | list_move_tail(&line->list, move_list); |
988 | spin_unlock(&l_mg->gc_lock); | 955 | spin_unlock(&l_mg->gc_lock); |
989 | 956 | ||
990 | mempool_free(line->map_bitmap, pblk->line_meta_pool); | 957 | kfree(line->map_bitmap); |
991 | line->map_bitmap = NULL; | 958 | line->map_bitmap = NULL; |
992 | line->smeta = NULL; | 959 | line->smeta = NULL; |
993 | line->emeta = NULL; | 960 | line->emeta = NULL; |