summaryrefslogtreecommitdiff
path: root/fs/bcachefs/btree_gc.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-12-13 22:43:03 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:48 +0300
commit14d7d61fac9c151a270c6ef6f969993eae9f1bbf (patch)
tree9634e430e3cda3bfb93d7b090108a8331635eb0b /fs/bcachefs/btree_gc.c
parent1ae40fd816ca6f52b46a8d74f799f8a85ecb92ad (diff)
downloadlinux-14d7d61fac9c151a270c6ef6f969993eae9f1bbf.tar.xz
bcachefs: Fix btree_gc when multiple passes required
We weren't resetting filesystem & device usage when restarting gc, which was spotted when free bucket counters overflowed - whoops. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_gc.c')
-rw-r--r--fs/bcachefs/btree_gc.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c
index 2defa811f48f..d4a0e0a716c5 100644
--- a/fs/bcachefs/btree_gc.c
+++ b/fs/bcachefs/btree_gc.c
@@ -1282,8 +1282,7 @@ fsck_err:
return ret;
}
-static int bch2_gc_start(struct bch_fs *c,
- bool metadata_only)
+static int bch2_gc_start(struct bch_fs *c)
{
struct bch_dev *ca = NULL;
unsigned i;
@@ -1298,7 +1297,6 @@ static int bch2_gc_start(struct bch_fs *c,
}
for_each_member_device(ca, c, i) {
- BUG_ON(ca->buckets_gc);
BUG_ON(ca->usage_gc);
ca->usage_gc = alloc_percpu(struct bch_dev_usage);
@@ -1315,6 +1313,22 @@ static int bch2_gc_start(struct bch_fs *c,
return 0;
}
+static int bch2_gc_reset(struct bch_fs *c)
+{
+ struct bch_dev *ca;
+ unsigned i;
+
+ for_each_member_device(ca, c, i) {
+ free_percpu(ca->usage_gc);
+ ca->usage_gc = NULL;
+ }
+
+ free_percpu(c->usage_gc);
+ c->usage_gc = NULL;
+
+ return bch2_gc_start(c);
+}
+
/* returns true if not equal */
static inline bool bch2_alloc_v4_cmp(struct bch_alloc_v4 l,
struct bch_alloc_v4 r)
@@ -1761,7 +1775,7 @@ int bch2_gc(struct bch_fs *c, bool initial, bool metadata_only)
bch2_btree_interior_updates_flush(c);
- ret = bch2_gc_start(c, metadata_only) ?:
+ ret = bch2_gc_start(c) ?:
bch2_gc_alloc_start(c, metadata_only) ?:
bch2_gc_reflink_start(c, metadata_only);
if (ret)
@@ -1822,6 +1836,9 @@ again:
bch2_gc_stripes_reset(c, metadata_only);
bch2_gc_alloc_reset(c, metadata_only);
bch2_gc_reflink_reset(c, metadata_only);
+ ret = bch2_gc_reset(c);
+ if (ret)
+ goto out;
/* flush fsck errors, reset counters */
bch2_flush_fsck_errs(c);