summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/ioctl.c4
-rw-r--r--fs/read_write.c8
2 files changed, 10 insertions, 2 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c
index c415668c86d4..6715b7208835 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -223,7 +223,11 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
if (!src_file.file)
return -EBADF;
+ ret = -EXDEV;
+ if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
+ goto fdput;
ret = vfs_clone_file_range(src_file.file, off, dst_file, destoff, olen);
+fdput:
fdput(src_file);
return ret;
}
diff --git a/fs/read_write.c b/fs/read_write.c
index 3d810a11102c..175d30e3b603 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -1655,8 +1655,12 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
struct inode *inode_out = file_inode(file_out);
int ret;
- if (inode_in->i_sb != inode_out->i_sb ||
- file_in->f_path.mnt != file_out->f_path.mnt)
+ /*
+ * FICLONE/FICLONERANGE ioctls enforce that src and dest files are on
+ * the same mount. Practically, they only need to be on the same file
+ * system.
+ */
+ if (inode_in->i_sb != inode_out->i_sb)
return -EXDEV;
if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode))