diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2017-12-24 22:04:28 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-02-08 15:23:07 -0500 |
commit | d5e561b3cc023dd247d2b3d08b680709ec21b477 (patch) | |
tree | 599c8eb006f519ed077947a1b7ef67916125fc78 | |
parent | f093d9e193341749c3e1acd72f2d3a0c56914b11 (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.h | 44 | ||||
-rw-r--r-- | fs/bcachefs/chardev.c | 124 | ||||
-rw-r--r-- | fs/bcachefs/migrate.c | 3 | ||||
-rw-r--r-- | fs/bcachefs/move.c | 221 | ||||
-rw-r--r-- | fs/bcachefs/move.h | 8 | ||||
-rw-r--r-- | fs/bcachefs/movinggc.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/super.c | 41 | ||||
-rw-r--r-- | fs/bcachefs/super.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/tier.c | 2 |
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); } |