aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Holmberg <hans.holmberg@cnexlabs.com>2018-06-01 10:41:12 -0400
committerJens Axboe <axboe@kernel.dk>2018-06-01 11:02:53 -0400
commitb06be2873d916e58c00ecfa664c22a75fa721260 (patch)
tree6a966747ebf3e2a747834718e7a9ba93780e14e2
parent87cc40bbe3371d0af1a2f31bf90665b55d3d1c0d (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.c30
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
776static int pblk_line_was_written(struct pblk_line *line, 776static 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
791struct pblk_line *pblk_recov_l2p(struct pblk *pblk) 803struct 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 */