Commit 452ce659 authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Dave Chinner

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: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent 42ec3d4c
...@@ -232,7 +232,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd, ...@@ -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) if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
goto fdput; goto fdput;
cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff, cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff,
olen); olen, 0);
if (cloned < 0) if (cloned < 0)
ret = cloned; ret = cloned;
else if (olen && cloned != olen) else if (olen && cloned != olen)
......
...@@ -543,7 +543,7 @@ __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst, ...@@ -543,7 +543,7 @@ __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
{ {
loff_t cloned; 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) if (count && cloned != count)
cloned = -EINVAL; cloned = -EINVAL;
return nfserrno(cloned < 0 ? cloned : 0); return nfserrno(cloned < 0 ? cloned : 0);
......
...@@ -142,7 +142,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len) ...@@ -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 */ /* 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) if (cloned == len)
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 */
......
...@@ -462,7 +462,7 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in, ...@@ -462,7 +462,7 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
case OVL_CLONE: case OVL_CLONE:
ret = vfs_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, flags);
break; break;
case OVL_DEDUPE: case OVL_DEDUPE:
...@@ -512,8 +512,8 @@ static loff_t ovl_remap_file_range(struct file *file_in, loff_t pos_in, ...@@ -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)))) !ovl_inode_upper(file_inode(file_out))))
return -EPERM; return -EPERM;
return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, 0, return ovl_copyfile(file_in, pos_in, file_out, pos_out, len,
op); remap_flags, op);
} }
const struct file_operations ovl_file_operations = { const struct file_operations ovl_file_operations = {
......
...@@ -1848,12 +1848,15 @@ int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, ...@@ -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); EXPORT_SYMBOL(generic_remap_file_range_prep);
loff_t do_clone_file_range(struct file *file_in, loff_t pos_in, 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_in = file_inode(file_in);
struct inode *inode_out = file_inode(file_out); struct inode *inode_out = file_inode(file_out);
loff_t ret; loff_t ret;
WARN_ON_ONCE(remap_flags);
if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode)) if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode))
return -EISDIR; return -EISDIR;
if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode)) 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,7 +1887,7 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
return ret; return ret;
ret = file_in->f_op->remap_file_range(file_in, pos_in, 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) if (ret < 0)
return ret; return ret;
...@@ -1895,12 +1898,14 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in, ...@@ -1895,12 +1898,14 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
EXPORT_SYMBOL(do_clone_file_range); EXPORT_SYMBOL(do_clone_file_range);
loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in, 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; loff_t ret;
file_start_write(file_out); 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); file_end_write(file_out);
return ret; return ret;
......
...@@ -1848,10 +1848,10 @@ extern int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, ...@@ -1848,10 +1848,10 @@ extern int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
unsigned int remap_flags); unsigned int remap_flags);
extern loff_t do_clone_file_range(struct file *file_in, loff_t pos_in, extern loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, 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, extern loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, 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, extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
struct inode *dest, loff_t destoff, struct inode *dest, loff_t destoff,
loff_t len, bool *is_same); loff_t len, bool *is_same);
......
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