vfs: swap names of {do,vfs}_clone_file_range()
authorAmir Goldstein <amir73il@gmail.com>
Tue, 18 Sep 2018 13:34:34 +0000 (16:34 +0300)
committerMiklos Szeredi <mszeredi@redhat.com>
Mon, 24 Sep 2018 08:54:01 +0000 (10:54 +0200)
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>
fs/ioctl.c
fs/nfsd/vfs.c
fs/overlayfs/copy_up.c
fs/overlayfs/file.c
fs/read_write.c
include/linux/fs.h

index 3212c29235ce34d21dedc26ea569978d45462706..2005529af560891043170b4d86ed05c2a62f19eb 100644 (file)
@@ -230,7 +230,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;
index 55a099e47ba2773e94e126285efc937391dee5d4..b53e76391e52539d11daee791bc47cc07b2ae773 100644 (file)
@@ -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,
index 296037afecdb4e689d458b54ffc597ed2265bbf9..1cc797a08a5b5f7eb6c002862c834177e5d6f93c 100644 (file)
@@ -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 */
-       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 */
index 5d1b4b38f7432b6b91e3212fbad5fee87cad76cd..986313da0c8895352d2216f0fb0b78d3854064fb 100644 (file)
@@ -461,7 +461,7 @@ static ssize_t ovl_copyfile(struct file *file_in, loff_t pos_in,
                break;
 
        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);
                break;
 
index 39b4a21dd9337a157927c1f8d0d741190de11e78..8a2737f0d61d3e0fbef04107da4a11283653544b 100644 (file)
@@ -1818,8 +1818,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);
@@ -1866,6 +1866,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);
 
 /*
index 6c0b4a1c22ff5bd84c5c4e29ce07b0366b7bc5b1..897eae8faee1b04f12fe8cbebbaae2b4505a771d 100644 (file)
@@ -1828,8 +1828,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);
@@ -2773,19 +2775,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.