bcachefs: Add an internal option for reading entire journal
authorKent Overstreet <kent.overstreet@gmail.com>
Sat, 13 Jun 2020 22:43:14 +0000 (18:43 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:41 +0000 (17:08 -0400)
To be used the debug tool that dumps the contents of the journal.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/journal.c
fs/bcachefs/journal_io.c
fs/bcachefs/opts.h
fs/bcachefs/recovery.c

index 767cb6f809e78ace5943373611ad031d543f32ee..cbfaec5143d8e15d8c2172f426fb76380b75ff98 100644 (file)
@@ -986,9 +986,8 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq,
        u64 last_seq = cur_seq, nr, seq;
 
        if (!list_empty(journal_entries))
-               last_seq = le64_to_cpu(list_first_entry(journal_entries,
-                                                       struct journal_replay,
-                                                       list)->j.seq);
+               last_seq = le64_to_cpu(list_last_entry(journal_entries,
+                               struct journal_replay, list)->j.last_seq);
 
        nr = cur_seq - last_seq;
 
@@ -1017,8 +1016,10 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq,
 
        list_for_each_entry(i, journal_entries, list) {
                seq = le64_to_cpu(i->j.seq);
+               BUG_ON(seq >= cur_seq);
 
-               BUG_ON(seq < last_seq || seq >= cur_seq);
+               if (seq < last_seq)
+                       continue;
 
                journal_seq_pin(j, seq)->devs = i->devs;
        }
index 1724c80b323c8046cc00e69de02096106f041d48..a1bae99aeaab7739585055e53e99bc7ebfdf496f 100644 (file)
@@ -40,19 +40,21 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca,
                                  list)->j.last_seq
                : 0;
 
-       /* Is this entry older than the range we need? */
-       if (le64_to_cpu(j->seq) < le64_to_cpu(last_seq)) {
-               ret = JOURNAL_ENTRY_ADD_OUT_OF_RANGE;
-               goto out;
-       }
+       if (!c->opts.read_entire_journal) {
+               /* Is this entry older than the range we need? */
+               if (le64_to_cpu(j->seq) < le64_to_cpu(last_seq)) {
+                       ret = JOURNAL_ENTRY_ADD_OUT_OF_RANGE;
+                       goto out;
+               }
 
-       /* Drop entries we don't need anymore */
-       list_for_each_entry_safe(i, pos, jlist->head, list) {
-               if (le64_to_cpu(i->j.seq) >= le64_to_cpu(j->last_seq))
-                       break;
-               list_del(&i->list);
-               kvpfree(i, offsetof(struct journal_replay, j) +
-                       vstruct_bytes(&i->j));
+               /* Drop entries we don't need anymore */
+               list_for_each_entry_safe(i, pos, jlist->head, list) {
+                       if (le64_to_cpu(i->j.seq) >= le64_to_cpu(j->last_seq))
+                               break;
+                       list_del(&i->list);
+                       kvpfree(i, offsetof(struct journal_replay, j) +
+                               vstruct_bytes(&i->j));
+               }
        }
 
        list_for_each_entry_reverse(i, jlist->head, list) {
index fe457117bf8950015af6a427f3be9bd1a4dbcb66..bc274918e18cee08c905a04c94513c4832e23f02 100644 (file)
@@ -265,6 +265,11 @@ enum opt_type {
          OPT_BOOL(),                                                   \
          NO_SB_OPT,                    false,                          \
          NULL,         "Don't free journal entries/keys after startup")\
+       x(read_entire_journal,          u8,                             \
+         0,                                                            \
+         OPT_BOOL(),                                                   \
+         NO_SB_OPT,                    false,                          \
+         NULL,         "Read all journal entries, not just dirty ones")\
        x(noexcl,                       u8,                             \
          OPT_MOUNT,                                                    \
          OPT_BOOL(),                                                   \
index 384dfb2279c17c66491587b716151769f7c6408a..26e5767aa5dee1a17eaa6546b075e158dd88946e 100644 (file)
@@ -319,20 +319,30 @@ static struct journal_keys journal_keys_sort(struct list_head *journal_entries)
        struct journal_key *src, *dst;
        size_t nr_keys = 0;
 
-       list_for_each_entry(p, journal_entries, list)
+       if (list_empty(journal_entries))
+               return keys;
+
+       keys.journal_seq_base =
+               le64_to_cpu(list_last_entry(journal_entries,
+                               struct journal_replay, list)->j.last_seq);
+
+       list_for_each_entry(p, journal_entries, list) {
+               if (le64_to_cpu(p->j.seq) < keys.journal_seq_base)
+                       continue;
+
                for_each_jset_key(k, _n, entry, &p->j)
                        nr_keys++;
+       }
 
-       keys.journal_seq_base =
-               le64_to_cpu(list_first_entry(journal_entries,
-                                            struct journal_replay,
-                                            list)->j.seq);
 
        keys.d = kvmalloc(sizeof(keys.d[0]) * nr_keys, GFP_KERNEL);
        if (!keys.d)
                goto err;
 
-       list_for_each_entry(p, journal_entries, list)
+       list_for_each_entry(p, journal_entries, list) {
+               if (le64_to_cpu(p->j.seq) < keys.journal_seq_base)
+                       continue;
+
                for_each_jset_key(k, _n, entry, &p->j)
                        keys.d[keys.nr++] = (struct journal_key) {
                                .btree_id       = entry->btree_id,
@@ -342,6 +352,7 @@ static struct journal_keys journal_keys_sort(struct list_head *journal_entries)
                                        keys.journal_seq_base,
                                .journal_offset = k->_data - p->j._data,
                        };
+       }
 
        sort(keys.d, keys.nr, sizeof(keys.d[0]), journal_sort_key_cmp, NULL);
 
@@ -568,6 +579,9 @@ verify_journal_entries_not_blacklisted_or_missing(struct bch_fs *c,
        int ret = 0;
 
        list_for_each_entry(i, journal, list) {
+               if (le64_to_cpu(i->j.seq) < start_seq)
+                       continue;
+
                fsck_err_on(seq != le64_to_cpu(i->j.seq), c,
                        "journal entries %llu-%llu missing! (replaying %llu-%llu)",
                        seq, le64_to_cpu(i->j.seq) - 1,