]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bcachefs: Walk leaf to root in btree_gc
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 29 May 2024 22:53:48 +0000 (18:53 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 14 Jul 2024 23:00:14 +0000 (19:00 -0400)
Next change will move gc_alloc_start initialization into the alloc
trigger, so we have to mark those first.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_gc.c
fs/bcachefs/btree_gc.h

index cd5880c94eddcd5cbc2886509fe8adc7a8c355ea..22771a861b298dcef738350c06e1db7fb90b4b64 100644 (file)
@@ -635,13 +635,27 @@ fsck_err:
 static int bch2_gc_btree(struct btree_trans *trans, enum btree_id btree, bool initial)
 {
        struct bch_fs *c = trans->c;
-       int level = 0, target_depth = btree_node_type_needs_gc(__btree_node_type(0, btree)) ? 0 : 1;
+       unsigned target_depth = btree_node_type_needs_gc(__btree_node_type(0, btree)) ? 0 : 1;
        int ret = 0;
 
        /* We need to make sure every leaf node is readable before going RW */
        if (initial)
                target_depth = 0;
 
+       for (unsigned level = target_depth; level < BTREE_MAX_DEPTH; level++) {
+               struct btree *prev = NULL;
+               struct btree_iter iter;
+               bch2_trans_node_iter_init(trans, &iter, btree, POS_MIN, 0, level,
+                                         BTREE_ITER_prefetch);
+
+               ret = for_each_btree_key_continue(trans, iter, 0, k, ({
+                       gc_pos_set(c, gc_pos_btree(btree, level, k.k->p));
+                       bch2_gc_mark_key(trans, btree, level, &prev, &iter, k, initial);
+               }));
+               if (ret)
+                       goto err;
+       }
+
        /* root */
        do {
 retry_root:
@@ -663,28 +677,11 @@ retry_root:
                gc_pos_set(c, gc_pos_btree(btree, b->c.level + 1, SPOS_MAX));
                struct bkey_s_c k = bkey_i_to_s_c(&b->key);
                ret = bch2_gc_mark_key(trans, btree, b->c.level + 1, NULL, NULL, k, initial);
-               level = b->c.level;
 err_root:
                bch2_trans_iter_exit(trans, &iter);
        } while (bch2_err_matches(ret, BCH_ERR_transaction_restart));
-
-       if (ret)
-               return ret;
-
-       for (; level >= target_depth; --level) {
-               struct btree *prev = NULL;
-               struct btree_iter iter;
-               bch2_trans_node_iter_init(trans, &iter, btree, POS_MIN, 0, level,
-                                         BTREE_ITER_prefetch);
-
-               ret = for_each_btree_key_continue(trans, iter, 0, k, ({
-                       gc_pos_set(c, gc_pos_btree(btree, level, k.k->p));
-                       bch2_gc_mark_key(trans, btree, level, &prev, &iter, k, initial);
-               }));
-               if (ret)
-                       break;
-       }
-
+err:
+       bch_err_fn(c, ret);
        return ret;
 }
 
index 876d81e2017d73e3240aa239c20a2defb5132981..1bdf841dc44b8aa3774f8b9eaab5872ee995c8e1 100644 (file)
@@ -58,6 +58,8 @@ static inline struct gc_pos gc_pos_btree_node(struct btree *b)
 
 static inline int gc_btree_order(enum btree_id btree)
 {
+       if (btree == BTREE_ID_alloc)
+               return -2;
        if (btree == BTREE_ID_stripes)
                return -1;
        return btree;
@@ -65,11 +67,11 @@ static inline int gc_btree_order(enum btree_id btree)
 
 static inline int gc_pos_cmp(struct gc_pos l, struct gc_pos r)
 {
-       return   cmp_int(l.phase, r.phase) ?:
-                cmp_int(gc_btree_order(l.btree),
-                        gc_btree_order(r.btree)) ?:
-               -cmp_int(l.level, r.level) ?:
-                bpos_cmp(l.pos, r.pos);
+       return  cmp_int(l.phase, r.phase) ?:
+               cmp_int(gc_btree_order(l.btree),
+                       gc_btree_order(r.btree)) ?:
+               cmp_int(l.level, r.level) ?:
+               bpos_cmp(l.pos, r.pos);
 }
 
 static inline bool gc_visited(struct bch_fs *c, struct gc_pos pos)