mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-23 00:00:02 +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];
|
__u8 devs[0];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define replicas_entry_bytes(_i) \
|
||||||
|
(offsetof(typeof(*(_i)), devs) + (_i)->nr_devs)
|
||||||
|
|
||||||
struct bch_sb_field_replicas {
|
struct bch_sb_field_replicas {
|
||||||
struct bch_sb_field field;
|
struct bch_sb_field field;
|
||||||
struct bch_replicas_entry entries[0];
|
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_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_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_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_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_GET_IDX _IOW(0xbc, 13, struct bch_ioctl_disk_get_idx)
|
||||||
#define BCH_IOCTL_DISK_RESIZE _IOW(0xbc, 14, struct bch_ioctl_disk_resize)
|
#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)));
|
} __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 {
|
struct bch_ioctl_dev_usage {
|
||||||
|
__u64 dev;
|
||||||
|
__u32 flags;
|
||||||
__u8 state;
|
__u8 state;
|
||||||
__u8 alive;
|
__u8 pad[7];
|
||||||
__u8 pad[6];
|
|
||||||
__u32 dev;
|
|
||||||
|
|
||||||
__u32 bucket_size;
|
__u32 bucket_size;
|
||||||
__u64 nr_buckets;
|
__u64 nr_buckets;
|
||||||
@ -237,35 +280,6 @@ struct bch_ioctl_dev_usage {
|
|||||||
__u64 sectors[BCH_DATA_NR];
|
__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
|
* BCH_IOCTL_READ_SUPER: read filesystem superblock
|
||||||
*
|
*
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "buckets.h"
|
#include "buckets.h"
|
||||||
#include "chardev.h"
|
#include "chardev.h"
|
||||||
#include "move.h"
|
#include "move.h"
|
||||||
|
#include "replicas.h"
|
||||||
#include "super.h"
|
#include "super.h"
|
||||||
#include "super-io.h"
|
#include "super-io.h"
|
||||||
|
|
||||||
@ -371,13 +372,85 @@ err:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long bch2_ioctl_usage(struct bch_fs *c,
|
static long bch2_ioctl_fs_usage(struct bch_fs *c,
|
||||||
struct bch_ioctl_usage __user *user_arg)
|
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;
|
struct bch_dev *ca;
|
||||||
unsigned i, j;
|
unsigned i;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!test_bit(BCH_FS_STARTED, &c->flags))
|
if (!test_bit(BCH_FS_STARTED, &c->flags))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -385,75 +458,30 @@ static long bch2_ioctl_usage(struct bch_fs *c,
|
|||||||
if (copy_from_user(&arg, user_arg, sizeof(arg)))
|
if (copy_from_user(&arg, user_arg, sizeof(arg)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
for (i = 0; i < arg.nr_devices; i++) {
|
if ((arg.flags & ~BCH_BY_INDEX) ||
|
||||||
struct bch_ioctl_dev_usage dst = { .alive = 0 };
|
arg.pad[0] ||
|
||||||
|
arg.pad[1] ||
|
||||||
|
arg.pad[2])
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
ret = copy_to_user(&user_arg->devs[i], &dst, sizeof(dst));
|
ca = bch2_device_lookup(c, arg.dev, arg.flags);
|
||||||
if (ret)
|
if (IS_ERR(ca))
|
||||||
return ret;
|
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];
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
percpu_ref_put(&ca->ref);
|
||||||
struct bch_fs_usage *src;
|
|
||||||
struct bch_ioctl_fs_usage dst = {
|
|
||||||
.capacity = c->capacity,
|
|
||||||
};
|
|
||||||
|
|
||||||
src = bch2_fs_usage_read(c);
|
return copy_to_user(user_arg, &arg, sizeof(arg));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long bch2_ioctl_read_super(struct bch_fs *c,
|
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) {
|
switch (cmd) {
|
||||||
case BCH_IOCTL_QUERY_UUID:
|
case BCH_IOCTL_QUERY_UUID:
|
||||||
return bch2_ioctl_query_uuid(c, arg);
|
return bch2_ioctl_query_uuid(c, arg);
|
||||||
case BCH_IOCTL_USAGE:
|
case BCH_IOCTL_FS_USAGE:
|
||||||
return bch2_ioctl_usage(c, arg);
|
return bch2_ioctl_fs_usage(c, arg);
|
||||||
|
case BCH_IOCTL_DEV_USAGE:
|
||||||
|
return bch2_ioctl_dev_usage(c, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
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: */
|
/* 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) \
|
#define replicas_entry_next(_i) \
|
||||||
((typeof(_i)) ((void *) (_i) + replicas_entry_bytes(_i)))
|
((typeof(_i)) ((void *) (_i) + replicas_entry_bytes(_i)))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user