UBIFS: always cleanup the recovered LEB
Now when we call 'ubifs_recover_leb()' only for LEBs which are potentially corrupted (i.e., only for last buds, not for all of them), we can cleanup every LEB, not only those where we find corruption. The reason - unstable bits. Even though the LEB may look good now, it might contain unstable bits which may hit us a bit later. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This commit is contained in:
Родитель
6179920695
Коммит
7c47bfd0db
|
@ -609,7 +609,7 @@ static int drop_incomplete_group(struct ubifs_scan_leb *sleb, int *offs)
|
||||||
struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
|
struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
|
||||||
int offs, void *sbuf, int grouped)
|
int offs, void *sbuf, int grouped)
|
||||||
{
|
{
|
||||||
int ret = 0, err, len = c->leb_size - offs, need_clean = 0;
|
int ret = 0, err, len = c->leb_size - offs;
|
||||||
int start = offs;
|
int start = offs;
|
||||||
struct ubifs_scan_leb *sleb;
|
struct ubifs_scan_leb *sleb;
|
||||||
void *buf = sbuf + offs;
|
void *buf = sbuf + offs;
|
||||||
|
@ -620,9 +620,6 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
|
||||||
if (IS_ERR(sleb))
|
if (IS_ERR(sleb))
|
||||||
return sleb;
|
return sleb;
|
||||||
|
|
||||||
if (sleb->ecc)
|
|
||||||
need_clean = 1;
|
|
||||||
|
|
||||||
while (len >= 8) {
|
while (len >= 8) {
|
||||||
dbg_scan("look at LEB %d:%d (%d bytes left)",
|
dbg_scan("look at LEB %d:%d (%d bytes left)",
|
||||||
lnum, offs, len);
|
lnum, offs, len);
|
||||||
|
@ -665,21 +662,18 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == SCANNED_GARBAGE || ret == SCANNED_A_BAD_PAD_NODE) {
|
if (ret == SCANNED_GARBAGE || ret == SCANNED_A_BAD_PAD_NODE) {
|
||||||
if (is_last_write(c, buf, offs)) {
|
if (is_last_write(c, buf, offs))
|
||||||
clean_buf(c, &buf, lnum, &offs, &len);
|
clean_buf(c, &buf, lnum, &offs, &len);
|
||||||
need_clean = 1;
|
else
|
||||||
} else
|
|
||||||
goto corrupted_rescan;
|
goto corrupted_rescan;
|
||||||
} else if (ret == SCANNED_A_CORRUPT_NODE) {
|
} else if (ret == SCANNED_A_CORRUPT_NODE) {
|
||||||
if (no_more_nodes(c, buf, len, lnum, offs)) {
|
if (no_more_nodes(c, buf, len, lnum, offs))
|
||||||
clean_buf(c, &buf, lnum, &offs, &len);
|
clean_buf(c, &buf, lnum, &offs, &len);
|
||||||
need_clean = 1;
|
else
|
||||||
} else
|
|
||||||
goto corrupted_rescan;
|
goto corrupted_rescan;
|
||||||
} else if (!is_empty(buf, len)) {
|
} else if (!is_empty(buf, len)) {
|
||||||
if (is_last_write(c, buf, offs)) {
|
if (is_last_write(c, buf, offs)) {
|
||||||
clean_buf(c, &buf, lnum, &offs, &len);
|
clean_buf(c, &buf, lnum, &offs, &len);
|
||||||
need_clean = 1;
|
|
||||||
} else {
|
} else {
|
||||||
int corruption = first_non_ff(buf, len);
|
int corruption = first_non_ff(buf, len);
|
||||||
|
|
||||||
|
@ -701,21 +695,16 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
|
||||||
buf = sbuf + offs;
|
buf = sbuf + offs;
|
||||||
len = c->leb_size - offs;
|
len = c->leb_size - offs;
|
||||||
clean_buf(c, &buf, lnum, &offs, &len);
|
clean_buf(c, &buf, lnum, &offs, &len);
|
||||||
need_clean = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offs % c->min_io_size) {
|
if (offs % c->min_io_size)
|
||||||
clean_buf(c, &buf, lnum, &offs, &len);
|
clean_buf(c, &buf, lnum, &offs, &len);
|
||||||
need_clean = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ubifs_end_scan(c, sleb, lnum, offs);
|
ubifs_end_scan(c, sleb, lnum, offs);
|
||||||
|
|
||||||
if (need_clean) {
|
|
||||||
err = fix_unclean_leb(c, sleb, start);
|
err = fix_unclean_leb(c, sleb, start);
|
||||||
if (err)
|
if (err)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
return sleb;
|
return sleb;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче