Commit 7fffc85b authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Add an internal option for reading entire journal

To be used the debug tool that dumps the contents of the journal.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent bd2bb273
...@@ -986,9 +986,8 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq, ...@@ -986,9 +986,8 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq,
u64 last_seq = cur_seq, nr, seq; u64 last_seq = cur_seq, nr, seq;
if (!list_empty(journal_entries)) if (!list_empty(journal_entries))
last_seq = le64_to_cpu(list_first_entry(journal_entries, last_seq = le64_to_cpu(list_last_entry(journal_entries,
struct journal_replay, struct journal_replay, list)->j.last_seq);
list)->j.seq);
nr = cur_seq - last_seq; nr = cur_seq - last_seq;
...@@ -1017,8 +1016,10 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq, ...@@ -1017,8 +1016,10 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq,
list_for_each_entry(i, journal_entries, list) { list_for_each_entry(i, journal_entries, list) {
seq = le64_to_cpu(i->j.seq); 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; journal_seq_pin(j, seq)->devs = i->devs;
} }
......
...@@ -40,6 +40,7 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca, ...@@ -40,6 +40,7 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca,
list)->j.last_seq list)->j.last_seq
: 0; : 0;
if (!c->opts.read_entire_journal) {
/* Is this entry older than the range we need? */ /* Is this entry older than the range we need? */
if (le64_to_cpu(j->seq) < le64_to_cpu(last_seq)) { if (le64_to_cpu(j->seq) < le64_to_cpu(last_seq)) {
ret = JOURNAL_ENTRY_ADD_OUT_OF_RANGE; ret = JOURNAL_ENTRY_ADD_OUT_OF_RANGE;
...@@ -54,6 +55,7 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca, ...@@ -54,6 +55,7 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca,
kvpfree(i, offsetof(struct journal_replay, j) + kvpfree(i, offsetof(struct journal_replay, j) +
vstruct_bytes(&i->j)); vstruct_bytes(&i->j));
} }
}
list_for_each_entry_reverse(i, jlist->head, list) { list_for_each_entry_reverse(i, jlist->head, list) {
/* Duplicate? */ /* Duplicate? */
......
...@@ -265,6 +265,11 @@ enum opt_type { ...@@ -265,6 +265,11 @@ enum opt_type {
OPT_BOOL(), \ OPT_BOOL(), \
NO_SB_OPT, false, \ NO_SB_OPT, false, \
NULL, "Don't free journal entries/keys after startup")\ 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, \ x(noexcl, u8, \
OPT_MOUNT, \ OPT_MOUNT, \
OPT_BOOL(), \ OPT_BOOL(), \
......
...@@ -319,20 +319,30 @@ static struct journal_keys journal_keys_sort(struct list_head *journal_entries) ...@@ -319,20 +319,30 @@ static struct journal_keys journal_keys_sort(struct list_head *journal_entries)
struct journal_key *src, *dst; struct journal_key *src, *dst;
size_t nr_keys = 0; 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) for_each_jset_key(k, _n, entry, &p->j)
nr_keys++; 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); keys.d = kvmalloc(sizeof(keys.d[0]) * nr_keys, GFP_KERNEL);
if (!keys.d) if (!keys.d)
goto err; 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) for_each_jset_key(k, _n, entry, &p->j)
keys.d[keys.nr++] = (struct journal_key) { keys.d[keys.nr++] = (struct journal_key) {
.btree_id = entry->btree_id, .btree_id = entry->btree_id,
...@@ -342,6 +352,7 @@ static struct journal_keys journal_keys_sort(struct list_head *journal_entries) ...@@ -342,6 +352,7 @@ static struct journal_keys journal_keys_sort(struct list_head *journal_entries)
keys.journal_seq_base, keys.journal_seq_base,
.journal_offset = k->_data - p->j._data, .journal_offset = k->_data - p->j._data,
}; };
}
sort(keys.d, keys.nr, sizeof(keys.d[0]), journal_sort_key_cmp, NULL); 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, ...@@ -568,6 +579,9 @@ verify_journal_entries_not_blacklisted_or_missing(struct bch_fs *c,
int ret = 0; int ret = 0;
list_for_each_entry(i, journal, list) { 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, fsck_err_on(seq != le64_to_cpu(i->j.seq), c,
"journal entries %llu-%llu missing! (replaying %llu-%llu)", "journal entries %llu-%llu missing! (replaying %llu-%llu)",
seq, le64_to_cpu(i->j.seq) - 1, seq, le64_to_cpu(i->j.seq) - 1,
......
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