diff options
-rw-r--r-- | fs/bcachefs/journal_io.c | 59 | ||||
-rw-r--r-- | fs/bcachefs/journal_io.h | 7 |
2 files changed, 45 insertions, 21 deletions
diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c index dd3f3434c1b0..1d4c7e0a0240 100644 --- a/fs/bcachefs/journal_io.c +++ b/fs/bcachefs/journal_io.c @@ -1272,6 +1272,34 @@ static void bch2_journal_print_checksum_error(struct bch_fs *c, struct journal_r printbuf_exit(&buf); } +struct u64_range bch2_journal_entry_missing_range(struct bch_fs *c, u64 start, u64 end) +{ + BUG_ON(start > end); + + if (start == end) + return (struct u64_range) {}; + + while (start < end && + bch2_journal_seq_is_blacklisted(c, start, false)) + start++; + + if (start == end) + return (struct u64_range) {}; + + struct u64_range missing = { .start = start }; + + while (start < end && + !bch2_journal_seq_is_blacklisted(c, start, false)) + start++; + + missing.end = start - 1; + + if (missing.start == missing.end) + return (struct u64_range) {}; + + return missing; +} + noinline_for_stack static int bch2_journal_check_for_missing(struct bch_fs *c, u64 start_seq, u64 end_seq) { @@ -1280,6 +1308,7 @@ static int bch2_journal_check_for_missing(struct bch_fs *c, u64 start_seq, u64 e struct genradix_iter radix_iter; struct journal_replay *i, **_i, *prev = NULL; + /* Sequence number we expect to find next, to check for missing entries */ u64 seq = start_seq; genradix_for_each(&c->journal_entries, radix_iter, _i) { @@ -1290,43 +1319,31 @@ static int bch2_journal_check_for_missing(struct bch_fs *c, u64 start_seq, u64 e BUG_ON(seq > le64_to_cpu(i->j.seq)); - while (seq < le64_to_cpu(i->j.seq)) { - while (seq < le64_to_cpu(i->j.seq) && - bch2_journal_seq_is_blacklisted(c, seq, false)) - seq++; - - if (seq == le64_to_cpu(i->j.seq)) - break; - - u64 missing_start = seq; - - while (seq < le64_to_cpu(i->j.seq) && - !bch2_journal_seq_is_blacklisted(c, seq, false)) - seq++; - - u64 missing_end = seq - 1; + struct u64_range missing; + while ((missing = bch2_journal_entry_missing_range(c, seq, le64_to_cpu(i->j.seq))).start) { printbuf_reset(&buf); prt_printf(&buf, "journal entries %llu-%llu missing! (replaying %llu-%llu)", - missing_start, missing_end, + missing.start, missing.end, start_seq, end_seq); - prt_printf(&buf, "\nprev at "); if (prev) { + prt_printf(&buf, "\n%llu at ", le64_to_cpu(prev->j.seq)); bch2_journal_ptrs_to_text(&buf, c, prev); prt_printf(&buf, " size %zu", vstruct_sectors(&prev->j, c->block_bits)); - } else - prt_printf(&buf, "(none)"); + } - prt_printf(&buf, "\nnext at "); + prt_printf(&buf, "\n%llu at ", le64_to_cpu(i->j.seq)); bch2_journal_ptrs_to_text(&buf, c, i); prt_printf(&buf, ", continue?"); fsck_err(c, journal_entries_missing, "%s", buf.buf); + + seq = missing.end + 1; } prev = i; - seq++; + seq = le64_to_cpu(i->j.seq) + 1; } fsck_err: printbuf_exit(&buf); diff --git a/fs/bcachefs/journal_io.h b/fs/bcachefs/journal_io.h index 6fa82c4050fe..f53c5c81d137 100644 --- a/fs/bcachefs/journal_io.h +++ b/fs/bcachefs/journal_io.h @@ -71,6 +71,13 @@ void bch2_journal_entry_to_text(struct printbuf *, struct bch_fs *, void bch2_journal_ptrs_to_text(struct printbuf *, struct bch_fs *, struct journal_replay *); +struct u64_range { + u64 start; + u64 end; +}; + +struct u64_range bch2_journal_entry_missing_range(struct bch_fs *, u64, u64); + int bch2_journal_read(struct bch_fs *, u64 *, u64 *, u64 *); CLOSURE_CALLBACK(bch2_journal_write); |