Commit cfe1c9e2 authored by Hans Holmberg's avatar Hans Holmberg Committed by Jens Axboe

lightnvm: pblk: handle bad sectors in the emeta area correctly

Unless we check if there are bad sectors in the entire emeta-area
we risk ending up with valid bitmap / available sector count inconsistency.
This results in lines with a bad chunk at the last LUN marked as bad,
so go through the whole emeta area and mark up the invalid sectors.
Signed-off-by: default avatarHans Holmberg <hans.holmberg@cnexlabs.com>
Signed-off-by: default avatarMatias Bjørling <mb@lightnvm.io>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 8f37d191
...@@ -1021,6 +1021,7 @@ static int pblk_line_init_bb(struct pblk *pblk, struct pblk_line *line, ...@@ -1021,6 +1021,7 @@ static int pblk_line_init_bb(struct pblk *pblk, struct pblk_line *line,
int nr_bb = 0; int nr_bb = 0;
u64 off; u64 off;
int bit = -1; int bit = -1;
int emeta_secs;
line->sec_in_line = lm->sec_per_line; line->sec_in_line = lm->sec_per_line;
...@@ -1055,18 +1056,18 @@ static int pblk_line_init_bb(struct pblk *pblk, struct pblk_line *line, ...@@ -1055,18 +1056,18 @@ static int pblk_line_init_bb(struct pblk *pblk, struct pblk_line *line,
/* Mark emeta metadata sectors as bad sectors. We need to consider bad /* Mark emeta metadata sectors as bad sectors. We need to consider bad
* blocks to make sure that there are enough sectors to store emeta * blocks to make sure that there are enough sectors to store emeta
*/ */
off = lm->sec_per_line - lm->emeta_sec[0]; emeta_secs = lm->emeta_sec[0];
bitmap_set(line->invalid_bitmap, off, lm->emeta_sec[0]); off = lm->sec_per_line;
while (nr_bb) { while (emeta_secs) {
off -= geo->sec_per_pl; off -= geo->sec_per_pl;
if (!test_bit(off, line->invalid_bitmap)) { if (!test_bit(off, line->invalid_bitmap)) {
bitmap_set(line->invalid_bitmap, off, geo->sec_per_pl); bitmap_set(line->invalid_bitmap, off, geo->sec_per_pl);
nr_bb--; emeta_secs -= geo->sec_per_pl;
} }
} }
line->sec_in_line -= lm->emeta_sec[0];
line->emeta_ssec = off; line->emeta_ssec = off;
line->sec_in_line -= lm->emeta_sec[0];
line->nr_valid_lbas = 0; line->nr_valid_lbas = 0;
line->left_msecs = line->sec_in_line; line->left_msecs = line->sec_in_line;
*line->vsc = cpu_to_le32(line->sec_in_line); *line->vsc = cpu_to_le32(line->sec_in_line);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment