diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-06-29 05:09:13 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-23 00:10:05 +0300 |
commit | faa6cb6c13c7223240366ebbf0217a6191fbfc32 (patch) | |
tree | c41d92045b9cdd9f84c1f0188ab4d7311796c2bc /fs/bcachefs/btree_gc.c | |
parent | bc652905c60b504ded266448b2810242d24c8d88 (diff) | |
download | linux-faa6cb6c13c7223240366ebbf0217a6191fbfc32.tar.xz |
bcachefs: Allow for unknown btree IDs
We need to allow filesystems with metadata from newer versions to be
mountable and usable by older versions.
This patch enables us to roll out new btrees without a new major version
number; we can now handle btree roots for unknown btree types.
The unknown btree roots will be retained, and fsck (including
backpointers) will check them, the same as other btree types.
We add a dynamic array for the extra, unknown btree roots, in addition
to the fixed size btree root array, and add new helpers for looking up
btree roots.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_gc.c')
-rw-r--r-- | fs/bcachefs/btree_gc.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c index 0c9cba56105c..9018a2a15212 100644 --- a/fs/bcachefs/btree_gc.c +++ b/fs/bcachefs/btree_gc.c @@ -529,8 +529,13 @@ static int bch2_repair_topology(struct bch_fs *c) bch2_trans_init(&trans, c, 0, 0); - for (i = 0; i < BTREE_ID_NR && !ret; i++) { - b = c->btree_roots[i].b; + for (i = 0; i < btree_id_nr_alive(c)&& !ret; i++) { + struct btree_root *r = bch2_btree_id_root(c, i); + + if (!r->alive) + continue; + + b = r->b; if (btree_node_fake(b)) continue; @@ -883,7 +888,7 @@ static int bch2_gc_btree(struct btree_trans *trans, enum btree_id btree_id, return ret; mutex_lock(&c->btree_root_lock); - b = c->btree_roots[btree_id].b; + b = bch2_btree_id_root(c, btree_id)->b; if (!btree_node_fake(b)) { struct bkey_s_c k = bkey_i_to_s_c(&b->key); @@ -1006,7 +1011,7 @@ static int bch2_gc_btree_init(struct btree_trans *trans, struct printbuf buf = PRINTBUF; int ret = 0; - b = c->btree_roots[btree_id].b; + b = bch2_btree_id_root(c, btree_id)->b; if (btree_node_fake(b)) return 0; @@ -1072,6 +1077,15 @@ static int bch2_gc_btrees(struct bch_fs *c, bool initial, bool metadata_only) ? bch2_gc_btree_init(&trans, ids[i], metadata_only) : bch2_gc_btree(&trans, ids[i], initial, metadata_only); + for (i = BTREE_ID_NR; i < btree_id_nr_alive(c) && !ret; i++) { + if (!bch2_btree_id_root(c, i)->alive) + continue; + + ret = initial + ? bch2_gc_btree_init(&trans, i, metadata_only) + : bch2_gc_btree(&trans, i, initial, metadata_only); + } + if (ret < 0) bch_err_fn(c, ret); |