bcachefs: BCH_IOCTL_QUERY_ACCOUNTING
Add a new ioctl that can return the new accounting counter types; it takes as input a bitmask of accounting types to return. This will be used for returning e.g. compression accounting and rebalance_work accounting. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
7f3dc6c98b
commit
8863d1e092
@ -5,6 +5,7 @@
|
||||
#include <linux/uuid.h>
|
||||
#include <asm/ioctl.h>
|
||||
#include "bcachefs_format.h"
|
||||
#include "bkey_types.h"
|
||||
|
||||
/*
|
||||
* Flags common to multiple ioctls:
|
||||
@ -85,6 +86,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)
|
||||
|
||||
/* ioctl below act on a particular file, not the filesystem as a whole: */
|
||||
|
||||
@ -262,6 +264,7 @@ replicas_usage_next(struct bch_replicas_usage *u)
|
||||
return (void *) u + replicas_usage_bytes(u);
|
||||
}
|
||||
|
||||
/* Obsolete */
|
||||
/*
|
||||
* BCH_IOCTL_FS_USAGE: query filesystem disk space usage
|
||||
*
|
||||
@ -287,6 +290,7 @@ struct bch_ioctl_fs_usage {
|
||||
struct bch_replicas_usage replicas[];
|
||||
};
|
||||
|
||||
/* Obsolete */
|
||||
/*
|
||||
* BCH_IOCTL_DEV_USAGE: query device disk space usage
|
||||
*
|
||||
@ -311,6 +315,7 @@ struct bch_ioctl_dev_usage {
|
||||
} d[10];
|
||||
};
|
||||
|
||||
/* Obsolete */
|
||||
struct bch_ioctl_dev_usage_v2 {
|
||||
__u64 dev;
|
||||
__u32 flags;
|
||||
@ -414,4 +419,28 @@ struct bch_ioctl_fsck_online {
|
||||
__u64 opts; /* string */
|
||||
};
|
||||
|
||||
/*
|
||||
* BCH_IOCTL_QUERY_ACCOUNTING: query filesystem disk accounting
|
||||
*
|
||||
* Returns disk space usage broken out by data type, number of replicas, and
|
||||
* by component device
|
||||
*
|
||||
* @replica_entries_bytes - size, in bytes, allocated for replica usage entries
|
||||
*
|
||||
* On success, @replica_entries_bytes will be changed to indicate the number of
|
||||
* bytes actually used.
|
||||
*
|
||||
* Returns -ERANGE if @replica_entries_bytes was too small
|
||||
*/
|
||||
struct bch_ioctl_query_accounting {
|
||||
__u64 capacity;
|
||||
__u64 used;
|
||||
__u64 online_reserved;
|
||||
|
||||
__u32 accounting_u64s; /* input parameter */
|
||||
__u32 accounting_types_mask; /* input parameter */
|
||||
|
||||
struct bkey_i_accounting accounting[];
|
||||
};
|
||||
|
||||
#endif /* _BCACHEFS_IOCTL_H */
|
||||
|
@ -557,6 +557,34 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long bch2_ioctl_query_accounting(struct bch_fs *c,
|
||||
struct bch_ioctl_query_accounting __user *user_arg)
|
||||
{
|
||||
struct bch_ioctl_query_accounting arg;
|
||||
darray_char accounting = {};
|
||||
int ret = 0;
|
||||
|
||||
if (!test_bit(BCH_FS_started, &c->flags))
|
||||
return -EINVAL;
|
||||
|
||||
ret = copy_from_user_errcode(&arg, user_arg, sizeof(arg)) ?:
|
||||
bch2_fs_accounting_read(c, &accounting, arg.accounting_types_mask) ?:
|
||||
(arg.accounting_u64s * sizeof(u64) < accounting.nr ? -ERANGE : 0) ?:
|
||||
copy_to_user_errcode(&user_arg->accounting, accounting.data, accounting.nr);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
arg.capacity = c->capacity;
|
||||
arg.used = bch2_fs_usage_read_short(c).used;
|
||||
arg.online_reserved = percpu_u64_get(c->online_reserved);
|
||||
arg.accounting_u64s = accounting.nr / sizeof(u64);
|
||||
|
||||
ret = copy_to_user_errcode(user_arg, &arg, sizeof(arg));
|
||||
err:
|
||||
darray_exit(&accounting);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* obsolete, didn't allow for new data types: */
|
||||
static long bch2_ioctl_dev_usage(struct bch_fs *c,
|
||||
struct bch_ioctl_dev_usage __user *user_arg)
|
||||
@ -910,6 +938,8 @@ long bch2_fs_ioctl(struct bch_fs *c, unsigned cmd, void __user *arg)
|
||||
BCH_IOCTL(disk_resize_journal, struct bch_ioctl_disk_resize_journal);
|
||||
case BCH_IOCTL_FSCK_ONLINE:
|
||||
BCH_IOCTL(fsck_online, struct bch_ioctl_fsck_online);
|
||||
case BCH_IOCTL_QUERY_ACCOUNTING:
|
||||
return bch2_ioctl_query_accounting(c, arg);
|
||||
default:
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
@ -315,6 +315,44 @@ int bch2_fs_replicas_usage_read(struct bch_fs *c, darray_char *usage)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bch2_fs_accounting_read(struct bch_fs *c, darray_char *out_buf, unsigned accounting_types_mask)
|
||||
{
|
||||
|
||||
struct bch_accounting_mem *acc = &c->accounting[0];
|
||||
int ret = 0;
|
||||
|
||||
darray_init(out_buf);
|
||||
|
||||
percpu_down_read(&c->mark_lock);
|
||||
darray_for_each(acc->k, i) {
|
||||
struct disk_accounting_pos a_p;
|
||||
bpos_to_disk_accounting_pos(&a_p, i->pos);
|
||||
|
||||
if (!(accounting_types_mask & BIT(a_p.type)))
|
||||
continue;
|
||||
|
||||
ret = darray_make_room(out_buf, sizeof(struct bkey_i_accounting) +
|
||||
sizeof(u64) * i->nr_counters);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
struct bkey_i_accounting *a_out =
|
||||
bkey_accounting_init((void *) &darray_top(*out_buf));
|
||||
set_bkey_val_u64s(&a_out->k, i->nr_counters);
|
||||
a_out->k.p = i->pos;
|
||||
bch2_accounting_mem_read(c, i->pos, a_out->v.d, i->nr_counters);
|
||||
|
||||
if (!bch2_accounting_key_is_zero(accounting_i_to_s_c(a_out)))
|
||||
out_buf->nr += bkey_bytes(&a_out->k);
|
||||
}
|
||||
|
||||
percpu_up_read(&c->mark_lock);
|
||||
|
||||
if (ret)
|
||||
darray_exit(out_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void bch2_fs_accounting_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
{
|
||||
struct bch_accounting_mem *acc = &c->accounting[0];
|
||||
|
@ -193,6 +193,7 @@ static inline void bch2_accounting_mem_read(struct bch_fs *c, struct bpos p,
|
||||
}
|
||||
|
||||
int bch2_fs_replicas_usage_read(struct bch_fs *, darray_char *);
|
||||
int bch2_fs_accounting_read(struct bch_fs *, darray_char *, unsigned);
|
||||
void bch2_fs_accounting_to_text(struct printbuf *, struct bch_fs *);
|
||||
|
||||
int bch2_accounting_gc_done(struct bch_fs *);
|
||||
|
Loading…
Reference in New Issue
Block a user