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>
This commit is contained in:
parent
42ec3d4c02
commit
452ce65951
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue