summaryrefslogtreecommitdiffstats
path: root/fs/ioctl.c
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2015-12-19 09:55:59 +0100
committerAl Viro <viro@zeniv.linux.org.uk>2016-01-01 08:36:19 +0100
commit54dbc15172375641ef03399e8f911d7165eb90fb (patch)
treeb85a2df3b98719f4cf6493d69409588886276833 /fs/ioctl.c
parentvfs: wire up compat ioctl for CLONE/CLONE_RANGE (diff)
downloadlinux-54dbc15172375641ef03399e8f911d7165eb90fb.tar.xz
linux-54dbc15172375641ef03399e8f911d7165eb90fb.zip
vfs: hoist the btrfs deduplication ioctl to the vfs
Hoist the btrfs EXTENT_SAME ioctl up to the VFS and make the name more systematic (FIDEDUPERANGE). Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ioctl.c')
-rw-r--r--fs/ioctl.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 84c6e79829ab..fcdd33b7ec78 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -568,6 +568,41 @@ static int ioctl_fsthaw(struct file *filp)
return thaw_super(sb);
}
+static long ioctl_file_dedupe_range(struct file *file, void __user *arg)
+{
+ struct file_dedupe_range __user *argp = arg;
+ struct file_dedupe_range *same = NULL;
+ int ret;
+ unsigned long size;
+ u16 count;
+
+ if (get_user(count, &argp->dest_count)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ size = offsetof(struct file_dedupe_range __user, info[count]);
+
+ same = memdup_user(argp, size);
+ if (IS_ERR(same)) {
+ ret = PTR_ERR(same);
+ same = NULL;
+ goto out;
+ }
+
+ ret = vfs_dedupe_file_range(file, same);
+ if (ret)
+ goto out;
+
+ ret = copy_to_user(argp, same, size);
+ if (ret)
+ ret = -EFAULT;
+
+out:
+ kfree(same);
+ return ret;
+}
+
/*
* When you add any new common ioctls to the switches above and below
* please update compat_sys_ioctl() too.
@@ -629,6 +664,9 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
case FICLONERANGE:
return ioctl_file_clone_range(filp, argp);
+ case FIDEDUPERANGE:
+ return ioctl_file_dedupe_range(filp, argp);
+
default:
if (S_ISREG(inode->i_mode))
error = file_ioctl(filp, cmd, arg);