vfs: pass remap flags to generic_remap_file_range_prep

Plumb the remap flags through the filesystem from the vfs function
dispatcher all the way to the prep function to prepare for behavior
changes in subsequent patches.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
Darrick J. Wong 2018-10-30 10:41:28 +11:00 committed by Dave Chinner
parent 2e5dfc99f2
commit a91ae49bba
8 changed files with 26 additions and 24 deletions

View file

@ -2538,7 +2538,7 @@ static int ocfs2_remap_file_range(struct file *file_in,
return -EINVAL; return -EINVAL;
return ocfs2_reflink_remap_range(file_in, pos_in, file_out, pos_out, return ocfs2_reflink_remap_range(file_in, pos_in, file_out, pos_out,
len, remap_flags & REMAP_FILE_DEDUP); len, remap_flags);
} }
const struct inode_operations ocfs2_file_iops = { const struct inode_operations ocfs2_file_iops = {

View file

@ -4825,7 +4825,7 @@ int ocfs2_reflink_remap_range(struct file *file_in,
struct file *file_out, struct file *file_out,
loff_t pos_out, loff_t pos_out,
u64 len, u64 len,
bool is_dedupe) 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);
@ -4851,7 +4851,7 @@ int ocfs2_reflink_remap_range(struct file *file_in,
goto out_unlock; goto out_unlock;
ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out, ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out,
&len, is_dedupe); &len, remap_flags);
if (ret <= 0) if (ret <= 0)
goto out_unlock; goto out_unlock;

View file

@ -120,6 +120,6 @@ int ocfs2_reflink_remap_range(struct file *file_in,
struct file *file_out, struct file *file_out,
loff_t pos_out, loff_t pos_out,
u64 len, u64 len,
bool is_dedupe); unsigned int remap_flags);
#endif /* OCFS2_REFCOUNTTREE_H */ #endif /* OCFS2_REFCOUNTTREE_H */

View file

