summaryrefslogtreecommitdiff
path: root/fs/bcachefs/recovery.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-10-24 21:20:16 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:45 -0400
commit33114c2d897405ec338df979d1bf1d3319f92938 (patch)
treecd05ca271bd49d93835d883483d2e5142986f724 /fs/bcachefs/recovery.c
parent801a3de6427924d87ecc7e218a99ad3245ee8290 (diff)
downloadlwn-33114c2d897405ec338df979d1bf1d3319f92938.tar.gz
lwn-33114c2d897405ec338df979d1bf1d3319f92938.zip
bcachefs: Drop alloc keys from journal when -o reconstruct_alloc
This fixes a bug where we'd pop an assertion due to replaying a key for an interior btree node when that node no longer exists. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/recovery.c')
-rw-r--r--fs/bcachefs/recovery.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index d70fa968db50..32fed6b81a52 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -25,6 +25,18 @@
#define QSTR(n) { { { .len = strlen(n) } }, .name = n }
+/* for -o reconstruct_alloc: */
+static void drop_alloc_keys(struct journal_keys *keys)
+{
+ size_t src, dst;
+
+ for (src = 0, dst = 0; src < keys->nr; src++)
+ if (keys->d[src].btree_id != BTREE_ID_ALLOC)
+ keys->d[dst++] = keys->d[src];
+
+ keys->nr = dst;
+}
+
/* iterate over keys read from the journal: */
static struct journal_key *journal_key_search(struct journal_keys *journal_keys,
@@ -930,7 +942,6 @@ static int read_btree_roots(struct bch_fs *c)
continue;
}
-
if (r->error) {
__fsck_err(c, i == BTREE_ID_ALLOC
? FSCK_CAN_IGNORE : 0,
@@ -1027,6 +1038,11 @@ int bch2_fs_recovery(struct bch_fs *c)
goto err;
}
+ if (c->opts.reconstruct_alloc) {
+ c->sb.compat &= ~(1ULL << BCH_COMPAT_FEAT_ALLOC_INFO);
+ drop_alloc_keys(&c->journal_keys);
+ }
+
ret = journal_replay_early(c, clean, &c->journal_entries);
if (ret)
goto err;