bcachefs: Drop alloc keys from journal when -o reconstruct_alloc
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 25 Oct 2020 01:20:16 +0000 (21:20 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:45 +0000 (17:08 -0400)
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>
fs/bcachefs/recovery.c

index d70fa968db50d95c5fa63ced0c8080e14434d903..32fed6b81a526a6f83549bc05cf56ab5907fb7a9 100644 (file)
 
 #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;