Commit dab1e248 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: Handle last journal write being torn

If the last journal write didn't complete sucessfully due to a torn
write, we'll detect it as a checksum error. In that case, we should just
pretend that journal entry was never written.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent ff56d68c
...@@ -1106,7 +1106,7 @@ int bch2_journal_read(struct bch_fs *c, u64 *blacklist_seq, u64 *start_seq) ...@@ -1106,7 +1106,7 @@ int bch2_journal_read(struct bch_fs *c, u64 *blacklist_seq, u64 *start_seq)
struct bch_dev *ca; struct bch_dev *ca;
unsigned iter; unsigned iter;
struct printbuf buf = PRINTBUF; struct printbuf buf = PRINTBUF;
bool degraded = false; bool degraded = false, last_write_torn = false;
u64 seq, last_seq = 0; u64 seq, last_seq = 0;
int ret = 0; int ret = 0;
...@@ -1142,8 +1142,13 @@ int bch2_journal_read(struct bch_fs *c, u64 *blacklist_seq, u64 *start_seq) ...@@ -1142,8 +1142,13 @@ 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 - * Find most recent flush entry, and ignore newer non flush entries -
* those entries will be blacklisted: * those entries will be blacklisted:
*
*
* XXX check for torn write on last journal entry
*/ */
genradix_for_each_reverse(&c->journal_entries, radix_iter, _i) { genradix_for_each_reverse(&c->journal_entries, radix_iter, _i) {
int write = READ;
i = *_i; i = *_i;
if (!i || i->ignore) if (!i || i->ignore)
...@@ -1152,8 +1157,17 @@ int bch2_journal_read(struct bch_fs *c, u64 *blacklist_seq, u64 *start_seq) ...@@ -1152,8 +1157,17 @@ int bch2_journal_read(struct bch_fs *c, u64 *blacklist_seq, u64 *start_seq)
if (!*start_seq) if (!*start_seq)
*blacklist_seq = *start_seq = le64_to_cpu(i->j.seq) + 1; *blacklist_seq = *start_seq = le64_to_cpu(i->j.seq) + 1;
if (!JSET_NO_FLUSH(&i->j)) { if (JSET_NO_FLUSH(&i->j)) {
int write = READ; journal_replay_free(c, i);
continue;
}
if (!last_write_torn && !i->csum_good) {
last_write_torn = true;
journal_replay_free(c, i);
continue;
}
if (journal_entry_err_on(le64_to_cpu(i->j.last_seq) > le64_to_cpu(i->j.seq), if (journal_entry_err_on(le64_to_cpu(i->j.last_seq) > le64_to_cpu(i->j.seq),
c, &i->j, NULL, c, &i->j, NULL,
"invalid journal entry: last_seq > seq (%llu > %llu)", "invalid journal entry: last_seq > seq (%llu > %llu)",
...@@ -1166,9 +1180,6 @@ int bch2_journal_read(struct bch_fs *c, u64 *blacklist_seq, u64 *start_seq) ...@@ -1166,9 +1180,6 @@ int bch2_journal_read(struct bch_fs *c, u64 *blacklist_seq, u64 *start_seq)
break; break;
} }
journal_replay_free(c, i);
}
if (!*start_seq) { if (!*start_seq) {
bch_info(c, "journal read done, but no entries found"); bch_info(c, "journal read done, but no entries found");
return 0; return 0;
......
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