From 69529e313666457c295ebb256f41126ca635b36b Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 2 Jan 2022 18:40:44 -0500 Subject: [PATCH] Update bcachefs sources to 90d824456e bcachefs: Improve path for when btree_gc needs another pass --- .bcachefs_revision | 2 +- libbcachefs/btree_gc.c | 72 ++++++++++++++++++++++++++++++--------- libbcachefs/k-eytzinger.h | 13 +++++++ 3 files changed, 69 insertions(+), 18 deletions(-) create mode 100644 libbcachefs/k-eytzinger.h diff --git a/.bcachefs_revision b/.bcachefs_revision index 193d8bd7..e9908fb6 100644 --- a/.bcachefs_revision +++ b/.bcachefs_revision @@ -1 +1 @@ -aa439f3b94eb3141f9b6d71f780300e7fef44af9 +90d824456e169e50965814b74a75c50045b13976 diff --git a/libbcachefs/btree_gc.c b/libbcachefs/btree_gc.c index 101cef7e..0625a65d 100644 --- a/libbcachefs/btree_gc.c +++ b/libbcachefs/btree_gc.c @@ -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 index 00000000..819db34e --- /dev/null +++ b/libbcachefs/k-eytzinger.h @@ -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 */