From cd398e1b690cc832b986d9f208e368f80f5f544d Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 26 Oct 2025 12:16:09 -0400 Subject: [PATCH] Update bcachefs sources to b552eb122251 bcachefs: track whether new btree nodes are roots --- .bcachefs_revision | 2 +- libbcachefs/btree/interior.c | 18 ++++++++++++----- libbcachefs/btree/interior.h | 1 + libbcachefs/data/move.c | 6 ++++++ libbcachefs/data/rebalance.c | 38 +++++++++++++++++++++++++++++++++++- 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/.bcachefs_revision b/.bcachefs_revision index 34b5a45f..3da8aa16 100644 --- a/.bcachefs_revision +++ b/.bcachefs_revision @@ -1 +1 @@ -553ac0f9757322932398e1a36bf44fc787d06ba8 +b552eb12225133c8bf869b461faba6b72e35d2be diff --git a/libbcachefs/btree/interior.c b/libbcachefs/btree/interior.c index 25bac981..34c8f560 100644 --- a/libbcachefs/btree/interior.c +++ b/libbcachefs/btree/interior.c @@ -50,7 +50,6 @@ static void bch2_btree_update_to_text(struct printbuf *, struct btree_update *); static int bch2_btree_insert_node(struct btree_update *, struct btree_trans *, btree_path_idx_t, struct btree *, struct keylist *); -static void bch2_btree_update_add_new_node(struct btree_update *, struct btree *); /* * Verify that child nodes correctly span parent node's range: @@ -610,7 +609,7 @@ static void bch2_btree_update_free(struct btree_update *as, struct btree_trans * closure_wake_up(&c->btree_interior_update_wait); } -static void btree_update_add_node(btree_update_nodes *nodes, struct btree *b) +static void bch2_btree_update_add_node(struct bch_fs *c, btree_update_nodes *nodes, struct btree *b) { BUG_ON(darray_make_room(nodes, 1)); @@ -620,6 +619,7 @@ static void btree_update_add_node(btree_update_nodes *nodes, struct btree *b) n->b = b; n->level = b->c.level; n->seq = b->data->keys.seq; + n->root = b == btree_node_root(c, b); bkey_copy(&n->key, &b->key); } @@ -977,8 +977,6 @@ static void bch2_btree_update_add_new_node(struct btree_update *as, struct btree b->will_make_reachable = 1UL|(unsigned long) as; set_btree_node_will_make_reachable(b); - btree_update_add_node(&as->new_nodes, b); - if (b->key.k.type == KEY_TYPE_btree_ptr_v2) { unsigned bytes = vstruct_end(&b->data->keys) - (void *) b->data; unsigned sectors = round_up(bytes, block_bytes(c)) >> 9; @@ -1063,7 +1061,7 @@ static void bch2_btree_interior_update_will_free_node(struct btree_update *as, mutex_unlock(&c->btree_interior_update_lock); - btree_update_add_node(&as->old_nodes, b); + bch2_btree_update_add_node(c, &as->old_nodes, b); } static void bch2_btree_update_done(struct btree_update *as, struct btree_trans *trans) @@ -1693,13 +1691,16 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans, if (n3) { bch2_btree_update_get_open_buckets(as, n3); bch2_btree_node_write_trans(trans, n3, SIX_LOCK_intent, 0); + bch2_btree_update_add_node(c, &as->new_nodes, n3); } if (n2) { bch2_btree_update_get_open_buckets(as, n2); bch2_btree_node_write_trans(trans, n2, SIX_LOCK_intent, 0); + bch2_btree_update_add_node(c, &as->new_nodes, n2); } bch2_btree_update_get_open_buckets(as, n1); bch2_btree_node_write_trans(trans, n1, SIX_LOCK_intent, 0); + bch2_btree_update_add_node(c, &as->new_nodes, n1); /* * The old node must be freed (in memory) _before_ unlocking the new @@ -1904,6 +1905,7 @@ static void __btree_increase_depth(struct btree_update *as, struct btree_trans * bch2_btree_update_get_open_buckets(as, n); bch2_btree_node_write_trans(trans, n, SIX_LOCK_intent, 0); + bch2_btree_update_add_node(c, &as->new_nodes, n); bch2_trans_node_add(trans, path, n); six_unlock_intent(&n->c.lock); @@ -2103,6 +2105,7 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans, bch2_btree_update_get_open_buckets(as, n); bch2_btree_node_write_trans(trans, n, SIX_LOCK_intent, 0); + bch2_btree_update_add_node(c, &as->new_nodes, n); bch2_btree_node_free_inmem(trans, trans->paths + path, b); bch2_btree_node_free_inmem(trans, trans->paths + sib_path, m); @@ -2157,6 +2160,8 @@ int bch2_btree_node_rewrite(struct btree_trans *trans, unsigned target, enum bch_trans_commit_flags flags) { + BUG_ON(btree_node_fake(b)); + struct bch_fs *c = trans->c; struct btree *n, *parent; struct btree_update *as; @@ -2200,6 +2205,7 @@ int bch2_btree_node_rewrite(struct btree_trans *trans, bch2_btree_update_get_open_buckets(as, n); bch2_btree_node_write_trans(trans, n, SIX_LOCK_intent, 0); + bch2_btree_update_add_node(c, &as->new_nodes, n); bch2_btree_node_free_inmem(trans, btree_iter_path(trans, iter), b); @@ -2439,6 +2445,8 @@ int bch2_btree_node_update_key(struct btree_trans *trans, struct btree_iter *ite struct btree *b, struct bkey_i *new_key, unsigned commit_flags, bool skip_triggers) { + BUG_ON(btree_node_fake(b)); + struct btree_path *path = btree_iter_path(trans, iter); /* diff --git a/libbcachefs/btree/interior.h b/libbcachefs/btree/interior.h index d0895df9..fdbb797b 100644 --- a/libbcachefs/btree/interior.h +++ b/libbcachefs/btree/interior.h @@ -27,6 +27,7 @@ enum btree_update_mode { struct btree_update_node { struct btree *b; unsigned level; + bool root; __le64 seq; __BKEY_PADDED(key, BKEY_BTREE_PTR_VAL_U64s_MAX); }; diff --git a/libbcachefs/data/move.c b/libbcachefs/data/move.c index 37e57686..465bec83 100644 --- a/libbcachefs/data/move.c +++ b/libbcachefs/data/move.c @@ -440,6 +440,9 @@ retry_root: if (b != btree_node_root(c, b)) goto retry_root; + if (btree_node_fake(b)) + return 0; + k = bkey_i_to_s_c(&b->key); ret = bch2_move_extent(ctxt, NULL, &snapshot_io_opts, pred, arg, &iter, level, k); root_err: @@ -768,6 +771,9 @@ retry: stats->pos = BBPOS(iter.btree_id, iter.pos); + if (btree_node_fake(b)) + goto next; + struct data_update_opts data_opts = {}; if (!pred(c, arg, b, &io_opts, &data_opts)) goto next; diff --git a/libbcachefs/data/rebalance.c b/libbcachefs/data/rebalance.c index 11adf944..809e3e11 100644 --- a/libbcachefs/data/rebalance.c +++ b/libbcachefs/data/rebalance.c @@ -582,8 +582,44 @@ static int do_rebalance_scan_btree(struct moving_context *ctxt, struct bch_fs *c = trans->c; struct bch_fs_rebalance *r = &c->rebalance; - bch2_trans_begin(trans); + /* + * peek(), peek_slot() don't know how to fetch btree root keys - we + * really should fix this + */ + while (level == bch2_btree_id_root(c, btree)->level + 1) { + bch2_trans_begin(trans); + CLASS(btree_node_iter, iter)(trans, btree, start, 0, level - 1, + BTREE_ITER_prefetch| + BTREE_ITER_not_extents| + BTREE_ITER_all_snapshots); + struct btree *b = bch2_btree_iter_peek_node(&iter); + int ret = PTR_ERR_OR_ZERO(b); + if (ret) + goto root_err; + + if (b != btree_node_root(c, b)) + continue; + + if (btree_node_fake(b)) + return 0; + + struct bkey_s_c k = bkey_i_to_s_c(&b->key); + + struct bch_inode_opts opts; + ret = bch2_bkey_get_io_opts(trans, snapshot_io_opts, k, &opts) ?: + bch2_update_rebalance_opts(trans, &opts, &iter, k, SET_NEEDS_REBALANCE_opt_change); +root_err: + if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) + continue; + if (bch2_err_matches(ret, BCH_ERR_data_update_fail)) + ret = 0; /* failure for this extent, keep going */ + WARN_ONCE(ret && !bch2_err_matches(ret, EROFS), + "unhandled error from move_extent: %s", bch2_err_str(ret)); + return ret; + } + + bch2_trans_begin(trans); CLASS(btree_node_iter, iter)(trans, btree, start, 0, level, BTREE_ITER_prefetch| BTREE_ITER_not_extents|