|
@@ -774,18 +774,30 @@ static void pblk_recov_wa_counters(struct pblk *pblk,
|
|
|
}
|
|
|
|
|
|
static int pblk_line_was_written(struct pblk_line *line,
|
|
|
- struct pblk_line_meta *lm)
|
|
|
+ struct pblk *pblk)
|
|
|
{
|
|
|
|
|
|
- int i;
|
|
|
- int state_mask = NVM_CHK_ST_OFFLINE | NVM_CHK_ST_FREE;
|
|
|
+ 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 bppa;
|
|
|
+ int smeta_blk;
|
|
|
|
|
|
- for (i = 0; i < lm->blk_per_line; i++) {
|
|
|
- if (!(line->chks[i].state & state_mask))
|
|
|
- return 1;
|
|
|
- }
|
|
|
+ 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)
|
|
@@ -824,7 +836,7 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
|
|
|
line->lun_bitmap = ((void *)(smeta_buf)) +
|
|
|
sizeof(struct line_smeta);
|
|
|
|
|
|
- if (!pblk_line_was_written(line, lm))
|
|
|
+ if (!pblk_line_was_written(line, pblk))
|
|
|
continue;
|
|
|
|
|
|
/* Lines that cannot be read are assumed as not written here */
|