From mboxrd@z Thu Jan 1 00:00:00 1970 From: Amir Goldstein Subject: [PATCH v2 1/4] vfs: allow vfs_clone_file_range() across mount points Date: Mon, 12 Sep 2016 18:06:40 +0300 Message-ID: <1473692803-11964-2-git-send-email-amir73il@gmail.com> References: <1473348594-31425-1-git-send-email-amir73il@gmail.com> <1473692803-11964-1-git-send-email-amir73il@gmail.com> Return-path: Received: from mail-wm0-f66.google.com ([74.125.82.66]:35251 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759817AbcILPHY (ORCPT ); Mon, 12 Sep 2016 11:07:24 -0400 In-Reply-To: <1473692803-11964-1-git-send-email-amir73il@gmail.com> Sender: linux-unionfs-owner@vger.kernel.org List-Id: linux-unionfs@vger.kernel.org To: Miklos Szeredi , Dave Chinner , linux-unionfs@vger.kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org, "Darrick J . Wong" , linux-fsdevel@vger.kernel.org FICLONE/FICLONERANGE ioctls return -EXDEV if src and dest files are not on the same mount point. Practically, clone only requires that src and dest files are on the same file system. Move the check for same mount point to ioctl code and keep only the check for same super block in the vfs helper. A following patch is going to use the vfs_clone_file_range() helper in overlayfs to copy up between lower and upper mount points on the same file system. Signed-off-by: Amir Goldstein --- fs/ioctl.c | 2 ++ fs/read_write.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/ioctl.c b/fs/ioctl.c index c415668..34d2994 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -223,6 +223,8 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd, if (!src_file.file) return -EBADF; + if (src_file.file->f_path.mnt != dst_file->f_path.mnt) + return -EXDEV; ret = vfs_clone_file_range(src_file.file, off, dst_file, destoff, olen); fdput(src_file); return ret; diff --git a/fs/read_write.c b/fs/read_write.c index 66215a7..9dc6e52 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1628,8 +1628,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 point. 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)) -- 2.7.4