| From 0f36e7f8595b2be370eb4278c976108f093d6c8b Mon Sep 17 00:00:00 2001 |
| From: Amir Goldstein <amir73il@gmail.com> |
| Date: Mon, 22 Oct 2018 20:56:46 +0300 |
| Subject: vfs: swap names of {do,vfs}_clone_file_range() |
| |
| commit a725356b6659469d182d662f22d770d83d3bc7b5 upstream. |
| |
| Commit 031a072a0b8a ("vfs: call vfs_clone_file_range() under freeze |
| protection") created a wrapper do_clone_file_range() around |
| vfs_clone_file_range() moving the freeze protection to former, so |
| overlayfs could call the latter. |
| |
| The more common vfs practice is to call do_xxx helpers from vfs_xxx |
| helpers, where freeze protecction is taken in the vfs_xxx helper, so |
| this anomality could be a source of confusion. |
| |
| It seems that commit 8ede205541ff ("ovl: add reflink/copyfile/dedup |
| support") may have fallen a victim to this confusion - |
| ovl_clone_file_range() calls the vfs_clone_file_range() helper in the |
| hope of getting freeze protection on upper fs, but in fact results in |
| overlayfs allowing to bypass upper fs freeze protection. |
| |
| Swap the names of the two helpers to conform to common vfs practice |
| and call the correct helpers from overlayfs and nfsd. |
| |
| Signed-off-by: Amir Goldstein <amir73il@gmail.com> |
| Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> |
| Fixes: 031a072a0b8a ("vfs: call vfs_clone_file_range() under freeze...") |
| Signed-off-by: Amir Goldstein <amir73il@gmail.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/ioctl.c | 2 +- |
| fs/nfsd/vfs.c | 3 ++- |
| fs/overlayfs/copy_up.c | 2 +- |
| fs/read_write.c | 17 +++++++++++++++-- |
| include/linux/fs.h | 17 +++-------------- |
| 5 files changed, 22 insertions(+), 19 deletions(-) |
| |
| diff --git a/fs/ioctl.c b/fs/ioctl.c |
| index 5ace7efb0d04..9db5ddaf7ef0 100644 |
| --- a/fs/ioctl.c |
| +++ b/fs/ioctl.c |
| @@ -229,7 +229,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd, |
| ret = -EXDEV; |
| if (src_file.file->f_path.mnt != dst_file->f_path.mnt) |
| goto fdput; |
| - ret = do_clone_file_range(src_file.file, off, dst_file, destoff, olen); |
| + ret = vfs_clone_file_range(src_file.file, off, dst_file, destoff, olen); |
| fdput: |
| fdput(src_file); |
| return ret; |
| diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c |
| index a3c9bfa77def..f55527ef21e8 100644 |
| --- a/fs/nfsd/vfs.c |
| +++ b/fs/nfsd/vfs.c |
| @@ -541,7 +541,8 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp, |
| __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst, |
| u64 dst_pos, u64 count) |
| { |
| - return nfserrno(do_clone_file_range(src, src_pos, dst, dst_pos, count)); |
| + return nfserrno(vfs_clone_file_range(src, src_pos, dst, dst_pos, |
| + count)); |
| } |
| |
| ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst, |
| diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c |
| index c441f9387a1b..321eae740148 100644 |
| --- a/fs/overlayfs/copy_up.c |
| +++ b/fs/overlayfs/copy_up.c |
| @@ -157,7 +157,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len) |
| } |
| |
| /* Try to use clone_file_range to clone up within the same fs */ |
| - error = vfs_clone_file_range(old_file, 0, new_file, 0, len); |
| + error = do_clone_file_range(old_file, 0, new_file, 0, len); |
| if (!error) |
| goto out; |
| /* Couldn't clone, so now we try to copy the data */ |
| diff --git a/fs/read_write.c b/fs/read_write.c |
| index 0046d72efe94..57a00ef895b2 100644 |
| --- a/fs/read_write.c |
| +++ b/fs/read_write.c |
| @@ -1812,8 +1812,8 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, |
| } |
| EXPORT_SYMBOL(vfs_clone_file_prep_inodes); |
| |
| -int vfs_clone_file_range(struct file *file_in, loff_t pos_in, |
| - struct file *file_out, loff_t pos_out, u64 len) |
| +int do_clone_file_range(struct file *file_in, loff_t pos_in, |
| + struct file *file_out, loff_t pos_out, u64 len) |
| { |
| struct inode *inode_in = file_inode(file_in); |
| struct inode *inode_out = file_inode(file_out); |
| @@ -1860,6 +1860,19 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in, |
| |
| return ret; |
| } |
| +EXPORT_SYMBOL(do_clone_file_range); |
| + |
| +int vfs_clone_file_range(struct file *file_in, loff_t pos_in, |
| + struct file *file_out, loff_t pos_out, u64 len) |
| +{ |
| + int ret; |
| + |
| + file_start_write(file_out); |
| + ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len); |
| + file_end_write(file_out); |
| + |
| + return ret; |
| +} |
| EXPORT_SYMBOL(vfs_clone_file_range); |
| |
| /* |
| diff --git a/include/linux/fs.h b/include/linux/fs.h |
| index cc613f20e5a6..7374639f0aa0 100644 |
| --- a/include/linux/fs.h |
| +++ b/include/linux/fs.h |
| @@ -1792,8 +1792,10 @@ extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, |
| extern int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, |
| struct inode *inode_out, loff_t pos_out, |
| u64 *len, bool is_dedupe); |
| +extern int do_clone_file_range(struct file *file_in, loff_t pos_in, |
| + struct file *file_out, loff_t pos_out, u64 len); |
| extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, |
| - struct file *file_out, loff_t pos_out, u64 len); |
| + struct file *file_out, loff_t pos_out, u64 len); |
| extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, |
| struct inode *dest, loff_t destoff, |
| loff_t len, bool *is_same); |
| @@ -2712,19 +2714,6 @@ static inline void file_end_write(struct file *file) |
| __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE); |
| } |
| |
| -static inline int do_clone_file_range(struct file *file_in, loff_t pos_in, |
| - struct file *file_out, loff_t pos_out, |
| - u64 len) |
| -{ |
| - int ret; |
| - |
| - file_start_write(file_out); |
| - ret = vfs_clone_file_range(file_in, pos_in, file_out, pos_out, len); |
| - file_end_write(file_out); |
| - |
| - return ret; |
| -} |
| - |
| /* |
| * get_write_access() gets write permission for a file. |
| * put_write_access() releases this write permission. |
| -- |
| 2.17.1 |
| |