summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2017-12-24 22:04:28 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2018-02-08 15:23:07 -0500
commitd5e561b3cc023dd247d2b3d08b680709ec21b477 (patch)
tree599c8eb006f519ed077947a1b7ef67916125fc78
parentf093d9e193341749c3e1acd72f2d3a0c56914b11 (diff)
bcachefs: BCH_DATA ioctl
New infrastructure for jobs that walk existing data and "do stuff" - rereplicate, migrate implemented so far Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/bcachefs_ioctl.h44
-rw-r--r--fs/bcachefs/chardev.c124
-rw-r--r--fs/bcachefs/migrate.c3
-rw-r--r--fs/bcachefs/move.c221
-rw-r--r--fs/bcachefs/move.h8
-rw-r--r--fs/bcachefs/movinggc.c2
-rw-r--r--fs/bcachefs/super.c41
-rw-r--r--fs/bcachefs/super.h1
-rw-r--r--fs/bcachefs/tier.c2
9 files changed, 346 insertions, 100 deletions
diff --git a/fs/bcachefs/bcachefs_ioctl.h b/fs/bcachefs/bcachefs_ioctl.h
index aa2a20504a9f..6578847b50c4 100644
--- a/fs/bcachefs/bcachefs_ioctl.h
+++ b/fs/bcachefs/bcachefs_ioctl.h
@@ -46,7 +46,6 @@ struct bch_ioctl_incremental {
#define BCH_IOCTL_DISK_ONLINE _IOW(0xbc, 6, struct bch_ioctl_disk)
#define BCH_IOCTL_DISK_OFFLINE _IOW(0xbc, 7, struct bch_ioctl_disk)
#define BCH_IOCTL_DISK_SET_STATE _IOW(0xbc, 8, struct bch_ioctl_disk_set_state)
-#define BCH_IOCTL_DISK_EVACUATE _IOW(0xbc, 9, struct bch_ioctl_disk)
#define BCH_IOCTL_DATA _IOW(0xbc, 10, struct bch_ioctl_data)
#define BCH_IOCTL_USAGE _IOWR(0xbc, 11, struct bch_ioctl_usage)
#define BCH_IOCTL_READ_SUPER _IOW(0xbc, 12, struct bch_ioctl_read_super)
@@ -75,30 +74,37 @@ struct bch_ioctl_disk_set_state {
__u64 dev;
};
-#define BCH_REWRITE_INCREASE_REPLICAS (1 << 0)
-#define BCH_REWRITE_DECREASE_REPLICAS (1 << 1)
-
-#define BCH_REWRITE_RECOMPRESS (1 << 0)
-#define BCH_REWRITE_DECREASE_REPLICAS (1 << 1)
-
enum bch_data_ops {
- BCH_DATA_SCRUB,
-};
-
-struct bch_data_op {
- __u8 type;
+ BCH_DATA_OP_SCRUB = 0,
+ BCH_DATA_OP_REREPLICATE = 1,
+ BCH_DATA_OP_MIGRATE = 2,
+ BCH_DATA_OP_NR = 3,
};
struct bch_ioctl_data {
+ __u32 op;
__u32 flags;
- __u32 pad;
-
- __u64 start_inode;
- __u64 start_offset;
- __u64 end_inode;
- __u64 end_offset;
-};
+ struct bpos start;
+ struct bpos end;
+
+ union {
+ struct {
+ __u32 dev;
+ __u32 pad;
+ } migrate;
+ };
+} __attribute__((packed, aligned(8)));
+
+struct bch_ioctl_data_progress {
+ __u8 data_type;
+ __u8 btree_id;
+ __u8 pad[2];
+ struct bpos pos;
+
+ __u64 sectors_done;
+ __u64 sectors_total;
+} __attribute__((packed, aligned(8)));
struct bch_ioctl_dev_usage {
__u8 state;
diff --git a/fs/bcachefs/chardev.c b/fs/bcachefs/chardev.c
index bc289bfe3a31..5ff90cc0015f 100644
--- a/fs/bcachefs/chardev.c
+++ b/fs/bcachefs/chardev.c
@@ -1,20 +1,25 @@
#ifndef NO_BCACHEFS_CHARDEV
#include "bcachefs.h"
+#include "alloc.h"
#include "bcachefs_ioctl.h"
#include "buckets.h"
#include "chardev.h"
+#include "move.h"
#include "super.h"
#include "super-io.h"
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/major.h>
+#include <linux/anon_inodes.h>
#include <linux/cdev.h>
#include <linux/device.h>
+#include <linux/file.h>
+#include <linux/fs.h>
#include <linux/ioctl.h>
-#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/major.h>
+#include <linux/sched/task.h>
#include <linux/slab.h>
+#include <linux/uaccess.h>
/* returns with ref on ca->ref */
static struct bch_dev *bch2_device_lookup(struct bch_fs *c, u64 dev,
@@ -266,23 +271,108 @@ static long bch2_ioctl_disk_set_state(struct bch_fs *c,
return ret;
}
-static long bch2_ioctl_disk_evacuate(struct bch_fs *c,
- struct bch_ioctl_disk arg)
+struct bch_data_ctx {
+ struct bch_fs *c;
+ struct bch_ioctl_data arg;
+ struct bch_move_stats stats;
+
+ int ret;
+
+ struct task_struct *thread;
+};
+
+static int bch2_data_thread(void *arg)
{
- struct bch_dev *ca;
- int ret;
+ struct bch_data_ctx *ctx = arg;
- if ((arg.flags & ~BCH_BY_INDEX) ||
- arg.pad)
+ ctx->ret = bch2_data_job(ctx->c, &ctx->stats, ctx->arg);
+
+ ctx->stats.data_type = U8_MAX;
+ return 0;
+}
+
+static int bch2_data_job_release(struct inode *inode, struct file *file)
+{
+ struct bch_data_ctx *ctx = file->private_data;
+
+ kthread_stop(ctx->thread);
+ put_task_struct(ctx->thread);
+ kfree(ctx);
+ return 0;
+}
+
+static ssize_t bch2_data_job_read(struct file *file, char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ struct bch_data_ctx *ctx = file->private_data;
+ struct bch_fs *c = ctx->c;
+ struct bch_ioctl_data_progress p = {
+ .data_type = ctx->stats.data_type,
+ .btree_id = ctx->stats.iter.btree_id,
+ .pos = ctx->stats.iter.pos,
+ .sectors_done = atomic64_read(&ctx->stats.sectors_seen),
+ .sectors_total = bch2_fs_sectors_used(c, bch2_fs_usage_read(c)),
+ };
+
+ if (len != sizeof(p))
return -EINVAL;
- ca = bch2_device_lookup(c, arg.dev, arg.flags);
- if (IS_ERR(ca))
- return PTR_ERR(ca);
+ return copy_to_user(buf, &p, sizeof(p)) ?: sizeof(p);
+}
- ret = bch2_dev_evacuate(c, ca);
+static const struct file_operations bcachefs_data_ops = {
+ .release = bch2_data_job_release,
+ .read = bch2_data_job_read,
+ .llseek = no_llseek,
+};
- percpu_ref_put(&ca->ref);
+static long bch2_ioctl_data(struct bch_fs *c,
+ struct bch_ioctl_data arg)
+{
+ struct bch_data_ctx *ctx = NULL;
+ struct file *file = NULL;
+ unsigned flags = O_RDONLY|O_CLOEXEC|O_NONBLOCK;
+ int ret, fd = -1;
+
+ if (arg.op >= BCH_DATA_OP_NR || arg.flags)
+ return -EINVAL;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->c = c;
+ ctx->arg = arg;
+
+ ctx->thread = kthread_create(bch2_data_thread, ctx, "[bcachefs]");
+ if (IS_ERR(ctx->thread)) {
+ ret = PTR_ERR(ctx->thread);
+ goto err;
+ }
+
+ ret = get_unused_fd_flags(flags);
+ if (ret < 0)
+ goto err;
+ fd = ret;
+
+ file = anon_inode_getfile("[bcachefs]", &bcachefs_data_ops, ctx, flags);
+ if (IS_ERR(file)) {
+ ret = PTR_ERR(file);
+ goto err;
+ }
+
+ fd_install(fd, file);
+
+ get_task_struct(ctx->thread);
+ wake_up_process(ctx->thread);
+
+ return fd;
+err:
+ if (fd >= 0)
+ put_unused_fd(fd);
+ if (!IS_ERR_OR_NULL(ctx->thread))
+ kthread_stop(ctx->thread);
+ kfree(ctx);
return ret;
}
@@ -474,8 +564,8 @@ long bch2_fs_ioctl(struct bch_fs *c, unsigned cmd, void __user *arg)
BCH_IOCTL(disk_offline, struct bch_ioctl_disk);
case BCH_IOCTL_DISK_SET_STATE:
BCH_IOCTL(disk_set_state, struct bch_ioctl_disk_set_state);
- case BCH_IOCTL_DISK_EVACUATE:
- BCH_IOCTL(disk_evacuate, struct bch_ioctl_disk);
+ case BCH_IOCTL_DATA:
+ BCH_IOCTL(data, struct bch_ioctl_data);
case BCH_IOCTL_READ_SUPER:
BCH_IOCTL(read_super, struct bch_ioctl_read_super);
case BCH_IOCTL_DISK_GET_IDX:
diff --git a/fs/bcachefs/migrate.c b/fs/bcachefs/migrate.c
index 01c8896078f2..9c2920cff61c 100644
--- a/fs/bcachefs/migrate.c
+++ b/fs/bcachefs/migrate.c
@@ -40,12 +40,15 @@ static int bch2_dev_usrdata_migrate(struct bch_fs *c, struct bch_dev *ca,
* operations
*/
do {
+ memset(&stats, 0, sizeof(stats));
+
ret = bch2_move_data(c, NULL,
SECTORS_IN_FLIGHT_PER_DEVICE,
NULL,
writepoint_hashed((unsigned long) current),
0,
ca->dev_idx,
+ POS_MIN, POS_MAX,
migrate_pred, ca,
&stats);
if (ret) {
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
index a67e7a451e38..e5a46ba6d03f 100644
--- a/fs/bcachefs/move.c
+++ b/fs/bcachefs/move.c
@@ -87,7 +87,6 @@ static int bch2_migrate_index_update(struct bch_write_op *op)
m->move_dev)))
bch2_extent_drop_ptr(extent_i_to_s(insert), ptr);
-
extent_for_each_ptr_crc(extent_i_to_s(new), ptr, crc) {
if (bch2_extent_has_device(extent_i_to_s_c(insert), ptr->dev)) {
/*
@@ -194,6 +193,8 @@ static void move_free(struct closure *cl)
struct bio_vec *bv;
int i;
+ bch2_disk_reservation_put(io->write.op.c, &io->write.op.res);
+
bio_for_each_segment_all(bv, &io->write.op.wbio.bio, i)
if (bv->bv_page)
__free_page(bv->bv_page);
@@ -243,20 +244,21 @@ static int bch2_move_extent(struct bch_fs *c,
int btree_insert_flags,
int move_device,
struct bch_io_opts opts,
- struct bkey_s_c k)
+ struct bkey_s_c_extent e)
{
struct extent_pick_ptr pick;
struct moving_io *io;
const struct bch_extent_ptr *ptr;
struct bch_extent_crc_unpacked crc;
- unsigned sectors = k.k->size, pages;
+ unsigned sectors = e.k->size, pages, nr_good;
+ int ret = -ENOMEM;
- bch2_extent_pick_ptr(c, k, NULL, &pick);
+ bch2_extent_pick_ptr(c, e.s_c, NULL, &pick);
if (IS_ERR_OR_NULL(pick.ca))
return pick.ca ? PTR_ERR(pick.ca) : 0;
/* write path might have to decompress data: */
- extent_for_each_ptr_crc(bkey_s_c_to_extent(k), ptr, crc)
+ extent_for_each_ptr_crc(e, ptr, crc)
sectors = max_t(unsigned, sectors, crc.uncompressed_size);
pages = DIV_ROUND_UP(sectors, PAGE_SECTORS);
@@ -266,7 +268,7 @@ static int bch2_move_extent(struct bch_fs *c,
goto err;
io->write.ctxt = ctxt;
- io->sectors = k.k->size;
+ io->sectors = e.k->size;
bio_init(&io->write.op.wbio.bio, io->bi_inline_vecs, pages);
bio_set_prio(&io->write.op.wbio.bio,
@@ -274,10 +276,8 @@ static int bch2_move_extent(struct bch_fs *c,
io->write.op.wbio.bio.bi_iter.bi_size = sectors << 9;
bch2_bio_map(&io->write.op.wbio.bio, NULL);
- if (bio_alloc_pages(&io->write.op.wbio.bio, GFP_KERNEL)) {
- kfree(io);
- goto err;
- }
+ if (bio_alloc_pages(&io->write.op.wbio.bio, GFP_KERNEL))
+ goto err_free;
io->rbio.opts = opts;
bio_init(&io->rbio.bio, io->bi_inline_vecs, pages);
@@ -285,7 +285,7 @@ static int bch2_move_extent(struct bch_fs *c,
io->rbio.bio.bi_iter.bi_size = sectors << 9;
bio_set_op_attrs(&io->rbio.bio, REQ_OP_READ, 0);
- io->rbio.bio.bi_iter.bi_sector = bkey_start_offset(k.k);
+ io->rbio.bio.bi_iter.bi_sector = bkey_start_offset(e.k);
io->rbio.bio.bi_end_io = move_read_endio;
io->write.btree_insert_flags = btree_insert_flags;
@@ -298,10 +298,22 @@ static int bch2_move_extent(struct bch_fs *c,
io->write.op.devs = devs;
io->write.op.write_point = wp;
+ if (move_device < 0 &&
+ ((nr_good = bch2_extent_nr_good_ptrs(c, e)) <
+ c->opts.data_replicas)) {
+ io->write.op.nr_replicas = c->opts.data_replicas - nr_good;
+
+ ret = bch2_disk_reservation_get(c, &io->write.op.res,
+ e.k->size,
+ io->write.op.nr_replicas, 0);
+ if (ret)
+ goto err_free_pages;
+ }
+
atomic64_inc(&ctxt->stats->keys_moved);
- atomic64_add(k.k->size, &ctxt->stats->sectors_moved);
+ atomic64_add(e.k->size, &ctxt->stats->sectors_moved);
- trace_move_extent(k.k);
+ trace_move_extent(e.k);
atomic_add(io->sectors, &ctxt->sectors_in_flight);
list_add_tail(&io->list, &ctxt->reads);
@@ -311,12 +323,16 @@ static int bch2_move_extent(struct bch_fs *c,
* ctxt when doing wakeup
*/
closure_get(&ctxt->cl);
- bch2_read_extent(c, &io->rbio, bkey_s_c_to_extent(k),
- &pick, BCH_READ_NODECODE);
+ bch2_read_extent(c, &io->rbio, e, &pick, BCH_READ_NODECODE);
return 0;
+err_free_pages:
+ bio_free_pages(&io->write.op.wbio.bio);
+err_free:
+ kfree(io);
err:
- trace_move_alloc_fail(k.k);
- return -ENOMEM;
+ percpu_ref_put(&pick.ca->io_ref);
+ trace_move_alloc_fail(e.k);
+ return ret;
}
static void do_pending_writes(struct moving_context *ctxt)
@@ -355,6 +371,8 @@ int bch2_move_data(struct bch_fs *c,
struct write_point_specifier wp,
int btree_insert_flags,
int move_device,
+ struct bpos start,
+ struct bpos end,
move_pred_fn pred, void *arg,
struct bch_move_stats *stats)
{
@@ -363,14 +381,16 @@ int bch2_move_data(struct bch_fs *c,
struct bch_io_opts opts = bch2_opts_to_inode_opts(c->opts);
BKEY_PADDED(k) tmp;
struct bkey_s_c k;
+ struct bkey_s_c_extent e;
u64 cur_inum = U64_MAX;
int ret = 0;
- memset(stats, 0, sizeof(*stats));
closure_init_stack(&ctxt.cl);
INIT_LIST_HEAD(&ctxt.reads);
init_waitqueue_head(&ctxt.wait);
- bch2_btree_iter_init(&stats->iter, c, BTREE_ID_EXTENTS, POS_MIN,
+
+ stats->data_type = BCH_DATA_USER;
+ bch2_btree_iter_init(&stats->iter, c, BTREE_ID_EXTENTS, start,
BTREE_ITER_PREFETCH);
if (rate)
@@ -396,10 +416,14 @@ peek:
ret = btree_iter_err(k);
if (ret)
break;
+ if (bkey_cmp(bkey_start_pos(k.k), end) >= 0)
+ break;
if (!bkey_extent_is_data(k.k))
goto next_nondata;
+ e = bkey_s_c_to_extent(k);
+
if (cur_inum != k.k->p.inode) {
struct bch_inode_unpacked inode;
@@ -413,7 +437,7 @@ peek:
goto peek;
}
- if (!pred(arg, bkey_s_c_to_extent(k)))
+ if (!pred(arg, e))
goto next;
/* unlock before doing IO: */
@@ -423,7 +447,8 @@ peek:
if (bch2_move_extent(c, &ctxt, devs, wp,
btree_insert_flags,
- move_device, opts, k)) {
+ move_device, opts,
+ bkey_s_c_to_extent(k))) {
/* memory allocation failure, wait for some IO to finish */
bch2_move_ctxt_wait_for_io(&ctxt);
continue;
@@ -453,3 +478,157 @@ next_nondata:
return ret;
}
+
+static int bch2_gc_data_replicas(struct bch_fs *c)
+{
+ struct btree_iter iter;
+ struct bkey_s_c k;
+ int ret;
+
+ mutex_lock(&c->replicas_gc_lock);
+ bch2_replicas_gc_start(c, 1 << BCH_DATA_USER);
+
+ for_each_btree_key(&iter, c, BTREE_ID_EXTENTS, POS_MIN,
+ BTREE_ITER_PREFETCH, k) {
+ ret = bch2_check_mark_super(c, BCH_DATA_USER, bch2_bkey_devs(k));
+ if (ret)
+ break;
+ }
+ ret = bch2_btree_iter_unlock(&iter) ?: 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_iter iter;
+ struct btree *b;
+ unsigned id;
+ int ret = 0;
+
+ 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(&iter, c, id, POS_MIN, BTREE_ITER_PREFETCH, b) {
+ ret = bch2_check_mark_super(c, BCH_DATA_BTREE,
+ bch2_bkey_devs(bkey_i_to_s_c(&b->key)));
+
+ bch2_btree_iter_cond_resched(&iter);
+ }
+
+ ret = bch2_btree_iter_unlock(&iter) ?: ret;
+ }
+
+ 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,
+ struct bch_move_stats *stats)
+{
+ struct btree *b;
+ unsigned id;
+ int ret = 0;
+
+ stats->data_type = BCH_DATA_BTREE;
+
+ for (id = 0; id < BTREE_ID_NR; id++) {
+ for_each_btree_node(&stats->iter, c, id, POS_MIN, BTREE_ITER_PREFETCH, b) {
+ if (pred(arg, bkey_i_to_s_c_extent(&b->key)))
+ ret = bch2_btree_node_rewrite(c, &stats->iter,
+ b->data->keys.seq, 0) ?: ret;
+
+ bch2_btree_iter_cond_resched(&stats->iter);
+ }
+
+ ret = bch2_btree_iter_unlock(&stats->iter) ?: ret;
+ }
+
+ return ret;
+}
+
+#if 0
+static bool scrub_data_pred(void *arg, struct bkey_s_c_extent e)
+{
+}
+#endif
+
+static bool rereplicate_metadata_pred(void *arg, struct bkey_s_c_extent e)
+{
+ struct bch_fs *c = arg;
+ unsigned nr_good = bch2_extent_nr_good_ptrs(c, e);
+
+ return nr_good && nr_good < c->opts.metadata_replicas;
+}
+
+static bool rereplicate_data_pred(void *arg, struct bkey_s_c_extent e)
+{
+ struct bch_fs *c = arg;
+ unsigned nr_good = bch2_extent_nr_good_ptrs(c, e);
+
+ return nr_good && nr_good < c->opts.data_replicas;
+}
+
+static bool migrate_pred(void *arg, struct bkey_s_c_extent e)
+{
+ struct bch_ioctl_data *op = arg;
+
+ return bch2_extent_has_device(e, op->migrate.dev);
+}
+
+int bch2_data_job(struct bch_fs *c,
+ struct bch_move_stats *stats,
+ struct bch_ioctl_data op)
+{
+ int ret = 0;
+
+ switch (op.op) {
+ case BCH_DATA_OP_REREPLICATE:
+ stats->data_type = BCH_DATA_JOURNAL;
+ ret = bch2_journal_flush_device(&c->journal, -1);
+
+ ret = bch2_move_btree(c, rereplicate_metadata_pred, c, stats) ?: ret;
+ ret = bch2_gc_btree_replicas(c) ?: ret;
+
+ ret = bch2_move_data(c, NULL, SECTORS_IN_FLIGHT_PER_DEVICE,
+ NULL,
+ writepoint_hashed((unsigned long) current),
+ 0, -1,
+ op.start,
+ op.end,
+ rereplicate_data_pred, c, stats) ?: ret;
+ ret = bch2_gc_data_replicas(c) ?: ret;
+ break;
+ case BCH_DATA_OP_MIGRATE:
+ if (op.migrate.dev >= c->sb.nr_devices)
+ return -EINVAL;
+
+ stats->data_type = BCH_DATA_JOURNAL;
+ ret = bch2_journal_flush_device(&c->journal, op.migrate.dev);
+
+ ret = bch2_move_btree(c, migrate_pred, &op, stats) ?: ret;
+ ret = bch2_gc_btree_replicas(c) ?: ret;
+
+ ret = bch2_move_data(c, NULL, SECTORS_IN_FLIGHT_PER_DEVICE,
+ NULL,
+ writepoint_hashed((unsigned long) current),
+ 0, -1,
+ op.start,
+ op.end,
+ migrate_pred, &op, stats) ?: ret;
+ ret = bch2_gc_data_replicas(c) ?: ret;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
diff --git a/fs/bcachefs/move.h b/fs/bcachefs/move.h
index 24d6ddfa9637..07aa5669524c 100644
--- a/fs/bcachefs/move.h
+++ b/fs/bcachefs/move.h
@@ -27,6 +27,7 @@ void bch2_migrate_write_init(struct migrate_write *, struct bch_read_bio *);
typedef bool (*move_pred_fn)(void *, struct bkey_s_c_extent);
struct bch_move_stats {
+ enum bch_data_type data_type;
struct btree_iter iter;
atomic64_t keys_moved;
@@ -38,7 +39,12 @@ struct bch_move_stats {
int bch2_move_data(struct bch_fs *, struct bch_ratelimit *,
unsigned, struct bch_devs_mask *,
struct write_point_specifier,
- int, int, move_pred_fn, void *,
+ int, int, struct bpos, struct bpos,
+ move_pred_fn, void *,
struct bch_move_stats *);
+int bch2_data_job(struct bch_fs *,
+ struct bch_move_stats *,
+ struct bch_ioctl_data);
+
#endif /* _BCACHEFS_MOVE_H */
diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c
index d6f2968ec4b1..515d5001aec8 100644
--- a/fs/bcachefs/movinggc.c
+++ b/fs/bcachefs/movinggc.c
@@ -106,6 +106,7 @@ static void bch2_copygc(struct bch_fs *c, struct bch_dev *ca)
size_t b;
int ret;
+ memset(&move_stats, 0, sizeof(move_stats));
closure_wait_event(&c->freelist_wait, have_copygc_reserve(ca));
/*
@@ -166,6 +167,7 @@ static void bch2_copygc(struct bch_fs *c, struct bch_dev *ca)
writepoint_ptr(&ca->copygc_write_point),
BTREE_INSERT_USE_RESERVE,
ca->dev_idx,
+ POS_MIN, POS_MAX,
copygc_pred, ca,
&move_stats);
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 4c8b20354e13..f836c199e06b 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -1650,47 +1650,6 @@ int bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca, int flags)
return 0;
}
-int bch2_dev_evacuate(struct bch_fs *c, struct bch_dev *ca)
-{
- unsigned data;
- int ret = 0;
-
- mutex_lock(&c->state_lock);
-
- if (ca->mi.state == BCH_MEMBER_STATE_RW &&
- bch2_dev_is_online(ca)) {
- bch_err(ca, "Cannot migrate data off RW device");
- ret = -EINVAL;
- goto err;
- }
-
- ret = bch2_dev_data_migrate(c, ca, 0);
- if (ret) {
- bch_err(ca, "Error migrating data: %i", ret);
- goto err;
- }
-
- ret = bch2_journal_flush_device(&c->journal, ca->dev_idx);
- if (ret) {
- bch_err(ca, "Migrate failed: error %i flushing journal", ret);
- goto err;
- }
-
- data = bch2_dev_has_data(c, ca);
- if (data) {
- char buf[100];
-
- bch2_scnprint_flag_list(buf, sizeof(buf),
- bch2_data_types, data);
- bch_err(ca, "Migrate failed, still has data (%s)", buf);
- ret = -EINVAL;
- goto err;
- }
-err:
- mutex_unlock(&c->state_lock);
- return ret;
-}
-
int bch2_dev_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
{
struct bch_member *mi;
diff --git a/fs/bcachefs/super.h b/fs/bcachefs/super.h
index 751ee20ae0b5..d0a38cf67508 100644
--- a/fs/bcachefs/super.h
+++ b/fs/bcachefs/super.h
@@ -188,7 +188,6 @@ int bch2_dev_remove(struct bch_fs *, struct bch_dev *, int);
int bch2_dev_add(struct bch_fs *, const char *);
int bch2_dev_online(struct bch_fs *, const char *);
int bch2_dev_offline(struct bch_fs *, struct bch_dev *, int);
-int bch2_dev_evacuate(struct bch_fs *, struct bch_dev *);
int bch2_dev_resize(struct bch_fs *, struct bch_dev *, u64);
bool bch2_fs_emergency_read_only(struct bch_fs *);
diff --git a/fs/bcachefs/tier.c b/fs/bcachefs/tier.c
index 6a581097a7e6..c4625c80bbf8 100644
--- a/fs/bcachefs/tier.c
+++ b/fs/bcachefs/tier.c
@@ -44,6 +44,7 @@ static int bch2_tiering_thread(void *arg)
unsigned long last;
unsigned i, nr_devices;
+ memset(&move_stats, 0, sizeof(move_stats));
set_freezable();
while (!kthread_should_stop()) {
@@ -91,6 +92,7 @@ static int bch2_tiering_thread(void *arg)
writepoint_ptr(&tier->wp),
0,
-1,
+ POS_MIN, POS_MAX,
tiering_pred, tier,
&move_stats);
}