Commit fdfb1e4f authored by Li Zefan's avatar Li Zefan Committed by Chris Mason

Btrfs: Make async snapshot ioctl more generic

If we had reserved some bytes in struct btrfs_ioctl_vol_args, we
wouldn't have to create a new structure for async snapshot creation.

Here we convert async snapshot ioctl to use a more generic ABI, as
we'll add more ioctls for snapshots/subvolumes in the future, readonly
snapshots for example.
Signed-off-by: default avatarLi Zefan <lizf@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 914ee295
...@@ -947,31 +947,41 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file, ...@@ -947,31 +947,41 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
static noinline int btrfs_ioctl_snap_create(struct file *file, static noinline int btrfs_ioctl_snap_create(struct file *file,
void __user *arg, int subvol, void __user *arg, int subvol,
int async) int v2)
{ {
struct btrfs_ioctl_vol_args *vol_args = NULL; struct btrfs_ioctl_vol_args *vol_args = NULL;
struct btrfs_ioctl_async_vol_args *async_vol_args = NULL; struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL;
char *name; char *name;
u64 fd; u64 fd;
u64 transid = 0;
int ret; int ret;
if (async) { if (v2) {
async_vol_args = memdup_user(arg, sizeof(*async_vol_args)); u64 transid = 0;
if (IS_ERR(async_vol_args)) u64 *ptr = NULL;
return PTR_ERR(async_vol_args);
vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2));
if (IS_ERR(vol_args_v2))
return PTR_ERR(vol_args_v2);
if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) {
ret = -EINVAL;
goto out;
}
name = vol_args_v2->name;
fd = vol_args_v2->fd;
vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
name = async_vol_args->name; if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC)
fd = async_vol_args->fd; ptr = &transid;
async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0';
ret = btrfs_ioctl_snap_create_transid(file, name, fd, ret = btrfs_ioctl_snap_create_transid(file, name, fd,
subvol, &transid); subvol, ptr);
if (ret == 0 && if (ret == 0 && ptr &&
copy_to_user(arg + copy_to_user(arg +
offsetof(struct btrfs_ioctl_async_vol_args, offsetof(struct btrfs_ioctl_vol_args_v2,
transid), &transid, sizeof(transid))) transid), ptr, sizeof(*ptr)))
ret = -EFAULT; ret = -EFAULT;
} else { } else {
vol_args = memdup_user(arg, sizeof(*vol_args)); vol_args = memdup_user(arg, sizeof(*vol_args));
...@@ -984,9 +994,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, ...@@ -984,9 +994,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
ret = btrfs_ioctl_snap_create_transid(file, name, fd, ret = btrfs_ioctl_snap_create_transid(file, name, fd,
subvol, NULL); subvol, NULL);
} }
out:
kfree(vol_args); kfree(vol_args);
kfree(async_vol_args); kfree(vol_args_v2);
return ret; return ret;
} }
...@@ -2248,7 +2258,7 @@ long btrfs_ioctl(struct file *file, unsigned int ...@@ -2248,7 +2258,7 @@ long btrfs_ioctl(struct file *file, unsigned int
return btrfs_ioctl_getversion(file, argp); return btrfs_ioctl_getversion(file, argp);
case BTRFS_IOC_SNAP_CREATE: case BTRFS_IOC_SNAP_CREATE:
return btrfs_ioctl_snap_create(file, argp, 0, 0); return btrfs_ioctl_snap_create(file, argp, 0, 0);
case BTRFS_IOC_SNAP_CREATE_ASYNC: case BTRFS_IOC_SNAP_CREATE_V2:
return btrfs_ioctl_snap_create(file, argp, 0, 1); return btrfs_ioctl_snap_create(file, argp, 0, 1);
case BTRFS_IOC_SUBVOL_CREATE: case BTRFS_IOC_SUBVOL_CREATE:
return btrfs_ioctl_snap_create(file, argp, 1, 0); return btrfs_ioctl_snap_create(file, argp, 1, 0);
......
...@@ -30,11 +30,15 @@ struct btrfs_ioctl_vol_args { ...@@ -30,11 +30,15 @@ struct btrfs_ioctl_vol_args {
char name[BTRFS_PATH_NAME_MAX + 1]; char name[BTRFS_PATH_NAME_MAX + 1];
}; };
#define BTRFS_SNAPSHOT_NAME_MAX 4079 #define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0)
struct btrfs_ioctl_async_vol_args {
#define BTRFS_SUBVOL_NAME_MAX 4039
struct btrfs_ioctl_vol_args_v2 {
__s64 fd; __s64 fd;
__u64 transid; __u64 transid;
char name[BTRFS_SNAPSHOT_NAME_MAX + 1]; __u64 flags;
__u64 unused[4];
char name[BTRFS_SUBVOL_NAME_MAX + 1];
}; };
#define BTRFS_INO_LOOKUP_PATH_MAX 4080 #define BTRFS_INO_LOOKUP_PATH_MAX 4080
...@@ -187,6 +191,6 @@ struct btrfs_ioctl_space_args { ...@@ -187,6 +191,6 @@ struct btrfs_ioctl_space_args {
struct btrfs_ioctl_space_args) struct btrfs_ioctl_space_args)
#define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64) #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64)
#define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
#define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \ #define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \
struct btrfs_ioctl_async_vol_args) struct btrfs_ioctl_vol_args_v2)
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment