aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-10-29 19:41:56 -0400
committerDave Chinner <david@fromorbit.com>2018-10-29 19:41:56 -0400
commit452ce65951a2f0719e4e119ecca134c06cfe22ee (patch)
tree5b004e6b2ca558d80623963388a9c51acae04e5a
parent42ec3d4c02187a18e27ff94b409ec27234bf2ffd (diff)
vfs: plumb remap flags through the vfs clone functions
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>
-rw-r--r--fs/ioctl.c2
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/overlayfs/copy_up.c2
-rw-r--r--fs/overlayfs/file.c6
-rw-r--r--fs/read_write.c13
-rw-r--r--include/linux/fs.h4
6 files changed, 17 insertions, 12 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 72537b68c272..505275ec5596 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -232,7 +232,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
232 if (src_file.file->f_path.mnt != dst_file->f_path.mnt) 232 if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
233 goto fdput; 233 goto fdput;
234 cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff, 234 cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff,
235 olen); 235 olen, 0);
236 if (cloned < 0) 236 if (cloned < 0)
237 ret = cloned; 237 ret = cloned;
238 else if (olen && cloned != olen) 238 else if (olen && cloned != olen)
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index ac6cb6101cbe..726fc5b2b27a 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -543,7 +543,7 @@ __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
543{ 543{
544 loff_t cloned; 544 loff_t cloned;
545 545
546 cloned = vfs_clone_file_range(src, src_pos, dst, dst_pos, count); 546 cloned = vfs_clone_file_range(src, src_pos, dst, dst_pos, count, 0);
547 if (count && cloned != count) 547 if (count && cloned != count)
548 cloned = -EINVAL; 548 cloned = -EINVAL;
549 return nfserrno(cloned < 0 ? cloned : 0); 549 return nfserrno(cloned < 0 ? cloned : 0);
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index 8750b7235516..5f82fece64a0 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -142,7 +142,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
142 } 142 }
143 143
144 /* Try to use clone_file_range to clone up within the same fs */ 144 /* Try to use clone_file_range to clone up within the same fs */
145 cloned = do_clone_file_range(old_file, 0, new_file, 0, len); 145 cloned = do_clone_file_range(old_file, 0, new_file, 0, len, 0);
146 if (cloned == len) 146 if (cloned == len)
147 goto out; 147 goto out;
148 /* Couldn't clone, so now we try to copy the data */ 148 /* Couldn't clone, so now we try to copy the data */
diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
index 6c3fec6168e9..0393815c8971 100644
--- a/fs/overlayfs/file.c
+++ b/fs/overlayfs/file.c
@@ -462,7 +462,7 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
462 462
463 case OVL_CLONE: 463 case OVL_CLONE:
464 ret = vfs_clone_file_range(real_in.file, pos_in, 464 ret = vfs_clone_file_range(real_in.file, pos_in,
465 real_out.file, pos_out, len); 465 real_out.file, pos_out, len, flags);
466 break; 466 break;
467 467
468 case OVL_DEDUPE: 468 case OVL_DEDUPE:
@@ -512,8 +512,8 @@ static loff_t ovl_remap_file_range(struct file *file_in, loff_t pos_in,
512 !ovl_inode_upper(file_inode(file_out)))) 512 !ovl_inode_upper(file_inode(file_out))))
513 return -EPERM; 513 return -EPERM;
514 514
515 return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, 0, 515 return ovl_copyfile(file_in, pos_in, file_out, pos_out, len,
516 op); 516 remap_flags, op);
517} 517}
518 518
519const struct file_operations ovl_file_operations = { 519const struct file_operations ovl_file_operations = {
diff --git a/fs/read_write.c b/fs/read_write.c
index 356641afa487..0d1ac1b9bc22 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -1848,12 +1848,15 @@ int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
1848EXPORT_SYMBOL(generic_remap_file_range_prep); 1848EXPORT_SYMBOL(generic_remap_file_range_prep);
1849 1849
1850loff_t do_clone_file_range(struct file *file_in, loff_t pos_in, 1850loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
1851 struct file *file_out, loff_t pos_out, loff_t len) 1851 struct file *file_out, loff_t pos_out,
1852 loff_t len, unsigned int remap_flags)
1852{ 1853{
1853 struct inode *inode_in = file_inode(file_in); 1854 struct inode *inode_in = file_inode(file_in);
1854 struct inode *inode_out = file_inode(file_out); 1855 struct inode *inode_out = file_inode(file_out);
1855 loff_t ret; 1856 loff_t ret;
1856 1857
1858 WARN_ON_ONCE(remap_flags);
1859
1857 if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode)) 1860 if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode))
1858 return -EISDIR; 1861 return -EISDIR;
1859 if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode)) 1862 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,
1884 return ret; 1887 return ret;
1885 1888
1886 ret = file_in->f_op->remap_file_range(file_in, pos_in, 1889 ret = file_in->f_op->remap_file_range(file_in, pos_in,
1887 file_out, pos_out, len, 0); 1890 file_out, pos_out, len, remap_flags);
1888 if (ret < 0) 1891 if (ret < 0)
1889 return ret; 1892 return ret;
1890 1893
@@ -1895,12 +1898,14 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
1895EXPORT_SYMBOL(do_clone_file_range); 1898EXPORT_SYMBOL(do_clone_file_range);
1896 1899
1897loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in, 1900loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in,
1898 struct file *file_out, loff_t pos_out, loff_t len) 1901 struct file *file_out, loff_t pos_out,
1902 loff_t len, unsigned int remap_flags)
1899{ 1903{
1900 loff_t ret; 1904 loff_t ret;
1901 1905
1902 file_start_write(file_out); 1906 file_start_write(file_out);
1903 ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len); 1907 ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len,
1908 remap_flags);
1904 file_end_write(file_out); 1909 file_end_write(file_out);
1905 1910
1906 return ret; 1911 return ret;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index c72d8c3c065a..1c5e55d2a67d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1848,10 +1848,10 @@ extern int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
1848 unsigned int remap_flags); 1848 unsigned int remap_flags);
1849extern loff_t do_clone_file_range(struct file *file_in, loff_t pos_in, 1849extern loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
1850 struct file *file_out, loff_t pos_out, 1850 struct file *file_out, loff_t pos_out,
1851 loff_t len); 1851 loff_t len, unsigned int remap_flags);
1852extern loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in, 1852extern loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in,
1853 struct file *file_out, loff_t pos_out, 1853 struct file *file_out, loff_t pos_out,
1854 loff_t len); 1854 loff_t len, unsigned int remap_flags);
1855extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, 1855extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
1856 struct inode *dest, loff_t destoff, 1856 struct inode *dest, loff_t destoff,
1857 loff_t len, bool *is_same); 1857 loff_t len, bool *is_same);