mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 22:26:55 +00:00
bcachefs: Recover from blacklisted journal entries
If it so happens that we crash while dirty, meaning we don't have the superblock clean section, and we erroneously mark a journal entry we wrote as blacklisted, we won't be able to recover. This patch fixes this by adding a fallback: if we've got no superblock clean section, and no non-ignored journal entries, we try the most recent ignored journal entry. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
14d7d61fac
commit
1ba8a796b4
2 changed files with 12 additions and 8 deletions
|
@ -1123,9 +1123,6 @@ int bch2_journal_read(struct bch_fs *c, u64 *blacklist_seq, u64 *start_seq)
|
|||
/*
|
||||
* Find most recent flush entry, and ignore newer non flush entries -
|
||||
* those entries will be blacklisted:
|
||||
*
|
||||
*
|
||||
* XXX check for torn write on last journal entry
|
||||
*/
|
||||
genradix_for_each_reverse(&c->journal_entries, radix_iter, _i) {
|
||||
int write = READ;
|
||||
|
@ -1139,13 +1136,13 @@ int bch2_journal_read(struct bch_fs *c, u64 *blacklist_seq, u64 *start_seq)
|
|||
*blacklist_seq = *start_seq = le64_to_cpu(i->j.seq) + 1;
|
||||
|
||||
if (JSET_NO_FLUSH(&i->j)) {
|
||||
journal_replay_free(c, i);
|
||||
i->ignore = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!last_write_torn && !i->csum_good) {
|
||||
last_write_torn = true;
|
||||
journal_replay_free(c, i);
|
||||
i->ignore = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1194,8 +1191,7 @@ int bch2_journal_read(struct bch_fs *c, u64 *blacklist_seq, u64 *start_seq)
|
|||
if (bch2_journal_seq_is_blacklisted(c, seq, true)) {
|
||||
fsck_err_on(!JSET_NO_FLUSH(&i->j), c,
|
||||
"found blacklisted journal entry %llu", seq);
|
||||
|
||||
journal_replay_free(c, i);
|
||||
i->ignore = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1137,7 +1137,15 @@ int bch2_fs_recovery(struct bch_fs *c)
|
|||
|
||||
if (!last_journal_entry) {
|
||||
fsck_err_on(!c->sb.clean, c, "no journal entries found");
|
||||
goto use_clean;
|
||||
if (clean)
|
||||
goto use_clean;
|
||||
|
||||
genradix_for_each_reverse(&c->journal_entries, iter, i)
|
||||
if (*i) {
|
||||
last_journal_entry = &(*i)->j;
|
||||
(*i)->ignore = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = journal_keys_sort(c);
|
||||
|
|
Loading…
Reference in a new issue