mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-22 00:00:03 +03:00
Update bcachefs sources to 5d7142b75a bcachefs: Redo filesystem usage ioctls
This commit is contained in:
parent
54fc3909b4
commit
f026d7cc81
@ -1 +1 @@
|
||||
a8faf2472b83bb675aceca3e43f20d232409b1cc
|
||||
5d7142b75a6eb52f7398fd119971c14d76add6ba
|
||||
|
@ -1080,6 +1080,9 @@ struct bch_replicas_entry {
|
||||
__u8 devs[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define replicas_entry_bytes(_i) \
|
||||
(offsetof(typeof(*(_i)), devs) + (_i)->nr_devs)
|
||||
|
||||
struct bch_sb_field_replicas {
|
||||
struct bch_sb_field field;
|
||||
struct bch_replicas_entry entries[0];
|
||||
|
@ -68,7 +68,8 @@ struct bch_ioctl_incremental {
|
||||
#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_DATA _IOW(0xbc, 10, struct bch_ioctl_data)
|
||||
#define BCH_IOCTL_USAGE _IOWR(0xbc, 11, struct bch_ioctl_usage)
|
||||
#define BCH_IOCTL_FS_USAGE _IOWR(0xbc, 11, struct bch_ioctl_fs_usage)
|
||||
#define BCH_IOCTL_DEV_USAGE _IOWR(0xbc, 11, struct bch_ioctl_dev_usage)
|
||||
#define BCH_IOCTL_READ_SUPER _IOW(0xbc, 12, struct bch_ioctl_read_super)
|
||||
#define BCH_IOCTL_DISK_GET_IDX _IOW(0xbc, 13, struct bch_ioctl_disk_get_idx)
|
||||
#define BCH_IOCTL_DISK_RESIZE _IOW(0xbc, 14, struct bch_ioctl_disk_resize)
|
||||
@ -224,11 +225,53 @@ struct bch_ioctl_data_event {
|
||||
};
|
||||
} __attribute__((packed, aligned(8)));
|
||||
|
||||
struct bch_replicas_usage {
|
||||
__u64 sectors;
|
||||
struct bch_replicas_entry r;
|
||||
} __attribute__((packed));
|
||||
|
||||
static inline struct bch_replicas_usage *
|
||||
replicas_usage_next(struct bch_replicas_usage *u)
|
||||
{
|
||||
return (void *) u + replicas_entry_bytes(&u->r) + 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* BCH_IOCTL_FS_USAGE: query filesystem disk space usage
|
||||
*
|
||||
* 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_fs_usage {
|
||||
__u64 capacity;
|
||||
__u64 used;
|
||||
__u64 online_reserved;
|
||||
__u64 persistent_reserved[BCH_REPLICAS_MAX];
|
||||
|
||||
__u32 replica_entries_bytes;
|
||||
__u32 pad;
|
||||
|
||||
struct bch_replicas_usage replicas[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* BCH_IOCTL_DEV_USAGE: query device disk space usage
|
||||
*
|
||||
* Returns disk space usage broken out by data type - both by buckets and
|
||||
* sectors.
|
||||
*/
|
||||
struct bch_ioctl_dev_usage {
|
||||
__u64 dev;
|
||||
__u32 flags;
|
||||
__u8 state;
|
||||
__u8 alive;
|
||||
__u8 pad[6];
|
||||
__u32 dev;
|
||||
__u8 pad[7];
|
||||
|
||||
__u32 bucket_size;
|
||||
__u64 nr_buckets;
|
||||
@ -237,35 +280,6 @@ struct bch_ioctl_dev_usage {
|
||||
__u64 sectors[BCH_DATA_NR];
|
||||
};
|
||||
|
||||
struct bch_ioctl_fs_usage {
|
||||
__u64 capacity;
|
||||
__u64 used;
|
||||
__u64 online_reserved;
|
||||
__u64 persistent_reserved[BCH_REPLICAS_MAX];
|
||||
__u64 sectors[BCH_DATA_NR][BCH_REPLICAS_MAX];
|
||||
};
|
||||
|
||||
/*
|
||||
* BCH_IOCTL_USAGE: query filesystem disk space usage
|
||||
*
|
||||
* Returns disk space usage broken out by data type, number of replicas, and
|
||||
* by component device
|
||||
*
|
||||
* @nr_devices - number of devices userspace allocated space for in @devs
|
||||
*
|
||||
* On success, @fs and @devs will be filled out appropriately and devs[i].alive
|
||||
* will indicate if a device was present in that slot
|
||||
*
|
||||
* Returns -ERANGE if @nr_devices was too small
|
||||
*/
|
||||
struct bch_ioctl_usage {
|
||||
__u16 nr_devices;
|
||||
__u16 pad[3];
|
||||
|
||||
struct bch_ioctl_fs_usage fs;
|
||||
struct bch_ioctl_dev_usage devs[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* BCH_IOCTL_READ_SUPER: read filesystem superblock
|
||||
*
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "buckets.h"
|
||||
#include "chardev.h"
|
||||
#include "move.h"
|
||||
#include "replicas.h"
|
||||
#include "super.h"
|
||||
#include "super-io.h"
|
||||
|
||||
@ -371,13 +372,85 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long bch2_ioctl_usage(struct bch_fs *c,
|
||||
struct bch_ioctl_usage __user *user_arg)
|
||||
static long bch2_ioctl_fs_usage(struct bch_fs *c,
|
||||
struct bch_ioctl_fs_usage __user *user_arg)
|
||||
{
|
||||
struct bch_ioctl_usage arg;
|
||||
struct bch_ioctl_fs_usage *arg = NULL;
|
||||
struct bch_replicas_usage *dst_e, *dst_end;
|
||||
struct bch_fs_usage *src;
|
||||
u32 replica_entries_bytes;
|
||||
unsigned i;
|
||||
int ret = 0;
|
||||
|
||||
if (!test_bit(BCH_FS_STARTED, &c->flags))
|
||||
return -EINVAL;
|
||||
|
||||
if (get_user(replica_entries_bytes, &user_arg->replica_entries_bytes))
|
||||
return -EFAULT;
|
||||
|
||||
arg = kzalloc(sizeof(*arg) + replica_entries_bytes, GFP_KERNEL);
|
||||
if (!arg)
|
||||
return -ENOMEM;
|
||||
|
||||
src = bch2_fs_usage_read(c);
|
||||
if (!src) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
arg->capacity = c->capacity;
|
||||
arg->used = bch2_fs_sectors_used(c, src);
|
||||
arg->online_reserved = src->online_reserved;
|
||||
|
||||
for (i = 0; i < BCH_REPLICAS_MAX; i++)
|
||||
arg->persistent_reserved[i] = src->persistent_reserved[i];
|
||||
|
||||
dst_e = arg->replicas;
|
||||
dst_end = (void *) arg->replicas + replica_entries_bytes;
|
||||
|
||||
for (i = 0; i < c->replicas.nr; i++) {
|
||||
struct bch_replicas_entry *src_e =
|
||||
cpu_replicas_entry(&c->replicas, i);
|
||||
|
||||
if (replicas_usage_next(dst_e) > dst_end) {
|
||||
ret = -ERANGE;
|
||||
break;
|
||||
}
|
||||
|
||||
dst_e->sectors = src->replicas[i];
|
||||
dst_e->r = *src_e;
|
||||
|
||||
/* recheck after setting nr_devs: */
|
||||
if (replicas_usage_next(dst_e) > dst_end) {
|
||||
ret = -ERANGE;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(dst_e->r.devs, src_e->devs, src_e->nr_devs);
|
||||
|
||||
dst_e = replicas_usage_next(dst_e);
|
||||
}
|
||||
|
||||
arg->replica_entries_bytes = (void *) dst_e - (void *) arg->replicas;
|
||||
|
||||
percpu_up_read(&c->mark_lock);
|
||||
kfree(src);
|
||||
|
||||
if (!ret)
|
||||
ret = copy_to_user(user_arg, arg,
|
||||
sizeof(*arg) + arg->replica_entries_bytes);
|
||||
err:
|
||||
kfree(arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long bch2_ioctl_dev_usage(struct bch_fs *c,
|
||||
struct bch_ioctl_dev_usage __user *user_arg)
|
||||
{
|
||||
struct bch_ioctl_dev_usage arg;
|
||||
struct bch_dev_usage src;
|
||||
struct bch_dev *ca;
|
||||
unsigned i, j;
|
||||
int ret;
|
||||
unsigned i;
|
||||
|
||||
if (!test_bit(BCH_FS_STARTED, &c->flags))
|
||||
return -EINVAL;
|
||||
@ -385,75 +458,30 @@ static long bch2_ioctl_usage(struct bch_fs *c,
|
||||
if (copy_from_user(&arg, user_arg, sizeof(arg)))
|
||||
return -EFAULT;
|
||||
|
||||
for (i = 0; i < arg.nr_devices; i++) {
|
||||
struct bch_ioctl_dev_usage dst = { .alive = 0 };
|
||||
if ((arg.flags & ~BCH_BY_INDEX) ||
|
||||
arg.pad[0] ||
|
||||
arg.pad[1] ||
|
||||
arg.pad[2])
|
||||
return -EINVAL;
|
||||
|
||||
ret = copy_to_user(&user_arg->devs[i], &dst, sizeof(dst));
|
||||
if (ret)
|
||||
return ret;
|
||||
ca = bch2_device_lookup(c, arg.dev, arg.flags);
|
||||
if (IS_ERR(ca))
|
||||
return PTR_ERR(ca);
|
||||
|
||||
src = bch2_dev_usage_read(c, ca);
|
||||
|
||||
arg.state = ca->mi.state;
|
||||
arg.bucket_size = ca->mi.bucket_size;
|
||||
arg.nr_buckets = ca->mi.nbuckets - ca->mi.first_bucket;
|
||||
|
||||
for (i = 0; i < BCH_DATA_NR; i++) {
|
||||
arg.buckets[i] = src.buckets[i];
|
||||
arg.sectors[i] = src.sectors[i];
|
||||
}
|
||||
|
||||
{
|
||||
struct bch_fs_usage *src;
|
||||
struct bch_ioctl_fs_usage dst = {
|
||||
.capacity = c->capacity,
|
||||
};
|
||||
percpu_ref_put(&ca->ref);
|
||||
|
||||
src = bch2_fs_usage_read(c);
|
||||
if (!src)
|
||||
return -ENOMEM;
|
||||
|
||||
dst.used = bch2_fs_sectors_used(c, src);
|
||||
dst.online_reserved = src->online_reserved;
|
||||
|
||||
percpu_up_read(&c->mark_lock);
|
||||
|
||||
for (i = 0; i < BCH_REPLICAS_MAX; i++) {
|
||||
dst.persistent_reserved[i] =
|
||||
src->persistent_reserved[i];
|
||||
#if 0
|
||||
for (j = 0; j < BCH_DATA_NR; j++)
|
||||
dst.sectors[j][i] = src.replicas[i].data[j];
|
||||
#endif
|
||||
}
|
||||
|
||||
kfree(src);
|
||||
|
||||
ret = copy_to_user(&user_arg->fs, &dst, sizeof(dst));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
for_each_member_device(ca, c, i) {
|
||||
struct bch_dev_usage src = bch2_dev_usage_read(c, ca);
|
||||
struct bch_ioctl_dev_usage dst = {
|
||||
.alive = 1,
|
||||
.state = ca->mi.state,
|
||||
.bucket_size = ca->mi.bucket_size,
|
||||
.nr_buckets = ca->mi.nbuckets - ca->mi.first_bucket,
|
||||
};
|
||||
|
||||
if (ca->dev_idx >= arg.nr_devices) {
|
||||
percpu_ref_put(&ca->ref);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (percpu_ref_tryget(&ca->io_ref)) {
|
||||
dst.dev = huge_encode_dev(ca->disk_sb.bdev->bd_dev);
|
||||
percpu_ref_put(&ca->io_ref);
|
||||
}
|
||||
|
||||
for (j = 0; j < BCH_DATA_NR; j++) {
|
||||
dst.buckets[j] = src.buckets[j];
|
||||
dst.sectors[j] = src.sectors[j];
|
||||
}
|
||||
|
||||
ret = copy_to_user(&user_arg->devs[i], &dst, sizeof(dst));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return copy_to_user(user_arg, &arg, sizeof(arg));
|
||||
}
|
||||
|
||||
static long bch2_ioctl_read_super(struct bch_fs *c,
|
||||
@ -547,8 +575,10 @@ long bch2_fs_ioctl(struct bch_fs *c, unsigned cmd, void __user *arg)
|
||||
switch (cmd) {
|
||||
case BCH_IOCTL_QUERY_UUID:
|
||||
return bch2_ioctl_query_uuid(c, arg);
|
||||
case BCH_IOCTL_USAGE:
|
||||
return bch2_ioctl_usage(c, arg);
|
||||
case BCH_IOCTL_FS_USAGE:
|
||||
return bch2_ioctl_fs_usage(c, arg);
|
||||
case BCH_IOCTL_DEV_USAGE:
|
||||
return bch2_ioctl_dev_usage(c, arg);
|
||||
}
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
|
@ -72,9 +72,6 @@ int bch2_replicas_set_usage(struct bch_fs *,
|
||||
|
||||
/* iterate over superblock replicas - used by userspace tools: */
|
||||
|
||||
#define replicas_entry_bytes(_i) \
|
||||
(offsetof(typeof(*(_i)), devs) + (_i)->nr_devs)
|
||||
|
||||
#define replicas_entry_next(_i) \
|
||||
((typeof(_i)) ((void *) (_i) + replicas_entry_bytes(_i)))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user