diff options
author | Hans Holmberg <hans.holmberg@cnexlabs.com> | 2018-06-01 10:41:12 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-06-01 11:02:53 -0400 |
commit | b06be2873d916e58c00ecfa664c22a75fa721260 (patch) | |
tree | 6a966747ebf3e2a747834718e7a9ba93780e14e2 | |
parent | 87cc40bbe3371d0af1a2f31bf90665b55d3d1c0d (diff) |
lightnvm: pblk: only try to recover lines with written smeta
When switching between different lun configurations, there is no
guarantee that all lines that contain closed/open chunks have some
valid data to recover.
Check that the smeta chunk has been written to instead. Also
skip bad lines (that does not have enough good chunks).
Signed-off-by: Hans Holmberg <hans.holmberg@cnexlabs.com>
Signed-off-by: Matias Bjørling <mb@lightnvm.io>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | drivers/lightnvm/pblk-recovery.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c index 788dce87043e..598342833d0d 100644 --- a/drivers/lightnvm/pblk-recovery.c +++ b/drivers/lightnvm/pblk-recovery.c | |||
@@ -774,18 +774,30 @@ static void pblk_recov_wa_counters(struct pblk *pblk, | |||
774 | } | 774 | } |
775 | 775 | ||
776 | static int pblk_line_was_written(struct pblk_line *line, | 776 | static int pblk_line_was_written(struct pblk_line *line, |
777 | struct pblk_line_meta *lm) | 777 | struct pblk *pblk) |
778 | { | 778 | { |
779 | 779 | ||
780 | int i; | 780 | struct pblk_line_meta *lm = &pblk->lm; |
781 | int state_mask = NVM_CHK_ST_OFFLINE | NVM_CHK_ST_FREE; | 781 | struct nvm_tgt_dev *dev = pblk->dev; |
782 | struct nvm_geo *geo = &dev->geo; | ||
783 | struct nvm_chk_meta *chunk; | ||
784 | struct ppa_addr bppa; | ||
785 | int smeta_blk; | ||
782 | 786 | ||
783 | for (i = 0; i < lm->blk_per_line; i++) { | 787 | if (line->state == PBLK_LINESTATE_BAD) |
784 | if (!(line->chks[i].state & state_mask)) | 788 | return 0; |
785 | return 1; | ||
786 | } | ||
787 | 789 | ||
788 | return 0; | 790 | smeta_blk = find_first_zero_bit(line->blk_bitmap, lm->blk_per_line); |
791 | if (smeta_blk >= lm->blk_per_line) | ||
792 | return 0; | ||
793 | |||
794 | bppa = pblk->luns[smeta_blk].bppa; | ||
795 | chunk = &line->chks[pblk_ppa_to_pos(geo, bppa)]; | ||
796 | |||
797 | if (chunk->state & NVM_CHK_ST_FREE) | ||
798 | return 0; | ||
799 | |||
800 | return 1; | ||
789 | } | 801 | } |
790 | 802 | ||
791 | struct pblk_line *pblk_recov_l2p(struct pblk *pblk) | 803 | struct pblk_line *pblk_recov_l2p(struct pblk *pblk) |
@@ -824,7 +836,7 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk) | |||
824 | line->lun_bitmap = ((void *)(smeta_buf)) + | 836 | line->lun_bitmap = ((void *)(smeta_buf)) + |
825 | sizeof(struct line_smeta); | 837 | sizeof(struct line_smeta); |
826 | 838 | ||
827 | if (!pblk_line_was_written(line, lm)) | 839 | if (!pblk_line_was_written(line, pblk)) |
828 | continue; | 840 | continue; |
829 | 841 | ||
830 | /* Lines that cannot be read are assumed as not written here */ | 842 | /* Lines that cannot be read are assumed as not written here */ |