summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-05-01 00:15:39 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:08:21 +0300
commitae0ff7b8b0ccf0643ea4d3968faabb2d5ee98c1c (patch)
tree059b8cb3b184eda983bed7f13e7d8910d5753804 /fs
parent9516950c0690b6a8bef4cc1c7ae269da996973d8 (diff)
downloadlinux-ae0ff7b8b0ccf0643ea4d3968faabb2d5ee98c1c.tar.xz
bcachefs: Redo replicas gc mechanism
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/migrate.c22
-rw-r--r--fs/bcachefs/move.c66
-rw-r--r--fs/bcachefs/replicas.c58
-rw-r--r--fs/bcachefs/replicas.h1
4 files changed, 69 insertions, 78 deletions
diff --git a/fs/bcachefs/migrate.c b/fs/bcachefs/migrate.c
index f9e6c9d9ef04..6b17d7918aa4 100644
--- a/fs/bcachefs/migrate.c
+++ b/fs/bcachefs/migrate.c
@@ -48,10 +48,6 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
iter = bch2_trans_get_iter(&trans, BTREE_ID_EXTENTS,
POS_MIN, BTREE_ITER_PREFETCH);
- mutex_lock(&c->replicas_gc_lock);
- bch2_replicas_gc_start(c, (1 << BCH_DATA_USER)|(1 << BCH_DATA_CACHED));
-
-
while ((k = bch2_btree_iter_peek(iter)).k &&
!(ret = bkey_err(k))) {
if (!bkey_extent_is_data(k.k) ||
@@ -97,12 +93,9 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
break;
}
- BUG_ON(ret == -EINTR);
-
- bch2_trans_exit(&trans);
+ ret = bch2_trans_exit(&trans) ?: ret;
- bch2_replicas_gc_end(c, ret);
- mutex_unlock(&c->replicas_gc_lock);
+ BUG_ON(ret == -EINTR);
return ret;
}
@@ -123,9 +116,6 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
bch2_trans_init(&trans, c);
closure_init_stack(&cl);
- mutex_lock(&c->replicas_gc_lock);
- bch2_replicas_gc_start(c, 1 << BCH_DATA_BTREE);
-
for (id = 0; id < BTREE_ID_NR; id++) {
for_each_btree_node(&trans, iter, id, POS_MIN,
BTREE_ITER_PREFETCH, b) {
@@ -178,10 +168,9 @@ retry:
ret = 0;
err:
- bch2_trans_exit(&trans);
+ ret = bch2_trans_exit(&trans) ?: ret;
- ret = bch2_replicas_gc_end(c, ret);
- mutex_unlock(&c->replicas_gc_lock);
+ BUG_ON(ret == -EINTR);
return ret;
}
@@ -189,5 +178,6 @@ err:
int bch2_dev_data_drop(struct bch_fs *c, unsigned dev_idx, int flags)
{
return bch2_dev_usrdata_drop(c, dev_idx, flags) ?:
- bch2_dev_metadata_drop(c, dev_idx, flags);
+ bch2_dev_metadata_drop(c, dev_idx, flags) ?:
+ bch2_replicas_gc2(c);
}
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
index ff426a2c8e7a..64ac8244e1e0 100644
--- a/fs/bcachefs/move.c
+++ b/fs/bcachefs/move.c
@@ -619,64 +619,6 @@ out:
return ret;
}
-static int bch2_gc_data_replicas(struct bch_fs *c)
-{
- struct btree_trans trans;
- struct btree_iter *iter;
- struct bkey_s_c k;
- int ret;
-
- bch2_trans_init(&trans, c);
-
- mutex_lock(&c->replicas_gc_lock);
- bch2_replicas_gc_start(c, (1 << BCH_DATA_USER)|(1 << BCH_DATA_CACHED));
-
- for_each_btree_key(&trans, iter, BTREE_ID_EXTENTS, POS_MIN,
- BTREE_ITER_PREFETCH, k, ret) {
- ret = bch2_mark_bkey_replicas(c, k);
- if (ret)
- break;
- }
- ret = bch2_trans_exit(&trans) ?: ret;
-
- bch2_replicas_gc_end(c, ret);
- mutex_unlock(&c->replicas_gc_lock);
-
- return ret;
-}
-
-static int bch2_gc_btree_replicas(struct bch_fs *c)
-{
- struct btree_trans trans;
- struct btree_iter *iter;
- struct btree *b;
- unsigned id;
- int ret = 0;
-
- bch2_trans_init(&trans, c);
-
- mutex_lock(&c->replicas_gc_lock);
- bch2_replicas_gc_start(c, 1 << BCH_DATA_BTREE);
-
- for (id = 0; id < BTREE_ID_NR; id++) {
- for_each_btree_node(&trans, iter, id, POS_MIN,
- BTREE_ITER_PREFETCH, b) {
- ret = bch2_mark_bkey_replicas(c, bkey_i_to_s_c(&b->key));
-
- bch2_trans_cond_resched(&trans);
- }
-
- ret = bch2_trans_iter_free(&trans, iter) ?: ret;
- }
-
- bch2_trans_exit(&trans);
-
- bch2_replicas_gc_end(c, ret);
- mutex_unlock(&c->replicas_gc_lock);
-
- return ret;
-}
-
static int bch2_move_btree(struct bch_fs *c,
move_pred_fn pred,
void *arg,
@@ -803,14 +745,14 @@ int bch2_data_job(struct bch_fs *c,
bch2_journal_meta(&c->journal);
}
- ret = bch2_gc_btree_replicas(c) ?: ret;
+ ret = bch2_replicas_gc2(c) ?: ret;
ret = bch2_move_data(c, NULL,
writepoint_hashed((unsigned long) current),
op.start,
op.end,
rereplicate_pred, c, stats) ?: ret;
- ret = bch2_gc_data_replicas(c) ?: ret;
+ ret = bch2_replicas_gc2(c) ?: ret;
break;
case BCH_DATA_OP_MIGRATE:
if (op.migrate.dev >= c->sb.nr_devices)
@@ -820,14 +762,14 @@ int bch2_data_job(struct bch_fs *c,
ret = bch2_journal_flush_device_pins(&c->journal, op.migrate.dev);
ret = bch2_move_btree(c, migrate_pred, &op, stats) ?: ret;
- ret = bch2_gc_btree_replicas(c) ?: ret;
+ ret = bch2_replicas_gc2(c) ?: ret;
ret = bch2_move_data(c, NULL,
writepoint_hashed((unsigned long) current),
op.start,
op.end,
migrate_pred, &op, stats) ?: ret;
- ret = bch2_gc_data_replicas(c) ?: ret;
+ ret = bch2_replicas_gc2(c) ?: ret;
break;
default:
ret = -EINVAL;
diff --git a/fs/bcachefs/replicas.c b/fs/bcachefs/replicas.c
index 2482dbbbad38..7a9a7ec26c93 100644
--- a/fs/bcachefs/replicas.c
+++ b/fs/bcachefs/replicas.c
@@ -571,6 +571,64 @@ int bch2_replicas_gc_start(struct bch_fs *c, unsigned typemask)
return 0;
}
+int bch2_replicas_gc2(struct bch_fs *c)
+{
+ struct bch_replicas_cpu new = { 0 };
+ unsigned i, nr;
+ int ret = 0;
+
+ bch2_journal_meta(&c->journal);
+retry:
+ nr = READ_ONCE(c->replicas.nr);
+ new.entry_size = READ_ONCE(c->replicas.entry_size);
+ new.entries = kcalloc(nr, new.entry_size, GFP_KERNEL);
+ if (!new.entries)
+ return -ENOMEM;
+
+ mutex_lock(&c->sb_lock);
+ percpu_down_write(&c->mark_lock);
+
+ if (nr != c->replicas.nr ||
+ new.entry_size != c->replicas.entry_size) {
+ percpu_up_write(&c->mark_lock);
+ mutex_unlock(&c->sb_lock);
+ kfree(new.entries);
+ goto retry;
+ }
+
+ for (i = 0; i < c->replicas.nr; i++) {
+ struct bch_replicas_entry *e =
+ cpu_replicas_entry(&c->replicas, i);
+
+ if (e->data_type == BCH_DATA_JOURNAL ||
+ c->usage_base->replicas[i] ||
+ percpu_u64_get(&c->usage[0]->replicas[i]) ||
+ percpu_u64_get(&c->usage[1]->replicas[i]))
+ memcpy(cpu_replicas_entry(&new, new.nr++),
+ e, new.entry_size);
+ }
+
+ bch2_cpu_replicas_sort(&new);
+
+ if (bch2_cpu_replicas_to_sb_replicas(c, &new)) {
+ ret = -ENOSPC;
+ goto err;
+ }
+
+ ret = replicas_table_update(c, &new);
+err:
+ kfree(new.entries);
+
+ percpu_up_write(&c->mark_lock);
+
+ if (!ret)
+ bch2_write_super(c);
+
+ mutex_unlock(&c->sb_lock);
+
+ return ret;
+}
+
int bch2_replicas_set_usage(struct bch_fs *c,
struct bch_replicas_entry *r,
u64 sectors)
diff --git a/fs/bcachefs/replicas.h b/fs/bcachefs/replicas.h
index 1ceedb6231fd..0d6e19126021 100644
--- a/fs/bcachefs/replicas.h
+++ b/fs/bcachefs/replicas.h
@@ -59,6 +59,7 @@ unsigned bch2_dev_has_data(struct bch_fs *, struct bch_dev *);
int bch2_replicas_gc_end(struct bch_fs *, int);
int bch2_replicas_gc_start(struct bch_fs *, unsigned);
+int bch2_replicas_gc2(struct bch_fs *);
int bch2_replicas_set_usage(struct bch_fs *,
struct bch_replicas_entry *,