mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 05:55:44 +02:00
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 <kent.overstreet@linux.dev>
This commit is contained in:
parent
a7c9add482
commit
66b7c51ceb
|
|
@ -966,14 +966,27 @@ do_bch2_trans_commit_to_journal_replay(struct btree_trans *trans)
|
|||
|
||||
for (struct jset_entry *i = btree_trans_journal_entries_start(trans);
|
||||
i != btree_trans_journal_entries_top(trans);
|
||||
i = vstruct_next(i))
|
||||
i = vstruct_next(i)) {
|
||||
if (i->type == BCH_JSET_ENTRY_btree_keys ||
|
||||
i->type == BCH_JSET_ENTRY_write_buffer_keys) {
|
||||
int ret = bch2_journal_key_insert(c, i->btree_id, i->level, i->start);
|
||||
if (ret)
|
||||
return ret;
|
||||
jset_entry_for_each_key(i, k) {
|
||||
int ret = bch2_journal_key_insert(c, i->btree_id, i->level, k);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (i->type == BCH_JSET_ENTRY_btree_root) {
|
||||
guard(mutex)(&c->btree_root_lock);
|
||||
|
||||
struct btree_root *r = bch2_btree_id_root(c, i->btree_id);
|
||||
|
||||
bkey_copy(&r->key, i->start);
|
||||
r->level = i->level;
|
||||
r->alive = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (struct bkey_i *i = btree_trans_subbuf_base(trans, &trans->accounting);
|
||||
i != btree_trans_subbuf_top(trans, &trans->accounting);
|
||||
i = bkey_next(i)) {
|
||||
|
|
|
|||
|
|
@ -270,6 +270,9 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
|
|||
struct printbuf buf = PRINTBUF;
|
||||
int ret = 0;
|
||||
|
||||
/* We don't yet do btree key updates correctly for when we're RW */
|
||||
BUG_ON(test_bit(BCH_FS_rw, &c->flags));
|
||||
|
||||
bkey_for_each_ptr_decode(k.k, ptrs_c, p, entry_c) {
|
||||
ret = bch2_check_fix_ptr(trans, k, p, entry_c, &do_update);
|
||||
if (ret)
|
||||
|
|
@ -277,12 +280,6 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
|
|||
}
|
||||
|
||||
if (do_update) {
|
||||
if (flags & BTREE_TRIGGER_is_root) {
|
||||
bch_err(c, "cannot update btree roots yet");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
struct bkey_i *new = bch2_bkey_make_mut_noupdate(trans, k);
|
||||
ret = PTR_ERR_OR_ZERO(new);
|
||||
if (ret)
|
||||
|
|
@ -370,19 +367,41 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
|
|||
bch_info(c, "new key %s", buf.buf);
|
||||
}
|
||||
|
||||
struct btree_iter iter;
|
||||
bch2_trans_node_iter_init(trans, &iter, btree, new->k.p, 0, level,
|
||||
BTREE_ITER_intent|BTREE_ITER_all_snapshots);
|
||||
ret = bch2_btree_iter_traverse(trans, &iter) ?:
|
||||
bch2_trans_update(trans, &iter, new,
|
||||
BTREE_UPDATE_internal_snapshot_node|
|
||||
BTREE_TRIGGER_norun);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
if (ret)
|
||||
goto err;
|
||||
if (!(flags & BTREE_TRIGGER_is_root)) {
|
||||
struct btree_iter iter;
|
||||
bch2_trans_node_iter_init(trans, &iter, btree, new->k.p, 0, level,
|
||||
BTREE_ITER_intent|BTREE_ITER_all_snapshots);
|
||||
ret = bch2_btree_iter_traverse(trans, &iter) ?:
|
||||
bch2_trans_update(trans, &iter, new,
|
||||
BTREE_UPDATE_internal_snapshot_node|
|
||||
BTREE_TRIGGER_norun);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (level)
|
||||
bch2_btree_node_update_key_early(trans, btree, level - 1, k, new);
|
||||
if (level)
|
||||
bch2_btree_node_update_key_early(trans, btree, level - 1, k, new);
|
||||
} else {
|
||||
struct jset_entry *e = bch2_trans_jset_entry_alloc(trans,
|
||||
jset_u64s(new->k.u64s));
|
||||
ret = PTR_ERR_OR_ZERO(e);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
journal_entry_set(e,
|
||||
BCH_JSET_ENTRY_btree_root,
|
||||
btree, level - 1,
|
||||
new, new->k.u64s);
|
||||
|
||||
/*
|
||||
* no locking, we're single threaded and not rw yet, see
|
||||
* the big assertino above that we repeat here:
|
||||
*/
|
||||
BUG_ON(test_bit(BCH_FS_rw, &c->flags));
|
||||
|
||||
struct btree *b = bch2_btree_id_root(c, btree)->b;
|
||||
bkey_copy(&b->key, new);
|
||||
}
|
||||
}
|
||||
err:
|
||||
printbuf_exit(&buf);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user