@ -1722,14 +1722,14 @@ static int generic_remap_check_len(struct inode *inode_in,
struct inode *inode_out, struct inode *inode_out,
loff_t pos_out, loff_t pos_out,
u64 *len, u64 *len,
bool is_dedupe) unsigned int remap_flags)
{ {
u64 blkmask = i_blocksize(inode_in) - 1; u64 blkmask = i_blocksize(inode_in) - 1;
if ((*len & blkmask) == 0) if ((*len & blkmask) == 0)
return 0; return 0;
if (is_dedupe) if (remap_flags & REMAP_FILE_DEDUP)
*len &= ~blkmask; *len &= ~blkmask;
else if (pos_out + *len < i_size_read(inode_out)) else if (pos_out + *len < i_size_read(inode_out))
return -EINVAL; return -EINVAL;
@ -1747,7 +1747,7 @@ static int generic_remap_check_len(struct inode *inode_in,
*/ */
int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, struct file *file_out, loff_t pos_out,
u64 *len, bool is_dedupe) u64 *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);
@ -1771,7 +1771,7 @@ int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
if (*len == 0) { if (*len == 0) {
loff_t isize = i_size_read(inode_in); loff_t isize = i_size_read(inode_in);
if (is_dedupe || pos_in == isize) if ((remap_flags & REMAP_FILE_DEDUP) || pos_in == isize)
return 0; return 0;
if (pos_in > isize) if (pos_in > isize)
return -EINVAL; return -EINVAL;
@ -1782,7 +1782,7 @@ int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
/* Check that we don't violate system file offset limits. */ /* Check that we don't violate system file offset limits. */
ret = generic_remap_checks(file_in, pos_in, file_out, pos_out, len, ret = generic_remap_checks(file_in, pos_in, file_out, pos_out, len,
is_dedupe); (remap_flags & REMAP_FILE_DEDUP));
if (ret) if (ret)
return ret; return ret;
@ -1804,7 +1804,7 @@ int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
/* /*
* Check that the extents are the same. * Check that the extents are the same.
*/ */
if (is_dedupe) { if (remap_flags & REMAP_FILE_DEDUP) {
bool is_same = false; bool is_same = false;
ret = vfs_dedupe_file_range_compare(inode_in, pos_in, ret = vfs_dedupe_file_range_compare(inode_in, pos_in,
@ -1816,7 +1816,7 @@ int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
} }
ret = generic_remap_check_len(inode_in, inode_out, pos_out, len, ret = generic_remap_check_len(inode_in, inode_out, pos_out, len,
is_dedupe); remap_flags);
if (ret) if (ret)
return ret; return ret;

View file

@ -932,7 +932,7 @@ xfs_file_remap_range(
return -EINVAL; return -EINVAL;
return xfs_reflink_remap_range(file_in, pos_in, file_out, pos_out, return xfs_reflink_remap_range(file_in, pos_in, file_out, pos_out,
len, remap_flags & REMAP_FILE_DEDUP); len, remap_flags);
} }
STATIC int STATIC int

View file

@ -921,13 +921,14 @@ xfs_reflink_update_dest(
struct xfs_inode *dest, struct xfs_inode *dest,
xfs_off_t newlen, xfs_off_t newlen,
xfs_extlen_t cowextsize, xfs_extlen_t cowextsize,
bool is_dedupe) unsigned int remap_flags)
{ {
struct xfs_mount *mp = dest->i_mount; struct xfs_mount *mp = dest->i_mount;
struct xfs_trans *tp; struct xfs_trans *tp;
int error; int error;
if (is_dedupe && newlen <= i_size_read(VFS_I(dest)) && cowextsize == 0) if ((remap_flags & REMAP_FILE_DEDUP) &&
newlen <= i_size_read(VFS_I(dest)) && cowextsize == 0)
return 0; return 0;
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
@ -948,7 +949,7 @@ xfs_reflink_update_dest(
dest->i_d.di_flags2 |= XFS_DIFLAG2_COWEXTSIZE; dest->i_d.di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
} }
if (!is_dedupe) { if (!(remap_flags & REMAP_FILE_DEDUP)) {
xfs_trans_ichgtime(tp, dest, xfs_trans_ichgtime(tp, dest,
XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
} }
@ -1296,7 +1297,7 @@ xfs_reflink_remap_prep(
struct file *file_out, struct file *file_out,
loff_t pos_out, loff_t pos_out,
u64 *len, u64 *len,
bool is_dedupe) unsigned int remap_flags)
{ {
struct inode *inode_in = file_inode(file_in); struct inode *inode_in = file_inode(file_in);
struct xfs_inode *src = XFS_I(inode_in); struct xfs_inode *src = XFS_I(inode_in);
@ -1327,7 +1328,7 @@ xfs_reflink_remap_prep(
goto out_unlock; goto out_unlock;
ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out, ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out,
len, is_dedupe); len, remap_flags);
if (ret <= 0) if (ret <= 0)
goto out_unlock; goto out_unlock;
@ -1336,7 +1337,7 @@ xfs_reflink_remap_prep(
* from the source file so we don't try to dedupe the partial * from the source file so we don't try to dedupe the partial
* EOF block. * EOF block.
*/ */
if (is_dedupe) { if (remap_flags & REMAP_FILE_DEDUP) {
*len &= ~blkmask; *len &= ~blkmask;
} else if (*len & blkmask) { } else if (*len & blkmask) {
/* /*
@ -1372,7 +1373,7 @@ xfs_reflink_remap_prep(
PAGE_ALIGN(pos_out + *len) - 1); PAGE_ALIGN(pos_out + *len) - 1);
/* If we're altering the file contents... */ /* If we're altering the file contents... */
if (!is_dedupe) { if (!(remap_flags & REMAP_FILE_DEDUP)) {
/* /*
* ...update the timestamps (which will grab the ilock again * ...update the timestamps (which will grab the ilock again
* from xfs_fs_dirty_inode, so we have to call it before we * from xfs_fs_dirty_inode, so we have to call it before we
@ -1410,7 +1411,7 @@ xfs_reflink_remap_range(
struct file *file_out, struct file *file_out,
loff_t pos_out, loff_t pos_out,
u64 len, u64 len,
bool is_dedupe) unsigned int remap_flags)
{ {
struct inode *inode_in = file_inode(file_in); struct inode *inode_in = file_inode(file_in);
struct xfs_inode *src = XFS_I(inode_in); struct xfs_inode *src = XFS_I(inode_in);
@ -1430,7 +1431,7 @@ xfs_reflink_remap_range(
/* Prepare and then clone file data. */ /* Prepare and then clone file data. */
ret = xfs_reflink_remap_prep(file_in, pos_in, file_out, pos_out, ret = xfs_reflink_remap_prep(file_in, pos_in, file_out, pos_out,
&len, is_dedupe); &len, remap_flags);
if (ret <= 0) if (ret <= 0)
return ret; return ret;
@ -1457,7 +1458,7 @@ xfs_reflink_remap_range(
cowextsize = src->i_d.di_cowextsize; cowextsize = src->i_d.di_cowextsize;
ret = xfs_reflink_update_dest(dest, pos_out + len, cowextsize, ret = xfs_reflink_update_dest(dest, pos_out + len, cowextsize,
is_dedupe); remap_flags);
out_unlock: out_unlock:
xfs_reflink_remap_unlock(file_in, file_out); xfs_reflink_remap_unlock(file_in, file_out);

View file

@ -28,7 +28,8 @@ extern int xfs_reflink_end_cow(struct xfs_inode *ip, xfs_off_t offset,
xfs_off_t count); xfs_off_t count);
extern int xfs_reflink_recover_cow(struct xfs_mount *mp); extern int xfs_reflink_recover_cow(struct xfs_mount *mp);
extern int xfs_reflink_remap_range(struct file *file_in, loff_t pos_in, extern int xfs_reflink_remap_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, u64 len, bool is_dedupe); struct file *file_out, loff_t pos_out, u64 len,
unsigned int remap_flags);
extern int xfs_reflink_inode_has_shared_extents(struct xfs_trans *tp, extern int xfs_reflink_inode_has_shared_extents(struct xfs_trans *tp,
struct xfs_inode *ip, bool *has_shared); struct xfs_inode *ip, bool *has_shared);
extern int xfs_reflink_clear_inode_flag(struct xfs_inode *ip, extern int xfs_reflink_clear_inode_flag(struct xfs_inode *ip,

View file

@ -1844,7 +1844,7 @@ extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *,
loff_t, size_t, unsigned int); loff_t, size_t, unsigned int);
extern int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, extern int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, struct file *file_out, loff_t pos_out,
u64 *count, bool is_dedupe); u64 *count, unsigned int remap_flags);
extern int do_clone_file_range(struct file *file_in, loff_t pos_in, extern int do_clone_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, u64 len); struct file *file_out, loff_t pos_out, u64 len);
extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in,