Commit a725356b authored by Amir Goldstein's avatar Amir Goldstein Committed by Miklos Szeredi

vfs: swap names of {do,vfs}_clone_file_range()

Commit 031a072a ("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 8ede2055 ("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: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent d9d150ae
...@@ -230,7 +230,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd, ...@@ -230,7 +230,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
ret = -EXDEV; ret = -EXDEV;
if (src_file.file->f_path.mnt != dst_file->f_path.mnt) if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
goto fdput; 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:
fdput(src_file); fdput(src_file);
return ret; return ret;
......
...@@ -541,7 +541,8 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -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, __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
u64 dst_pos, u64 count) 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, ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst,
......
...@@ -141,7 +141,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len) ...@@ -141,7 +141,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 */ /* 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) if (!error)
goto out; goto out;
/* Couldn't clone, so now we try to copy the data */ /* Couldn't clone, so now we try to copy the data */
......
...@@ -461,7 +461,7 @@ static ssize_t ovl_copyfile(struct file *file_in, loff_t pos_in, ...@@ -461,7 +461,7 @@ static ssize_t ovl_copyfile(struct file *file_in, loff_t pos_in,
break; break;
case OVL_CLONE: case OVL_CLONE:
ret = do_clone_file_range(real_in.file, pos_in, ret = vfs_clone_file_range(real_in.file, pos_in,
real_out.file, pos_out, len); real_out.file, pos_out, len);
break; break;
......
...@@ -1818,7 +1818,7 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, ...@@ -1818,7 +1818,7 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in,
} }
EXPORT_SYMBOL(vfs_clone_file_prep_inodes); EXPORT_SYMBOL(vfs_clone_file_prep_inodes);
int vfs_clone_file_range(struct file *file_in, loff_t pos_in, int do_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)
{ {
struct inode *inode_in = file_inode(file_in); struct inode *inode_in = file_inode(file_in);
...@@ -1866,6 +1866,19 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in, ...@@ -1866,6 +1866,19 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
return ret; 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); EXPORT_SYMBOL(vfs_clone_file_range);
/* /*
......
...@@ -1828,6 +1828,8 @@ extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, ...@@ -1828,6 +1828,8 @@ 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, extern int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in,
struct inode *inode_out, loff_t pos_out, struct inode *inode_out, loff_t pos_out,
u64 *len, bool is_dedupe); 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, 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, extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
...@@ -2773,19 +2775,6 @@ static inline void file_end_write(struct file *file) ...@@ -2773,19 +2775,6 @@ static inline void file_end_write(struct file *file)
__sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE); __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. * get_write_access() gets write permission for a file.
* put_write_access() releases this write permission. * put_write_access() releases this write permission.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment