]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: BTREE_ITER_NOPRESERVE
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 22 Dec 2021 01:48:26 +0000 (20:48 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:19 +0000 (17:09 -0400)
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>
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_iter.h
fs/bcachefs/btree_types.h
fs/bcachefs/btree_update_interior.c
fs/bcachefs/btree_update_leaf.c

index a9db8d05dc93184587988f09bebc40d7a56f3618..777197ec2656ec70fd22ad8a8566f6f6dba2aef8 100644 (file)
@@ -1807,12 +1807,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 flags)
 {
        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);
@@ -1836,7 +1838,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);
-               path->preserve = true;
        } else {
                path = btree_path_alloc(trans, path_pos);
                path_pos = NULL;
@@ -1845,7 +1846,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;
@@ -1860,6 +1860,9 @@ struct btree_path *bch2_path_get(struct btree_trans *trans, bool cached,
                trans->paths_sorted             = false;
        }
 
+       if (!(flags & BTREE_ITER_NOPRESERVE))
+               path->preserve = true;
+
        if (path->intent_ref)
                locks_want = max(locks_want, level + 1);
 
@@ -2642,13 +2645,8 @@ static void __bch2_trans_iter_init(struct btree_trans *trans,
        iter->k.p       = pos;
        iter->k.size    = 0;
 
-       iter->path = bch2_path_get(trans,
-                                  flags & BTREE_ITER_CACHED,
-                                  btree_id,
-                                  iter->pos,
-                                  locks_want,
-                                  depth,
-                                  flags & BTREE_ITER_INTENT);
+       iter->path = bch2_path_get(trans, btree_id, iter->pos,
+                                  locks_want, depth, flags);
 }
 
 void bch2_trans_iter_init(struct btree_trans *trans,
index af1922c448edd5786f1232ebaa2a6edbccd63ab2..457a7601b0ce8de58ef5f2f3ed9efa7f15a08a1a 100644 (file)
@@ -159,8 +159,8 @@ bch2_btree_path_make_mut(struct btree_trans *trans,
 
 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);
+struct btree_path *bch2_path_get(struct btree_trans *, enum btree_id, struct bpos,
+                                unsigned, unsigned, unsigned);
 inline struct bkey_s_c bch2_btree_path_peek_slot(struct btree_path *, struct bkey *);
 
 #ifdef CONFIG_BCACHEFS_DEBUG
index e1b417df4b73aa3e83ec076b67ed90a0f2091f43..223af7848fb45efa5d88da5e6b848cb552f58e2f 100644 (file)
@@ -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,
index 8865ab7d087be8d0fc709e2c960872c73245b9b2..3e6dd2ed1c030d8e67e9790d46a08cf68e58548f 100644 (file)
@@ -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);
+       sib_path = bch2_path_get(trans, path->btree_id, sib_pos,
+                                U8_MAX, level, BTREE_ITER_INTENT);
        ret = bch2_btree_path_traverse(trans, sib_path, false);
        if (ret)
                goto err;
index 96fc2cd13f21938e689a5e4cc2210ca6538331e6..50c9caa729ff009ec7365b867fcac7b10a0ec00f 100644 (file)
@@ -1297,7 +1297,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;