diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2018-10-29 19:41:56 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2018-10-29 19:41:56 -0400 |
commit | 452ce65951a2f0719e4e119ecca134c06cfe22ee (patch) | |
tree | 5b004e6b2ca558d80623963388a9c51acae04e5a | |
parent | 42ec3d4c02187a18e27ff94b409ec27234bf2ffd (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.c | 2 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 2 | ||||
-rw-r--r-- | fs/overlayfs/copy_up.c | 2 | ||||
-rw-r--r-- | fs/overlayfs/file.c | 6 | ||||
-rw-r--r-- | fs/read_write.c | 13 | ||||
-rw-r--r-- | include/linux/fs.h | 4 |
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 | ||
519 | const struct file_operations ovl_file_operations = { | 519 | const 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, | |||
1848 | EXPORT_SYMBOL(generic_remap_file_range_prep); | 1848 | EXPORT_SYMBOL(generic_remap_file_range_prep); |
1849 | 1849 | ||
1850 | loff_t do_clone_file_range(struct file *file_in, loff_t pos_in, | 1850 | loff_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, | |||
1895 | EXPORT_SYMBOL(do_clone_file_range); | 1898 | EXPORT_SYMBOL(do_clone_file_range); |
1896 | 1899 | ||
1897 | loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in, | 1900 | loff_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); |
1849 | extern loff_t do_clone_file_range(struct file *file_in, loff_t pos_in, | 1849 | extern 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); |
1852 | extern loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in, | 1852 | extern 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); |
1855 | extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, | 1855 | extern 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); |