diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-12-21 20:48:26 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2021-12-25 17:37:12 -0500 |
commit | 732e06f7684a58c2d77aa1b30f81e473984717d6 (patch) | |
tree | 41e1001db2cd7306c0aab5ea40e0faa2531e4312 | |
parent | cabc3b6dfbcb7e3e4836ec212aef4bdbd6e62dd4 (diff) |
bcachefs: BTREE_ITER_NOPRESERVE
This adds a flag to not mark the initial btree_path as preserve, for
paths that we expect to be cheap to reconstitute if necessary - this
solves a btree_path overflow caused by need_whiteout_for_snapshot().
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/btree_iter.c | 20 | ||||
-rw-r--r-- | fs/bcachefs/btree_iter.h | 5 | ||||
-rw-r--r-- | fs/bcachefs/btree_types.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_interior.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 3 |
5 files changed, 16 insertions, 17 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index c187531ac581..e9091f8a153e 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -1818,12 +1818,14 @@ static struct btree_path *btree_path_alloc(struct btree_trans *trans, return path; } -struct btree_path *bch2_path_get(struct btree_trans *trans, bool cached, +struct btree_path *bch2_path_get(struct btree_trans *trans, enum btree_id btree_id, struct bpos pos, unsigned locks_want, unsigned level, - bool intent, unsigned long ip) + unsigned flags, unsigned long ip) { struct btree_path *path, *path_pos = NULL; + bool cached = flags & BTREE_ITER_CACHED; + bool intent = flags & BTREE_ITER_INTENT; int i; BUG_ON(trans->restarted); @@ -1845,7 +1847,6 @@ struct btree_path *bch2_path_get(struct btree_trans *trans, bool cached, path_pos->level == level) { __btree_path_get(path_pos, intent); path = btree_path_set_pos(trans, path_pos, pos, intent, ip); - path->preserve = true; } else { path = btree_path_alloc(trans, path_pos); path_pos = NULL; @@ -1854,7 +1855,6 @@ struct btree_path *bch2_path_get(struct btree_trans *trans, bool cached, path->pos = pos; path->btree_id = btree_id; path->cached = cached; - path->preserve = true; path->uptodate = BTREE_ITER_NEED_TRAVERSE; path->should_be_locked = false; path->level = level; @@ -1869,6 +1869,9 @@ struct btree_path *bch2_path_get(struct btree_trans *trans, bool cached, btree_trans_verify_sorted(trans); } + if (!(flags & BTREE_ITER_NOPRESERVE)) + path->preserve = true; + if (path->intent_ref) locks_want = max(locks_want, level + 1); @@ -2625,13 +2628,8 @@ static void __bch2_trans_iter_init(struct btree_trans *trans, iter->ip_allocated = ip; #endif - iter->path = bch2_path_get(trans, - flags & BTREE_ITER_CACHED, - btree_id, - iter->pos, - locks_want, - depth, - flags & BTREE_ITER_INTENT, ip); + iter->path = bch2_path_get(trans, btree_id, iter->pos, + locks_want, depth, flags, ip); } void bch2_trans_iter_init(struct btree_trans *trans, diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h index 26eb90a7eab8..4c903b9dd716 100644 --- a/fs/bcachefs/btree_iter.h +++ b/fs/bcachefs/btree_iter.h @@ -134,9 +134,8 @@ bch2_btree_path_make_mut(struct btree_trans *, struct btree_path *, bool, unsigned long); int __must_check bch2_btree_path_traverse(struct btree_trans *, struct btree_path *, unsigned); -struct btree_path *bch2_path_get(struct btree_trans *, bool, enum btree_id, - struct bpos, unsigned, unsigned, bool, - unsigned long); +struct btree_path *bch2_path_get(struct btree_trans *, enum btree_id, struct bpos, + unsigned, unsigned, unsigned, unsigned long); inline struct bkey_s_c bch2_btree_path_peek_slot(struct btree_path *, struct bkey *); #ifdef CONFIG_BCACHEFS_DEBUG diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h index 22dbbe365bbe..c84bba7bcda5 100644 --- a/fs/bcachefs/btree_types.h +++ b/fs/bcachefs/btree_types.h @@ -210,6 +210,7 @@ struct btree_node_iter { #define __BTREE_ITER_ALL_SNAPSHOTS (1 << 11) #define BTREE_ITER_ALL_SNAPSHOTS (1 << 12) #define BTREE_ITER_FILTER_SNAPSHOTS (1 << 13) +#define BTREE_ITER_NOPRESERVE (1 << 14) enum btree_path_uptodate { BTREE_ITER_UPTODATE = 0, diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index d895d4eff0a9..f5d879dee423 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -1609,8 +1609,8 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans, ? bpos_predecessor(b->data->min_key) : bpos_successor(b->data->max_key); - sib_path = bch2_path_get(trans, false, path->btree_id, sib_pos, - U8_MAX, level, true, _THIS_IP_); + sib_path = bch2_path_get(trans, path->btree_id, sib_pos, + U8_MAX, level, BTREE_ITER_INTENT, _THIS_IP_); ret = bch2_btree_path_traverse(trans, sib_path, false); if (ret) goto err; diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index 295942e7356e..1966441b1a62 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -1285,7 +1285,8 @@ static int need_whiteout_for_snapshot(struct btree_trans *trans, pos.snapshot++; for_each_btree_key_norestart(trans, iter, btree_id, pos, - BTREE_ITER_ALL_SNAPSHOTS, k, ret) { + BTREE_ITER_ALL_SNAPSHOTS| + BTREE_ITER_NOPRESERVE, k, ret) { if (bkey_cmp(k.k->p, pos)) break; |