aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorLi Zefan <lizf@cn.fujitsu.com>2010-12-10 01:41:56 -0500
committerChris Mason <chris.mason@oracle.com>2010-12-10 16:29:11 -0500
commitfdfb1e4f6c61477a61890b64974d65cdc3a98702 (patch)
tree2bb65569dfbcfe12e4d54449d018abeebf88e89d /fs/btrfs
parent914ee295af418e936ec20a08c1663eaabe4cd07a (diff)
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: Li Zefan <lizf@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ioctl.c44
-rw-r--r--fs/btrfs/ioctl.h14
2 files changed, 36 insertions, 22 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 7cc2e8e075b4..f87552a1d7ea 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -947,31 +947,41 @@ out:
947 947
948static noinline int btrfs_ioctl_snap_create(struct file *file, 948static noinline int btrfs_ioctl_snap_create(struct file *file,
949 void __user *arg, int subvol, 949 void __user *arg, int subvol,
950 int async) 950 int v2)
951{ 951{
952 struct btrfs_ioctl_vol_args *vol_args = NULL; 952 struct btrfs_ioctl_vol_args *vol_args = NULL;
953 struct btrfs_ioctl_async_vol_args *async_vol_args = NULL; 953 struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL;
954 char *name; 954 char *name;
955 u64 fd; 955 u64 fd;
956 u64 transid = 0;
957 int ret; 956 int ret;
958 957
959 if (async) { 958 if (v2) {
960 async_vol_args = memdup_user(arg, sizeof(*async_vol_args)); 959 u64 transid = 0;
961 if (IS_ERR(async_vol_args)) 960 u64 *ptr = NULL;
962 return PTR_ERR(async_vol_args);
963 961
964 name = async_vol_args->name; 962 vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2));
965 fd = async_vol_args->fd; 963 if (IS_ERR(vol_args_v2))
966 async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0'; 964 return PTR_ERR(vol_args_v2);
965
966 if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) {
967 ret = -EINVAL;
968 goto out;
969 }
970
971 name = vol_args_v2->name;
972 fd = vol_args_v2->fd;
973 vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
974
975 if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC)
976 ptr = &transid;
967 977
968 ret = btrfs_ioctl_snap_create_transid(file, name, fd, 978 ret = btrfs_ioctl_snap_create_transid(file, name, fd,
969 subvol, &transid); 979 subvol, ptr);
970 980
971 if (ret == 0 && 981 if (ret == 0 && ptr &&
972 copy_to_user(arg + 982 copy_to_user(arg +
973 offsetof(struct btrfs_ioctl_async_vol_args, 983 offsetof(struct btrfs_ioctl_vol_args_v2,
974 transid), &transid, sizeof(transid))) 984 transid), ptr, sizeof(*ptr)))
975 ret = -EFAULT; 985 ret = -EFAULT;
976 } else { 986 } else {
977 vol_args = memdup_user(arg, sizeof(*vol_args)); 987 vol_args = memdup_user(arg, sizeof(*vol_args));
@@ -984,9 +994,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
984 ret = btrfs_ioctl_snap_create_transid(file, name, fd, 994 ret = btrfs_ioctl_snap_create_transid(file, name, fd,
985 subvol, NULL); 995 subvol, NULL);
986 } 996 }
987 997out:
988 kfree(vol_args); 998 kfree(vol_args);
989 kfree(async_vol_args); 999 kfree(vol_args_v2);
990 1000
991 return ret; 1001 return ret;
992} 1002}
@@ -2248,7 +2258,7 @@ long btrfs_ioctl(struct file *file, unsigned int
2248 return btrfs_ioctl_getversion(file, argp); 2258 return btrfs_ioctl_getversion(file, argp);
2249 case BTRFS_IOC_SNAP_CREATE: 2259 case BTRFS_IOC_SNAP_CREATE:
2250 return btrfs_ioctl_snap_create(file, argp, 0, 0); 2260 return btrfs_ioctl_snap_create(file, argp, 0, 0);
2251 case BTRFS_IOC_SNAP_CREATE_ASYNC: 2261 case BTRFS_IOC_SNAP_CREATE_V2:
2252 return btrfs_ioctl_snap_create(file, argp, 0, 1); 2262 return btrfs_ioctl_snap_create(file, argp, 0, 1);
2253 case BTRFS_IOC_SUBVOL_CREATE: 2263 case BTRFS_IOC_SUBVOL_CREATE:
2254 return btrfs_ioctl_snap_create(file, argp, 1, 0); 2264 return btrfs_ioctl_snap_create(file, argp, 1, 0);
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index 17c99ebdf960..c344d12c646b 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -30,11 +30,15 @@ struct btrfs_ioctl_vol_args {
30 char name[BTRFS_PATH_NAME_MAX + 1]; 30 char name[BTRFS_PATH_NAME_MAX + 1];
31}; 31};
32 32
33#define BTRFS_SNAPSHOT_NAME_MAX 4079 33#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0)
34struct btrfs_ioctl_async_vol_args { 34
35#define BTRFS_SUBVOL_NAME_MAX 4039
36struct btrfs_ioctl_vol_args_v2 {
35 __s64 fd; 37 __s64 fd;
36 __u64 transid; 38 __u64 transid;
37 char name[BTRFS_SNAPSHOT_NAME_MAX + 1]; 39 __u64 flags;
40 __u64 unused[4];
41 char name[BTRFS_SUBVOL_NAME_MAX + 1];
38}; 42};
39 43
40#define BTRFS_INO_LOOKUP_PATH_MAX 4080 44#define BTRFS_INO_LOOKUP_PATH_MAX 4080
@@ -187,6 +191,6 @@ struct btrfs_ioctl_space_args {
187 struct btrfs_ioctl_space_args) 191 struct btrfs_ioctl_space_args)
188#define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64) 192#define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64)
189#define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) 193#define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
190#define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \ 194#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \
191 struct btrfs_ioctl_async_vol_args) 195 struct btrfs_ioctl_vol_args_v2)
192#endif 196#endif