vfs: plumb remap flags through the vfs clone functions
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 29 Oct 2018 23:41:56 +0000 (10:41 +1100)
committerDave Chinner <david@fromorbit.com>
Mon, 29 Oct 2018 23:41:56 +0000 (10:41 +1100)
Plumb a remap_flags argument through the {do,vfs}_clone_file_range
functions so that clone can take advantage of it.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Dave Chinner <david@fromorbit.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 72537b68c272db2af0797d97a2ad3c60fd3ef692..505275ec55969b39964f08c41a468c9175fcf7fb 100644 (file)
@@ -232,7 +232,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
        if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
                goto fdput;
        cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff,
-                                     olen);
+                                     olen, 0);
        if (cloned < 0)
                ret = cloned;
        else if (olen && cloned != olen)
index ac6cb6101cbeceaa37fc52540c5e1e4ff9602033..726fc5b2b27a5e7914c05ae169b12cf7adc55bb5 100644 (file)
@@ -543,7 +543,7 @@ __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
 {
        loff_t cloned;
 
-       cloned = vfs_clone_file_range(src, src_pos, dst, dst_pos, count);
+       cloned = vfs_clone_file_range(src, src_pos, dst, dst_pos, count, 0);
        if (count && cloned != count)
                cloned = -EINVAL;
        return nfserrno(cloned < 0 ? cloned : 0);
index 8750b72355169366466e29e25767bcca94b8e441..5f82fece64a06201deb0bb8eab2c6b51dc5c309d 100644 (file)
@@ -142,7 +142,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 */
-       cloned = do_clone_file_range(old_file, 0, new_file, 0, len);
+       cloned = do_clone_file_range(old_file, 0, new_file, 0, len, 0);
        if (cloned == len)
                goto out;
        /* Couldn't clone, so now we try to copy the data */
index 6c3fec6168e9a0d8330031f63b3fc86f0b2b1294..0393815c897175e3fd5a6b14e7b8e72356449f3f 100644 (file)
@@ -462,7 +462,7 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
 
        case OVL_CLONE:
                ret = vfs_clone_file_range(real_in.file, pos_in,
-                                          real_out.file, pos_out, len);
+                                          real_out.file, pos_out, len, flags);
                break;
 
        case OVL_DEDUPE:
@@ -512,8 +512,8 @@ static loff_t ovl_remap_file_range(struct file *file_in, loff_t pos_in,
             !ovl_inode_upper(file_inode(file_out))))
                return -EPERM;
 
-       return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, 0,
-                           op);
+       return ovl_copyfile(file_in, pos_in, file_out, pos_out, len,
+                           remap_flags, op);
 }
 
 const struct file_operations ovl_file_operations = {
index 356641afa4874b4701c5afffb0ea4a61264b51b6..0d1ac1b9bc2230ad3f054d56479b0585c9ba646a 100644 (file)
@@ -1848,12 +1848,15 @@ int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
 EXPORT_SYMBOL(generic_remap_file_range_prep);
 
 loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
-                          struct file *file_out, loff_t pos_out, loff_t len)
+                          struct file *file_out, loff_t pos_out,
+                          loff_t len, unsigned int remap_flags)
 {
        struct inode *inode_in = file_inode(file_in);
        struct inode *inode_out = file_inode(file_out);
        loff_t ret;
 
+       WARN_ON_ONCE(remap_flags);
+
        if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode))
                return -EISDIR;
        if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode))
@@ -1884,7 +1887,7 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
                return ret;
 
        ret = file_in->f_op->remap_file_range(file_in, pos_in,
-                       file_out, pos_out, len, 0);
+                       file_out, pos_out, len, remap_flags);
        if (ret < 0)
                return ret;
 
@@ -1895,12 +1898,14 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
 EXPORT_SYMBOL(do_clone_file_range);
 
 loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in,
-                           struct file *file_out, loff_t pos_out, loff_t len)
+                           struct file *file_out, loff_t pos_out,
+                           loff_t len, unsigned int remap_flags)
 {
        loff_t ret;
 
        file_start_write(file_out);
-       ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len);
+       ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len,
+                                 remap_flags);
        file_end_write(file_out);
 
        return ret;
index c72d8c3c065a807645bc06ffc706c961ac88a1f1..1c5e55d2a67d30094962a31cf3d0eea4e259c799 100644 (file)
@@ -1848,10 +1848,10 @@ extern int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
                                         unsigned int remap_flags);
 extern loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
                                  struct file *file_out, loff_t pos_out,
-                                 loff_t len);
+                                 loff_t len, unsigned int remap_flags);
 extern loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in,
                                   struct file *file_out, loff_t pos_out,
-                                  loff_t len);
+                                  loff_t len, unsigned int remap_flags);
 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);