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>
This commit is contained in:
Kent Overstreet 2025-01-26 22:05:02 -05:00
parent 5ee760f667
commit 50ca857457
4 changed files with 60 additions and 0 deletions

View File

@ -87,6 +87,7 @@ struct bch_ioctl_incremental {
#define BCH_IOCTL_FSCK_OFFLINE _IOW(0xbc, 19, struct bch_ioctl_fsck_offline)
#define BCH_IOCTL_FSCK_ONLINE _IOW(0xbc, 20, struct bch_ioctl_fsck_online)
#define BCH_IOCTL_QUERY_ACCOUNTING _IOW(0xbc, 21, struct bch_ioctl_query_accounting)
#define BCH_IOCTL_QUERY_COUNTERS _IOW(0xbc, 21, struct bch_ioctl_query_counters)
/* ioctl below act on a particular file, not the filesystem as a whole: */
@ -443,4 +444,13 @@ struct bch_ioctl_query_accounting {
struct bkey_i_accounting accounting[];
};
#define BCH_IOCTL_QUERY_COUNTERS_MOUNT (1 << 0)
struct bch_ioctl_query_counters {
__u16 nr;
__u16 flags;
__u32 pad;
__u64 d[];
};
#endif /* _BCACHEFS_IOCTL_H */

View File

@ -11,6 +11,7 @@
#include "move.h"
#include "recovery_passes.h"
#include "replicas.h"
#include "sb-counters.h"
#include "super-io.h"
#include "thread_with_file.h"
@ -710,6 +711,8 @@ long bch2_fs_ioctl(struct bch_fs *c, unsigned cmd, void __user *arg)
BCH_IOCTL(fsck_online, struct bch_ioctl_fsck_online);
case BCH_IOCTL_QUERY_ACCOUNTING:
return bch2_ioctl_query_accounting(c, arg);
case BCH_IOCTL_QUERY_COUNTERS:
return bch2_ioctl_query_counters(c, arg);
default:
return -ENOTTY;
}

View File

@ -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

View File

@ -11,6 +11,10 @@ int bch2_sb_counters_from_cpu(struct bch_fs *);
void bch2_fs_counters_exit(struct bch_fs *);
int bch2_fs_counters_init(struct bch_fs *);
extern const char * const bch2_counter_names[];
extern const struct bch_sb_field_ops bch_sb_field_ops_counters;
long bch2_ioctl_query_counters(struct bch_fs *,
struct bch_ioctl_query_counters __user *);
#endif // _BCACHEFS_SB_COUNTERS_H