Skip to content

Commit 66b7c51

Browse files
author
Kent Overstreet
committed
bcachefs: bch2_check_fix_ptrs() can now repair btree roots
This is straightforward enough: check_fix_ptrs() currently only runs before we go RW, so updating the btree root pointer in c->btree_roots suffices - it'll be written out in the first journal write we do. For that, do_bch2_trans_commit_to_journal_replay() now handles JSET_ENTRY_btree_root entries. Signed-off-by: Kent Overstreet <[email protected]>
1 parent a7c9add commit 66b7c51

File tree

2 files changed

+54
-22
lines changed

2 files changed

+54
-22
lines changed

fs/bcachefs/btree_trans_commit.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -966,14 +966,27 @@ do_bch2_trans_commit_to_journal_replay(struct btree_trans *trans)
966966

967967
for (struct jset_entry *i = btree_trans_journal_entries_start(trans);
968968
i != btree_trans_journal_entries_top(trans);
969-
i = vstruct_next(i))
969+
i = vstruct_next(i)) {
970970
if (i->type == BCH_JSET_ENTRY_btree_keys ||
971971
i->type == BCH_JSET_ENTRY_write_buffer_keys) {
972-
int ret = bch2_journal_key_insert(c, i->btree_id, i->level, i->start);
973-
if (ret)
974-
return ret;
972+
jset_entry_for_each_key(i, k) {
973+
int ret = bch2_journal_key_insert(c, i->btree_id, i->level, k);
974+
if (ret)
975+
return ret;
976+
}
975977
}
976978

979+
if (i->type == BCH_JSET_ENTRY_btree_root) {
980+
guard(mutex)(&c->btree_root_lock);
981+
982+
struct btree_root *r = bch2_btree_id_root(c, i->btree_id);
983+
984+
bkey_copy(&r->key, i->start);
985+
r->level = i->level;
986+
r->alive = true;
987+
}
988+
}
989+
977990
for (struct bkey_i *i = btree_trans_subbuf_base(trans, &trans->accounting);
978991
i != btree_trans_subbuf_top(trans, &trans->accounting);
979992
i = bkey_next(i)) {

fs/bcachefs/buckets.c

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -270,19 +270,16 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
270270
struct printbuf buf = PRINTBUF;
271271
int ret = 0;
272272

273+
/* We don't yet do btree key updates correctly for when we're RW */
274+
BUG_ON(test_bit(BCH_FS_rw, &c->flags));
275+
273276
bkey_for_each_ptr_decode(k.k, ptrs_c, p, entry_c) {
274277
ret = bch2_check_fix_ptr(trans, k, p, entry_c, &do_update);
275278
if (ret)
276279
goto err;
277280
}
278281

279282
if (do_update) {
280-
if (flags & BTREE_TRIGGER_is_root) {
281-
bch_err(c, "cannot update btree roots yet");
282-
ret = -EINVAL;
283-
goto err;
284-
}
285-
286283
struct bkey_i *new = bch2_bkey_make_mut_noupdate(trans, k);
287284
ret = PTR_ERR_OR_ZERO(new);
288285
if (ret)
@@ -370,19 +367,41 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
370367
bch_info(c, "new key %s", buf.buf);
371368
}
372369

373-
struct btree_iter iter;
374-
bch2_trans_node_iter_init(trans, &iter, btree, new->k.p, 0, level,
375-
BTREE_ITER_intent|BTREE_ITER_all_snapshots);
376-
ret = bch2_btree_iter_traverse(trans, &iter) ?:
377-
bch2_trans_update(trans, &iter, new,
378-
BTREE_UPDATE_internal_snapshot_node|
379-
BTREE_TRIGGER_norun);
380-
bch2_trans_iter_exit(trans, &iter);
381-
if (ret)
382-
goto err;
370+
if (!(flags & BTREE_TRIGGER_is_root)) {
371+
struct btree_iter iter;
372+
bch2_trans_node_iter_init(trans, &iter, btree, new->k.p, 0, level,
373+
BTREE_ITER_intent|BTREE_ITER_all_snapshots);
374+
ret = bch2_btree_iter_traverse(trans, &iter) ?:
375+
bch2_trans_update(trans, &iter, new,
376+
BTREE_UPDATE_internal_snapshot_node|
377+
BTREE_TRIGGER_norun);
378+
bch2_trans_iter_exit(trans, &iter);
379+
if (ret)
380+
goto err;
383381

384-
if (level)
385-
bch2_btree_node_update_key_early(trans, btree, level - 1, k, new);
382+
if (level)
383+
bch2_btree_node_update_key_early(trans, btree, level - 1, k, new);
384+
} else {
385+
struct jset_entry *e = bch2_trans_jset_entry_alloc(trans,
386+
jset_u64s(new->k.u64s));
387+
ret = PTR_ERR_OR_ZERO(e);
388+
if (ret)
389+
goto err;
390+
391+
journal_entry_set(e,
392+
BCH_JSET_ENTRY_btree_root,
393+
btree, level - 1,
394+
new, new->k.u64s);
395+
396+
/*
397+
* no locking, we're single threaded and not rw yet, see
398+
* the big assertino above that we repeat here:
399+
*/
400+
BUG_ON(test_bit(BCH_FS_rw, &c->flags));
401+
402+
struct btree *b = bch2_btree_id_root(c, btree)->b;
403+
bkey_copy(&b->key, new);
404+
}
386405
}
387406
err:
388407
printbuf_exit(&buf);

0 commit comments

Comments
 (0)