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>
This commit is contained in:
committed by
Jens Axboe
parent
87cc40bbe3
commit
b06be2873d
@@ -774,18 +774,30 @@ static void pblk_recov_wa_counters(struct pblk *pblk,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int pblk_line_was_written(struct pblk_line *line,
|
static int pblk_line_was_written(struct pblk_line *line,
|
||||||
struct pblk_line_meta *lm)
|
struct pblk *pblk)
|
||||||
{
|
{
|
||||||
|
|
||||||
int i;
|
struct pblk_line_meta *lm = &pblk->lm;
|
||||||
int state_mask = NVM_CHK_ST_OFFLINE | NVM_CHK_ST_FREE;
|
struct nvm_tgt_dev *dev = pblk->dev;
|
||||||
|
struct nvm_geo *geo = &dev->geo;
|
||||||
for (i = 0; i < lm->blk_per_line; i++) {
|
struct nvm_chk_meta *chunk;
|
||||||
if (!(line->chks[i].state & state_mask))
|
struct ppa_addr bppa;
|
||||||
return 1;
|
int smeta_blk;
|
||||||
}
|
|
||||||
|
|
||||||
|
if (line->state == PBLK_LINESTATE_BAD)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
smeta_blk = find_first_zero_bit(line->blk_bitmap, lm->blk_per_line);
|
||||||
|
if (smeta_blk >= lm->blk_per_line)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bppa = pblk->luns[smeta_blk].bppa;
|
||||||
|
chunk = &line->chks[pblk_ppa_to_pos(geo, bppa)];
|
||||||
|
|
||||||
|
if (chunk->state & NVM_CHK_ST_FREE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
|
struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
|
||||||
@@ -824,7 +836,7 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
|
|||||||
line->lun_bitmap = ((void *)(smeta_buf)) +
|
line->lun_bitmap = ((void *)(smeta_buf)) +
|
||||||
sizeof(struct line_smeta);
|
sizeof(struct line_smeta);
|
||||||
|
|
||||||
if (!pblk_line_was_written(line, lm))
|
if (!pblk_line_was_written(line, pblk))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Lines that cannot be read are assumed as not written here */
|
/* Lines that cannot be read are assumed as not written here */
|
||||||
|
|||||||
Reference in New Issue
Block a user