]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to 90d824456e bcachefs: Improve path for when btree_gc needs...
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 2 Jan 2022 23:40:44 +0000 (18:40 -0500)
committerKent Overstreet <kent.overstreet@gmail.com>
Sun, 2 Jan 2022 23:40:44 +0000 (18:40 -0500)
.bcachefs_revision
libbcachefs/btree_gc.c
libbcachefs/k-eytzinger.h [new file with mode: 0644]

index 193d8bd79d5dc0d5dc0c3428f2bf7fd7bbd150cd..e9908fb69ba611c2c6089aa522c2942184b0c87a 100644 (file)
@@ -1 +1 @@
-aa439f3b94eb3141f9b6d71f780300e7fef44af9
+90d824456e169e50965814b74a75c50045b13976
index 101cef7e927963ccda16c4d452b230d2f894d0ad..0625a65d714382f3ec95766cb008466270d563b4 100644 (file)
@@ -586,7 +586,7 @@ static int bch2_check_fix_ptrs(struct bch_fs *c, enum btree_id btree_id,
                                (bch2_bkey_val_to_text(&PBUF(buf), c, *k), buf))) {
                        if (data_type == BCH_DATA_btree) {
                                g->_mark.data_type      = data_type;
-                               g->gen_valid            = true;
+                               set_bit(BCH_FS_NEED_ANOTHER_GC, &c->flags);
                        } else {
                                do_update = true;
                        }
@@ -1425,6 +1425,27 @@ static int bch2_gc_alloc_start(struct bch_fs *c, bool initial, bool metadata_onl
        return bch2_alloc_read(c, true, metadata_only);
 }
 
+static void bch2_gc_alloc_reset(struct bch_fs *c, bool initial, bool metadata_only)
+{
+       struct bch_dev *ca;
+       unsigned i;
+
+       for_each_member_device(ca, c, i) {
+               struct bucket_array *buckets = __bucket_array(ca, true);
+               struct bucket *g;
+
+               for_each_bucket(g, buckets) {
+                       if (metadata_only &&
+                           (g->mark.data_type == BCH_DATA_user ||
+                            g->mark.data_type == BCH_DATA_cached ||
+                            g->mark.data_type == BCH_DATA_parity))
+                               continue;
+                       g->_mark.dirty_sectors = 0;
+                       g->_mark.cached_sectors = 0;
+               }
+       };
+}
+
 static int bch2_gc_reflink_done(struct bch_fs *c, bool initial,
                                bool metadata_only)
 {
@@ -1495,6 +1516,16 @@ fsck_err:
        return ret;
 }
 
+static void bch2_gc_reflink_reset(struct bch_fs *c, bool initial,
+                                 bool metadata_only)
+{
+       struct genradix_iter iter;
+       struct reflink_gc *r;
+
+       genradix_for_each(&c->reflink_gc_table, iter, r)
+               r->refcount = 0;
+}
+
 static int bch2_gc_reflink_start(struct bch_fs *c, bool initial,
                                 bool metadata_only)
 {
@@ -1597,6 +1628,12 @@ fsck_err:
        return ret;
 }
 
+static void bch2_gc_stripes_reset(struct bch_fs *c, bool initial,
+                               bool metadata_only)
+{
+       genradix_free(&c->gc_stripes);
+}
+
 /**
  * bch2_gc - walk _all_ references to buckets, and recompute them:
  *
@@ -1630,13 +1667,13 @@ int bch2_gc(struct bch_fs *c, bool initial, bool metadata_only)
        /* flush interior btree updates: */
        closure_wait_event(&c->btree_interior_update_wait,
                           !bch2_btree_interior_updates_nr_pending(c));
-again:
+
        ret   = bch2_gc_start(c, metadata_only) ?:
                bch2_gc_alloc_start(c, initial, metadata_only) ?:
                bch2_gc_reflink_start(c, initial, metadata_only);
        if (ret)
                goto out;
-
+again:
        gc_pos_set(c, gc_phase(GC_PHASE_START));
 
        bch2_mark_superblocks(c);
@@ -1675,25 +1712,26 @@ again:
 
        if (test_bit(BCH_FS_NEED_ANOTHER_GC, &c->flags) ||
            (!iter && bch2_test_restart_gc)) {
+               if (iter++ > 2) {
+                       bch_info(c, "Unable to fix bucket gens, looping");
+                       ret = -EINVAL;
+                       goto out;
+               }
+
                /*
                 * XXX: make sure gens we fixed got saved
                 */
-               if (iter++ <= 2) {
-                       bch_info(c, "Second GC pass needed, restarting:");
-                       clear_bit(BCH_FS_NEED_ANOTHER_GC, &c->flags);
-                       __gc_pos_set(c, gc_phase(GC_PHASE_NOT_RUNNING));
+               bch_info(c, "Second GC pass needed, restarting:");
+               clear_bit(BCH_FS_NEED_ANOTHER_GC, &c->flags);
+               __gc_pos_set(c, gc_phase(GC_PHASE_NOT_RUNNING));
 
-                       percpu_down_write(&c->mark_lock);
-                       bch2_gc_free(c);
-                       percpu_up_write(&c->mark_lock);
-                       /* flush fsck errors, reset counters */
-                       bch2_flush_fsck_errs(c);
+               bch2_gc_stripes_reset(c, initial, metadata_only);
+               bch2_gc_alloc_reset(c, initial, metadata_only);
+               bch2_gc_reflink_reset(c, initial, metadata_only);
 
-                       goto again;
-               }
-
-               bch_info(c, "Unable to fix bucket gens, looping");
-               ret = -EINVAL;
+               /* flush fsck errors, reset counters */
+               bch2_flush_fsck_errs(c);
+               goto again;
        }
 out:
        if (!ret) {
diff --git a/libbcachefs/k-eytzinger.h b/libbcachefs/k-eytzinger.h
new file mode 100644 (file)
index 0000000..819db34
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _K_EYTZINGER_H
+#define _K_EYTZINGER_H
+
+/* One based indexing */
+/* k = number of children */
+
+static inline unsigned k_eytzinger_child(unsigned k, unsigned i, unsigned child)
+{
+       return (k * i + child) * (k - 1);
+}
+
+#endif /* _K_EYTZINGER_H */