This patch ensures that smeta/emeta was written properly before even trying to read it based on chunk table state and write pointer. Signed-off-by: Igor Konopko <igor.j.konopko@xxxxxxxxx> --- drivers/lightnvm/pblk-recovery.c | 43 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c index 688fdeb..ba1691d 100644 --- a/drivers/lightnvm/pblk-recovery.c +++ b/drivers/lightnvm/pblk-recovery.c @@ -653,8 +653,42 @@ static int pblk_line_was_written(struct pblk_line *line, bppa = pblk->luns[smeta_blk].bppa; chunk = &line->chks[pblk_ppa_to_pos(geo, bppa)]; - if (chunk->state & NVM_CHK_ST_FREE) - return 0; + if (chunk->state & NVM_CHK_ST_CLOSED || + (chunk->state & NVM_CHK_ST_OPEN + && chunk->wp >= lm->smeta_sec)) + return 1; + + return 0; +} + +static int pblk_line_was_emeta_written(struct pblk_line *line, + struct pblk *pblk) +{ + + struct pblk_line_meta *lm = &pblk->lm; + struct nvm_tgt_dev *dev = pblk->dev; + struct nvm_geo *geo = &dev->geo; + struct nvm_chk_meta *chunk; + struct ppa_addr ppa; + int i, pos; + int min = pblk->min_write_pgs; + u64 paddr = line->emeta_ssec; + + for (i = 0; i < lm->emeta_sec[0]; i++, paddr++) { + ppa = addr_to_gen_ppa(pblk, paddr, line->id); + pos = pblk_ppa_to_pos(geo, ppa); + while (test_bit(pos, line->blk_bitmap)) { + paddr += min; + ppa = addr_to_gen_ppa(pblk, paddr, line->id); + pos = pblk_ppa_to_pos(geo, ppa); + } + chunk = &line->chks[pos]; + + if (!(chunk->state & NVM_CHK_ST_CLOSED || + (chunk->state & NVM_CHK_ST_OPEN + && chunk->wp > ppa.m.sec))) + return 0; + } return 1; } @@ -788,6 +822,11 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk) goto next; } + if (!pblk_line_was_emeta_written(line, pblk)) { + pblk_recov_l2p_from_oob(pblk, line); + goto next; + } + if (pblk_line_emeta_read(pblk, line, line->emeta->buf)) { pblk_recov_l2p_from_oob(pblk, line); goto next; -- 2.9.5