diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2022-12-14 14:47:42 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2022-12-14 15:11:34 -0500 |
commit | ca2b096ed0403f34418cd4bb3af42d19d1f21005 (patch) | |
tree | e7e65d9d85386be5e5cb0a6554b1ba2d1edd5285 | |
parent | 2c1b5516b0d942ef7181c118c65120c4f7b9e1cb (diff) |
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>
-rw-r--r-- | fs/bcachefs/journal_io.c | 10 | ||||
-rw-r--r-- | fs/bcachefs/recovery.c | 10 |
2 files changed, 12 insertions, 8 deletions
diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c index 295047d1316e..d6f259348b3d 100644 --- a/fs/bcachefs/journal_io.c +++ b/fs/bcachefs/journal_io.c @@ -1128,9 +1128,6 @@ int bch2_journal_read(struct bch_fs *c, /* * 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; @@ -1144,13 +1141,13 @@ int bch2_journal_read(struct bch_fs *c, *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; } @@ -1199,8 +1196,7 @@ int bch2_journal_read(struct bch_fs *c, 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; } } diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index 8fe2c756e973..8c1aa6d2ce45 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -1150,7 +1150,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); |