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: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
bd2bb273a0
commit
7fffc85baf
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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(), \
|
||||
|
@ -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)
|
||||
for_each_jset_key(k, _n, entry, &p->j)
|
||||
nr_keys++;
|
||||
if (list_empty(journal_entries))
|
||||
return keys;
|
||||
|
||||
keys.journal_seq_base =
|
||||
le64_to_cpu(list_first_entry(journal_entries,
|
||||
struct journal_replay,
|
||||
list)->j.seq);
|
||||
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.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,
|
||||
|
Loading…
Reference in New Issue
Block a user