summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/sb-counters.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2025-01-26 22:05:02 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2025-03-14 21:02:11 -0400
commit50ca857457e0a983bc6f881fcb1c47f8322a2c48 (patch)
tree7f13f2201350477abd6466372216583628589f63 /fs/bcachefs/sb-counters.c
parentbcachefs: BCH_COUNTER_bucket_discard_fast (diff)
downloadlinux-50ca857457e0a983bc6f881fcb1c47f8322a2c48.tar.gz
linux-50ca857457e0a983bc6f881fcb1c47f8322a2c48.zip
bcachefs: BCH_IOCTL_QUERY_COUNTERS
Add an ioctl for querying counters, the same ones provided in /sys/fs/bcachefs/<uuid>/counters/, but more suitable for a 'bcachefs top' command. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/sb-counters.c')
-rw-r--r--fs/bcachefs/sb-counters.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/fs/bcachefs/sb-counters.c b/fs/bcachefs/sb-counters.c
index 5153a47ec7d4..2b4b8445d418 100644
--- a/fs/bcachefs/sb-counters.c
+++ b/fs/bcachefs/sb-counters.c
@@ -11,6 +11,13 @@ static const u8 counters_to_stable_map[] = {
#undef x
};
+const char * const bch2_counter_names[] = {
+#define x(t, n, ...) (#t),
+ BCH_PERSISTENT_COUNTERS()
+#undef x
+ NULL
+};
+
static size_t bch2_sb_counter_nr_entries(struct bch_sb_field_counters *ctrs)
{
if (!ctrs)
@@ -102,3 +109,39 @@ const struct bch_sb_field_ops bch_sb_field_ops_counters = {
.validate = bch2_sb_counters_validate,
.to_text = bch2_sb_counters_to_text,
};
+
+#ifndef NO_BCACHEFS_CHARDEV
+long bch2_ioctl_query_counters(struct bch_fs *c,
+ struct bch_ioctl_query_counters __user *user_arg)
+{
+ struct bch_ioctl_query_counters arg;
+ int ret = copy_from_user_errcode(&arg, user_arg, sizeof(arg));
+ if (ret)
+ return ret;
+
+ if ((arg.flags & ~BCH_IOCTL_QUERY_COUNTERS_MOUNT) ||
+ arg.pad)
+ return -EINVAL;
+
+ arg.nr = min(arg.nr, BCH_COUNTER_NR);
+ ret = put_user(arg.nr, &user_arg->nr);
+ if (ret)
+ return ret;
+
+ for (unsigned i = 0; i < BCH_COUNTER_NR; i++) {
+ unsigned stable = counters_to_stable_map[i];
+
+ if (stable < arg.nr) {
+ u64 v = !(arg.flags & BCH_IOCTL_QUERY_COUNTERS_MOUNT)
+ ? percpu_u64_get(&c->counters[i])
+ : c->counters_on_mount[i];
+
+ ret = put_user(v, &user_arg->d[stable]);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+#endif