mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 00:04:15 +08:00
bcachefs: Redo replicas gc mechanism
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
9516950c06
commit
ae0ff7b8b0
@ -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,13 +93,10 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = bch2_trans_exit(&trans) ?: ret;
|
||||
|
||||
BUG_ON(ret == -EINTR);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
|
||||
bch2_replicas_gc_end(c, ret);
|
||||
mutex_unlock(&c->replicas_gc_lock);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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 *,
|
||||
|
Loading…
Reference in New Issue
Block a user