On 2019/8/5 下午9:19, Josef Bacik wrote: > In testing block group removal it's sometimes handy to be able to create > block groups on demand. Add an ioctl to allow us to force allocation > from userspace. > > Signed-off-by: Josef Bacik <jo...@toxicpanda.com> > --- > v1->v2: > - I noticed last week when backporting this that btrfs_chunk_alloc doesn't > figure out the rest of the flags needed for the type. Use > btrfs_force_chunk_alloc instead so that we get the raid settings for the > alloc > type we're using.
Still not sure if it's worthy to add a debug only ioctl. If sysfs is not good enough, maybe modify btrfs_force_chunk_alloc() to do extra chunk allocation depending on a internal return value overridable function? At least for the later case, we can trigger empty chunk allocation with BPF while without messing any interface. Thanks, Qu > > fs/btrfs/ioctl.c | 30 ++++++++++++++++++++++++++++++ > include/uapi/linux/btrfs.h | 1 + > 2 files changed, 31 insertions(+) > > diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c > index d0743ec1231d..891bf198d46a 100644 > --- a/fs/btrfs/ioctl.c > +++ b/fs/btrfs/ioctl.c > @@ -5553,6 +5553,34 @@ static int _btrfs_ioctl_send(struct file *file, void > __user *argp, bool compat) > return ret; > } > > +static long btrfs_ioctl_alloc_chunk(struct file *file, void __user *arg) > +{ > + struct btrfs_root *root = BTRFS_I(file_inode(file))->root; > + struct btrfs_trans_handle *trans; > + u64 flags; > + int ret; > + > + if (!capable(CAP_SYS_ADMIN)) > + return -EPERM; > + > + if (copy_from_user(&flags, arg, sizeof(flags))) > + return -EFAULT; > + > + /* We can only specify one type at a time. */ > + if (flags != BTRFS_BLOCK_GROUP_DATA && > + flags != BTRFS_BLOCK_GROUP_METADATA && > + flags != BTRFS_BLOCK_GROUP_SYSTEM) > + return -EINVAL; > + > + trans = btrfs_start_transaction(root, 0); > + if (IS_ERR(trans)) > + return PTR_ERR(trans); > + > + ret = btrfs_force_chunk_alloc(trans, flags); > + btrfs_end_transaction(trans); > + return ret < 0 ? ret : 0; > +} > + > long btrfs_ioctl(struct file *file, unsigned int > cmd, unsigned long arg) > { > @@ -5699,6 +5727,8 @@ long btrfs_ioctl(struct file *file, unsigned int > return btrfs_ioctl_get_subvol_rootref(file, argp); > case BTRFS_IOC_INO_LOOKUP_USER: > return btrfs_ioctl_ino_lookup_user(file, argp); > + case BTRFS_IOC_ALLOC_CHUNK: > + return btrfs_ioctl_alloc_chunk(file, argp); > } > > return -ENOTTY; > diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h > index c195896d478f..3a6474c34ad0 100644 > --- a/include/uapi/linux/btrfs.h > +++ b/include/uapi/linux/btrfs.h > @@ -943,5 +943,6 @@ enum btrfs_err_code { > struct btrfs_ioctl_get_subvol_rootref_args) > #define BTRFS_IOC_INO_LOOKUP_USER _IOWR(BTRFS_IOCTL_MAGIC, 62, \ > struct btrfs_ioctl_ino_lookup_user_args) > +#define BTRFS_IOC_ALLOC_CHUNK _IOR(BTRFS_IOCTL_MAGIC, 63, __u64) > > #endif /* _UAPI_LINUX_BTRFS_H */ >
signature.asc
Description: OpenPGP digital signature