summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorBrett Holman <bholman.devel@gmail.com>2021-07-23 22:57:19 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:10 +0300
commit8dd6ed9451894e2168328e2203d227303b472ca3 (patch)
tree8b2b411aa819dbd93a8b584dd6411f5a0890d251 /fs
parentfd0bd123d5bc11d665ad0e80eaf4b458619f8b3d (diff)
downloadlinux-8dd6ed9451894e2168328e2203d227303b472ca3.tar.xz
bcachefs: add progress stats to sysfs
This adds progress stats to sysfs for copygc, rebalance, recovery, and the cmd_job ioctls. Signed-off-by: Brett Holman <bholman.devel@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/bcachefs.h4
-rw-r--r--fs/bcachefs/move.c31
-rw-r--r--fs/bcachefs/move.h4
-rw-r--r--fs/bcachefs/move_types.h2
-rw-r--r--fs/bcachefs/movinggc.c3
-rw-r--r--fs/bcachefs/rebalance.c11
-rw-r--r--fs/bcachefs/rebalance_types.h1
-rw-r--r--fs/bcachefs/recovery.c4
-rw-r--r--fs/bcachefs/super.c3
-rw-r--r--fs/bcachefs/sysfs.c40
10 files changed, 94 insertions, 9 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
index 6a289b6f1fb4..e2aac1da18ae 100644
--- a/fs/bcachefs/bcachefs.h
+++ b/fs/bcachefs/bcachefs.h
@@ -792,6 +792,10 @@ mempool_t bio_bounce_pages;
struct write_point copygc_write_point;
s64 copygc_wait;
+ /* DATA PROGRESS STATS */
+ struct list_head data_progress_list;
+ struct mutex data_progress_lock;
+
/* STRIPES: */
GENRADIX(struct stripe) stripes[2];
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
index 9a423a3e4570..8d28d8fc5395 100644
--- a/fs/bcachefs/move.c
+++ b/fs/bcachefs/move.c
@@ -686,6 +686,30 @@ out:
return ret;
}
+inline void bch_move_stats_init(struct bch_move_stats *stats, char *name)
+{
+ memset(stats, 0, sizeof(*stats));
+
+ scnprintf(stats->name, sizeof(stats->name),
+ "%s", name);
+}
+
+static inline void progress_list_add(struct bch_fs *c,
+ struct bch_move_stats *stats)
+{
+ mutex_lock(&c->data_progress_lock);
+ list_add(&stats->list, &c->data_progress_list);
+ mutex_unlock(&c->data_progress_lock);
+}
+
+static inline void progress_list_del(struct bch_fs *c,
+ struct bch_move_stats *stats)
+{
+ mutex_lock(&c->data_progress_lock);
+ list_del(&stats->list);
+ mutex_unlock(&c->data_progress_lock);
+}
+
int bch2_move_data(struct bch_fs *c,
enum btree_id start_btree_id, struct bpos start_pos,
enum btree_id end_btree_id, struct bpos end_pos,
@@ -698,6 +722,7 @@ int bch2_move_data(struct bch_fs *c,
enum btree_id id;
int ret;
+ progress_list_add(c, stats);
closure_init_stack(&ctxt.cl);
INIT_LIST_HEAD(&ctxt.reads);
init_waitqueue_head(&ctxt.wait);
@@ -731,6 +756,7 @@ int bch2_move_data(struct bch_fs *c,
atomic64_read(&stats->sectors_moved),
atomic64_read(&stats->keys_moved));
+ progress_list_del(c, stats);
return ret;
}
@@ -755,6 +781,7 @@ static int bch2_move_btree(struct bch_fs *c,
int ret = 0;
bch2_trans_init(&trans, c, 0, 0);
+ progress_list_add(c, stats);
stats->data_type = BCH_DATA_btree;
@@ -803,6 +830,7 @@ next:
if (ret)
bch_err(c, "error %i in bch2_move_btree", ret);
+ progress_list_del(c, stats);
return ret;
}
@@ -944,6 +972,7 @@ int bch2_data_job(struct bch_fs *c,
switch (op.op) {
case BCH_DATA_OP_REREPLICATE:
+ bch_move_stats_init(stats, "rereplicate");
stats->data_type = BCH_DATA_journal;
ret = bch2_journal_flush_device_pins(&c->journal, -1);
@@ -968,6 +997,7 @@ int bch2_data_job(struct bch_fs *c,
if (op.migrate.dev >= c->sb.nr_devices)
return -EINVAL;
+ bch_move_stats_init(stats, "migrate");
stats->data_type = BCH_DATA_journal;
ret = bch2_journal_flush_device_pins(&c->journal, op.migrate.dev);
@@ -985,6 +1015,7 @@ int bch2_data_job(struct bch_fs *c,
ret = bch2_replicas_gc2(c) ?: ret;
break;
case BCH_DATA_OP_REWRITE_OLD_NODES:
+ bch_move_stats_init(stats, "rewrite_old_nodes");
ret = bch2_scan_old_btree_nodes(c, stats);
break;
default:
diff --git a/fs/bcachefs/move.h b/fs/bcachefs/move.h
index 99d6acb10880..901d8f875946 100644
--- a/fs/bcachefs/move.h
+++ b/fs/bcachefs/move.h
@@ -67,4 +67,8 @@ int bch2_data_job(struct bch_fs *,
struct bch_move_stats *,
struct bch_ioctl_data);
+inline void bch_move_stats_init(struct bch_move_stats *stats,
+ char *name);
+
+
#endif /* _BCACHEFS_MOVE_H */
diff --git a/fs/bcachefs/move_types.h b/fs/bcachefs/move_types.h
index fc0de165af9f..9df6d18137a5 100644
--- a/fs/bcachefs/move_types.h
+++ b/fs/bcachefs/move_types.h
@@ -6,6 +6,8 @@ struct bch_move_stats {
enum bch_data_type data_type;
enum btree_id btree_id;
struct bpos pos;
+ struct list_head list;
+ char name[32];
atomic64_t keys_moved;
atomic64_t keys_raced;
diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c
index 651381a5ccc5..b05dcbbd1a47 100644
--- a/fs/bcachefs/movinggc.c
+++ b/fs/bcachefs/movinggc.c
@@ -147,7 +147,8 @@ static int bch2_copygc(struct bch_fs *c)
size_t b, heap_size = 0;
int ret;
- memset(&move_stats, 0, sizeof(move_stats));
+ bch_move_stats_init(&move_stats, "copygc");
+
/*
* Find buckets with lowest sector counts, skipping completely
* empty buckets, by building a maxheap sorted by sector count,
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
index b7e61da0f4d1..fe0a1dbac199 100644
--- a/fs/bcachefs/rebalance.c
+++ b/fs/bcachefs/rebalance.c
@@ -166,6 +166,7 @@ static int bch2_rebalance_thread(void *arg)
struct bch_fs_rebalance *r = &c->rebalance;
struct io_clock *clock = &c->io_clock[WRITE];
struct rebalance_work w, p;
+ struct bch_move_stats move_stats;
unsigned long start, prev_start;
unsigned long prev_run_time, prev_run_cputime;
unsigned long cputime, prev_cputime;
@@ -179,6 +180,7 @@ static int bch2_rebalance_thread(void *arg)
prev_start = jiffies;
prev_cputime = curr_cputime();
+ bch_move_stats_init(&move_stats, "rebalance");
while (!kthread_wait_freezable(r->enabled)) {
cond_resched();
@@ -235,7 +237,7 @@ static int bch2_rebalance_thread(void *arg)
prev_cputime = cputime;
r->state = REBALANCE_RUNNING;
- memset(&r->move_stats, 0, sizeof(r->move_stats));
+ memset(&move_stats, 0, sizeof(move_stats));
rebalance_work_reset(c);
bch2_move_data(c,
@@ -245,7 +247,7 @@ static int bch2_rebalance_thread(void *arg)
NULL, /* &r->pd.rate, */
writepoint_ptr(&c->rebalance_write_point),
rebalance_pred, NULL,
- &r->move_stats);
+ &move_stats);
}
return 0;
@@ -281,10 +283,7 @@ void bch2_rebalance_work_to_text(struct printbuf *out, struct bch_fs *c)
h1);
break;
case REBALANCE_RUNNING:
- pr_buf(out, "running\n"
- "pos ");
- bch2_bpos_to_text(out, r->move_stats.pos);
- pr_buf(out, "\n");
+ pr_buf(out, "running\n");
break;
}
}
diff --git a/fs/bcachefs/rebalance_types.h b/fs/bcachefs/rebalance_types.h
index 2f62a643c39f..7462a92e9598 100644
--- a/fs/bcachefs/rebalance_types.h
+++ b/fs/bcachefs/rebalance_types.h
@@ -19,7 +19,6 @@ struct bch_fs_rebalance {
enum rebalance_state state;
u64 throttled_until_iotime;
unsigned long throttled_until_cputime;
- struct bch_move_stats move_stats;
unsigned enabled:1;
};
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index afb72648fe54..b02af94f4037 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -1216,7 +1216,9 @@ use_clean:
if (!(c->sb.compat & (1ULL << BCH_COMPAT_extents_above_btree_updates_done)) ||
!(c->sb.compat & (1ULL << BCH_COMPAT_bformat_overflow_done))) {
- struct bch_move_stats stats = { 0 };
+ struct bch_move_stats stats;
+
+ bch_move_stats_init(&stats, "recovery");
bch_info(c, "scanning for old btree nodes");
ret = bch2_fs_read_write(c);
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 11557a863d3d..1d793e554084 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -712,6 +712,9 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
INIT_LIST_HEAD(&c->ec_stripe_new_list);
mutex_init(&c->ec_stripe_new_lock);
+ INIT_LIST_HEAD(&c->data_progress_list);
+ mutex_init(&c->data_progress_lock);
+
spin_lock_init(&c->ec_stripes_heap_lock);
seqcount_init(&c->gc_pos_lock);
diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c
index 9b1ffbf96e14..b5ce336f00ca 100644
--- a/fs/bcachefs/sysfs.c
+++ b/fs/bcachefs/sysfs.c
@@ -203,6 +203,8 @@ read_attribute(new_stripes);
read_attribute(io_timers_read);
read_attribute(io_timers_write);
+read_attribute(data_op_data_progress);
+
#ifdef CONFIG_BCACHEFS_TESTS
write_attribute(perf_test);
#endif /* CONFIG_BCACHEFS_TESTS */
@@ -239,6 +241,37 @@ static size_t bch2_btree_avg_write_size(struct bch_fs *c)
return nr ? div64_u64(sectors, nr) : 0;
}
+static long stats_to_text(struct printbuf *out, struct bch_fs *c,
+ struct bch_move_stats *stats)
+{
+ pr_buf(out, "%s: data type %s btree_id %s position: ",
+ stats->name,
+ bch2_data_types[stats->data_type],
+ bch2_btree_ids[stats->btree_id]);
+ bch2_bpos_to_text(out, stats->pos);
+ pr_buf(out, "%s", "\n");
+
+ return 0;
+}
+
+static long data_progress_to_text(struct printbuf *out, struct bch_fs *c)
+{
+ long ret = 0;
+ struct bch_move_stats *iter;
+
+ mutex_lock(&c->data_progress_lock);
+
+ if (list_empty(&c->data_progress_list))
+ pr_buf(out, "%s", "no progress to report\n");
+ else
+ list_for_each_entry(iter, &c->data_progress_list, list) {
+ stats_to_text(out, c, iter);
+ }
+
+ mutex_unlock(&c->data_progress_lock);
+ return ret;
+}
+
static int fs_alloc_debug_to_text(struct printbuf *out, struct bch_fs *c)
{
struct bch_fs_usage_online *fs_usage = bch2_fs_usage_read(c);
@@ -434,6 +467,11 @@ SHOW(bch2_fs)
return out.pos - buf;
}
+ if (attr == &sysfs_data_op_data_progress) {
+ data_progress_to_text(&out, c);
+ return out.pos - buf;
+ }
+
return 0;
}
@@ -596,6 +634,8 @@ struct attribute *bch2_fs_internal_files[] = {
&sysfs_io_timers_read,
&sysfs_io_timers_write,
+ &sysfs_data_op_data_progress,
+
&sysfs_internal_uuid,
NULL
};