summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-08-11 19:30:38 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-08-14 12:28:44 -0400
commit419b6323982b7ff9f9d5da4076898be5cb0b42fe (patch)
tree945a2e7dd2e0929cab5d9af99296744909919130
parent279ee1e15b17663dce42c68de4792bdef64c1e5b (diff)
bcachefs: Fix 'journal not marked as containing replicas'
This fixes the replicas_write_errors test: the patch bcachefs: mark journal replicas before journal write submission partially fixed replicas marking for the journal, but it broke the case where one replica failed - this patch re-adds marking after the journal write completes, when we know how many replicas succeeded. Additionally, we do not consider it a fsck error when the very last journal entry is not correctly marked, since there is an inherent race there. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/journal_io.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c
index 378b3f9170d4..50a7c3330807 100644
--- a/fs/bcachefs/journal_io.c
+++ b/fs/bcachefs/journal_io.c
@@ -1305,18 +1305,14 @@ int bch2_journal_read(struct bch_fs *c,
bch2_replicas_entry_sort(&replicas.e);
- /*
- * If we're mounting in degraded mode - if we didn't read all
- * the devices - this is wrong:
- */
-
printbuf_reset(&buf);
bch2_replicas_entry_to_text(&buf, &replicas.e);
if (!degraded &&
- fsck_err_on(!bch2_replicas_marked(c, &replicas.e), c,
- "superblock not marked as containing replicas %s",
- buf.buf)) {
+ !bch2_replicas_marked(c, &replicas.e) &&
+ (le64_to_cpu(i->j.seq) == *last_seq ||
+ fsck_err(c, "superblock not marked as containing replicas for journal entry %llu\n %s",
+ le64_to_cpu(i->j.seq), buf.buf))) {
ret = bch2_mark_replicas(c, &replicas.e);
if (ret)
goto err;
@@ -1483,6 +1479,7 @@ static void journal_write_done(struct closure *cl)
struct journal *j = container_of(cl, struct journal, io);
struct bch_fs *c = container_of(j, struct bch_fs, journal);
struct journal_buf *w = journal_last_unwritten_buf(j);
+ struct bch_replicas_padded replicas;
union journal_res_state old, new;
u64 v, seq;
int err = 0;
@@ -1494,7 +1491,13 @@ static void journal_write_done(struct closure *cl)
if (!w->devs_written.nr) {
bch_err(c, "unable to write journal to sufficient devices");
err = -EIO;
+ } else {
+ bch2_devlist_to_replicas(&replicas.e, BCH_DATA_journal,
+ w->devs_written);
+ if (bch2_mark_replicas(c, &replicas.e))
+ err = -EIO;
}
+
if (err)
bch2_fatal_error(c);