summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-10-29 19:41:28 -0400
committerDave Chinner <david@fromorbit.com>2018-10-29 19:41:28 -0400
commita91ae49bbaf43910edb09e03fedf26b23875bd52 (patch)
tree8152c5568a957e47b986e25324846e06a6d1fd57
parent2e5dfc99f2e61c42083ba742395e7a7b353513d1 (diff)
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>
-rw-r--r--fs/ocfs2/file.c2
-rw-r--r--fs/ocfs2/refcounttree.c4
-rw-r--r--fs/ocfs2/refcounttree.h2
-rw-r--r--fs/read_write.c14
-rw-r--r--fs/xfs/xfs_file.c2
-rw-r--r--fs/xfs/xfs_reflink.c21
-rw-r--r--fs/xfs/xfs_reflink.h3
-rw-r--r--include/linux/fs.h2
8 files changed, 26 insertions, 24 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 0b757a24567c..9809b0e5746f 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2538,7 +2538,7 @@ static int ocfs2_remap_file_range(struct file *file_in,
2538 return -EINVAL; 2538 return -EINVAL;
2539 2539
2540 return ocfs2_reflink_remap_range(file_in, pos_in, file_out, pos_out, 2540 return ocfs2_reflink_remap_range(file_in, pos_in, file_out, pos_out,
2541 len, remap_flags & REMAP_FILE_DEDUP); 2541 len, remap_flags);
2542} 2542}
2543 2543
2544const struct inode_operations ocfs2_file_iops = { 2544const struct inode_operations ocfs2_file_iops = {
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 36c56dfbe485..df9781567ec0 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -4825,7 +4825,7 @@ int ocfs2_reflink_remap_range(struct file *file_in,
4825 struct file *file_out, 4825 struct file *file_out,
4826 loff_t pos_out, 4826 loff_t pos_out,
4827 u64 len, 4827 u64 len,
4828 bool is_dedupe) 4828 unsigned int remap_flags)
4829{ 4829{
4830 struct inode *inode_in = file_inode(file_in); 4830 struct inode *inode_in = file_inode(file_in);
4831 struct inode *inode_out = file_inode(file_out); 4831 struct inode *inode_out = file_inode(file_out);
@@ -4851,7 +4851,7 @@ int ocfs2_reflink_remap_range(struct file *file_in,
4851 goto out_unlock; 4851 goto out_unlock;
4852 4852
4853 ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out, 4853 ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out,
4854 &len, is_dedupe); 4854 &len, remap_flags);
4855 if (ret <= 0) 4855 if (ret <= 0)
4856 goto out_unlock; 4856 goto out_unlock;
4857 4857
diff --git a/fs/ocfs2/refcounttree.h b/fs/ocfs2/refcounttree.h
index 4af55bf4b35b..d2c5f526edff 100644
--- a/fs/ocfs2/refcounttree.h
+++ b/fs/ocfs2/refcounttree.h
@@ -120,6 +120,6 @@ int ocfs2_reflink_remap_range(struct file *file_in,
120 struct file *file_out, 120 struct file *file_out,
121 loff_t pos_out, 121 loff_t pos_out,
122 u64 len, 122 u64 len,
123 bool is_dedupe); 123 unsigned int remap_flags);
124 124
125#endif /* OCFS2_REFCOUNTTREE_H */ 125#endif /* OCFS2_REFCOUNTTREE_H */
diff --git a/fs/read_write.c b/fs/read_write.c
index 766bdcb381f3..201381689284 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -1722,14 +1722,14 @@ static int generic_remap_check_len(struct inode *inode_in,
1722 struct inode *inode_out, 1722 struct inode *inode_out,
1723 loff_t pos_out, 1723 loff_t pos_out,
1724 u64 *len, 1724 u64 *len,
1725 bool is_dedupe) 1725 unsigned int remap_flags)
1726{ 1726{
1727 u64 blkmask = i_blocksize(inode_in) - 1; 1727 u64 blkmask = i_blocksize(inode_in) - 1;
1728 1728
1729 if ((*len & blkmask) == 0) 1729 if ((*len & blkmask) == 0)
1730 return 0; 1730 return 0;
1731 1731
1732 if (is_dedupe) 1732 if (remap_flags & REMAP_FILE_DEDUP)
1733 *len &= ~blkmask; 1733 *len &= ~blkmask;
1734 else if (pos_out + *len < i_size_read(inode_out)) 1734 else if (pos_out + *len < i_size_read(inode_out))
1735 return -EINVAL; 1735 return -EINVAL;
@@ -1747,7 +1747,7 @@ static int generic_remap_check_len(struct inode *inode_in,
1747 */ 1747 */
1748int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, 1748int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
1749 struct file *file_out, loff_t pos_out, 1749 struct file *file_out, loff_t pos_out,
1750 u64 *len, bool is_dedupe) 1750 u64 *len, unsigned int remap_flags)
1751{ 1751{
1752 struct inode *inode_in = file_inode(file_in); 1752 struct inode *inode_in = file_inode(file_in);
1753 struct inode *inode_out = file_inode(file_out); 1753 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,
1771 if (*len == 0) { 1771 if (*len == 0) {
1772 loff_t isize = i_size_read(inode_in); 1772 loff_t isize = i_size_read(inode_in);
1773 1773
1774 if (is_dedupe || pos_in == isize) 1774 if ((remap_flags & REMAP_FILE_DEDUP) || pos_in == isize)
1775 return 0; 1775 return 0;
1776 if (pos_in > isize) 1776 if (pos_in > isize)
1777 return -EINVAL; 1777 return -EINVAL;
@@ -1782,7 +1782,7 @@ int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
1782 1782
1783 /* Check that we don't violate system file offset limits. */ 1783 /* Check that we don't violate system file offset limits. */
1784 ret = generic_remap_checks(file_in, pos_in, file_out, pos_out, len, 1784 ret = generic_remap_checks(file_in, pos_in, file_out, pos_out, len,
1785 is_dedupe); 1785 (remap_flags & REMAP_FILE_DEDUP));
1786 if (ret) 1786 if (ret)
1787 return ret; 1787 return ret;
1788 1788
@@ -1804,7 +1804,7 @@ int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
1804 /* 1804 /*
1805 * Check that the extents are the same. 1805 * Check that the extents are the same.
1806 */ 1806 */
1807 if (is_dedupe) { 1807 if (remap_flags & REMAP_FILE_DEDUP) {
1808 bool is_same = false; 1808 bool is_same = false;
1809 1809
1810 ret = vfs_dedupe_file_range_compare(inode_in, pos_in, 1810 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,
1816 } 1816 }
1817 1817
1818 ret = generic_remap_check_len(inode_in, inode_out, pos_out, len, 1818 ret = generic_remap_check_len(inode_in, inode_out, pos_out, len,
1819 is_dedupe); 1819 remap_flags);
1820 if (ret) 1820 if (ret)
1821 return ret; 1821 return ret;
1822 1822
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 2ad94d508f80..20314eb4677a 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -932,7 +932,7 @@ xfs_file_remap_range(
932 return -EINVAL; 932 return -EINVAL;
933 933
934 return xfs_reflink_remap_range(file_in, pos_in, file_out, pos_out, 934 return xfs_reflink_remap_range(file_in, pos_in, file_out, pos_out,
935 len, remap_flags & REMAP_FILE_DEDUP); 935 len, remap_flags);
936} 936}
937 937
938STATIC int 938STATIC int
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index a7757a128a78..29aab196ce7e 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -921,13 +921,14 @@ xfs_reflink_update_dest(
921 struct xfs_inode *dest, 921 struct xfs_inode *dest,
922 xfs_off_t newlen, 922 xfs_off_t newlen,
923 xfs_extlen_t cowextsize, 923 xfs_extlen_t cowextsize,
924 bool is_dedupe) 924 unsigned int remap_flags)
925{ 925{
926 struct xfs_mount *mp = dest->i_mount; 926 struct xfs_mount *mp = dest->i_mount;
927 struct xfs_trans *tp; 927 struct xfs_trans *tp;
928 int error; 928 int error;
929 929
930 if (is_dedupe && newlen <= i_size_read(VFS_I(dest)) && cowextsize == 0) 930 if ((remap_flags & REMAP_FILE_DEDUP) &&
931 newlen <= i_size_read(VFS_I(dest)) && cowextsize == 0)
931 return 0; 932 return 0;
932 933
933 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp); 934 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
@@ -948,7 +949,7 @@ xfs_reflink_update_dest(
948 dest->i_d.di_flags2 |= XFS_DIFLAG2_COWEXTSIZE; 949 dest->i_d.di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
949 } 950 }
950 951
951 if (!is_dedupe) { 952 if (!(remap_flags & REMAP_FILE_DEDUP)) {
952 xfs_trans_ichgtime(tp, dest, 953 xfs_trans_ichgtime(tp, dest,
953 XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 954 XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
954 } 955 }
@@ -1296,7 +1297,7 @@ xfs_reflink_remap_prep(
1296 struct file *file_out, 1297 struct file *file_out,
1297 loff_t pos_out, 1298 loff_t pos_out,
1298 u64 *len, 1299 u64 *len,
1299 bool is_dedupe) 1300 unsigned int remap_flags)
1300{ 1301{
1301 struct inode *inode_in = file_inode(file_in); 1302 struct inode *inode_in = file_inode(file_in);
1302 struct xfs_inode *src = XFS_I(inode_in); 1303 struct xfs_inode *src = XFS_I(inode_in);
@@ -1327,7 +1328,7 @@ xfs_reflink_remap_prep(
1327 goto out_unlock; 1328 goto out_unlock;
1328 1329
1329 ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out, 1330 ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out,
1330 len, is_dedupe); 1331 len, remap_flags);
1331 if (ret <= 0) 1332 if (ret <= 0)
1332 goto out_unlock; 1333 goto out_unlock;
1333 1334
@@ -1336,7 +1337,7 @@ xfs_reflink_remap_prep(
1336 * from the source file so we don't try to dedupe the partial 1337 * from the source file so we don't try to dedupe the partial
1337 * EOF block. 1338 * EOF block.
1338 */ 1339 */
1339 if (is_dedupe) { 1340 if (remap_flags & REMAP_FILE_DEDUP) {
1340 *len &= ~blkmask; 1341 *len &= ~blkmask;
1341 } else if (*len & blkmask) { 1342 } else if (*len & blkmask) {
1342 /* 1343 /*
@@ -1372,7 +1373,7 @@ xfs_reflink_remap_prep(
1372 PAGE_ALIGN(pos_out + *len) - 1); 1373 PAGE_ALIGN(pos_out + *len) - 1);
1373 1374
1374 /* If we're altering the file contents... */ 1375 /* If we're altering the file contents... */
1375 if (!is_dedupe) { 1376 if (!(remap_flags & REMAP_FILE_DEDUP)) {
1376 /* 1377 /*
1377 * ...update the timestamps (which will grab the ilock again 1378 * ...update the timestamps (which will grab the ilock again
1378 * from xfs_fs_dirty_inode, so we have to call it before we 1379 * from xfs_fs_dirty_inode, so we have to call it before we
@@ -1410,7 +1411,7 @@ xfs_reflink_remap_range(
1410 struct file *file_out, 1411 struct file *file_out,
1411 loff_t pos_out, 1412 loff_t pos_out,
1412 u64 len, 1413 u64 len,
1413 bool is_dedupe) 1414 unsigned int remap_flags)
1414{ 1415{
1415 struct inode *inode_in = file_inode(file_in); 1416 struct inode *inode_in = file_inode(file_in);
1416 struct xfs_inode *src = XFS_I(inode_in); 1417 struct xfs_inode *src = XFS_I(inode_in);
@@ -1430,7 +1431,7 @@ xfs_reflink_remap_range(
1430 1431
1431 /* Prepare and then clone file data. */ 1432 /* Prepare and then clone file data. */
1432 ret = xfs_reflink_remap_prep(file_in, pos_in, file_out, pos_out, 1433 ret = xfs_reflink_remap_prep(file_in, pos_in, file_out, pos_out,
1433 &len, is_dedupe); 1434 &len, remap_flags);
1434 if (ret <= 0) 1435 if (ret <= 0)
1435 return ret; 1436 return ret;
1436 1437
@@ -1457,7 +1458,7 @@ xfs_reflink_remap_range(
1457 cowextsize = src->i_d.di_cowextsize; 1458 cowextsize = src->i_d.di_cowextsize;
1458 1459
1459 ret = xfs_reflink_update_dest(dest, pos_out + len, cowextsize, 1460 ret = xfs_reflink_update_dest(dest, pos_out + len, cowextsize,
1460 is_dedupe); 1461 remap_flags);
1461 1462
1462out_unlock: 1463out_unlock:
1463 xfs_reflink_remap_unlock(file_in, file_out); 1464 xfs_reflink_remap_unlock(file_in, file_out);
diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h
index c585ad9552b2..6f82d628bf17 100644
--- a/fs/xfs/xfs_reflink.h
+++ b/fs/xfs/xfs_reflink.h
@@ -28,7 +28,8 @@ extern int xfs_reflink_end_cow(struct xfs_inode *ip, xfs_off_t offset,
28 xfs_off_t count); 28 xfs_off_t count);
29extern int xfs_reflink_recover_cow(struct xfs_mount *mp); 29extern int xfs_reflink_recover_cow(struct xfs_mount *mp);
30extern int xfs_reflink_remap_range(struct file *file_in, loff_t pos_in, 30extern int xfs_reflink_remap_range(struct file *file_in, loff_t pos_in,
31 struct file *file_out, loff_t pos_out, u64 len, bool is_dedupe); 31 struct file *file_out, loff_t pos_out, u64 len,
32 unsigned int remap_flags);
32extern int xfs_reflink_inode_has_shared_extents(struct xfs_trans *tp, 33extern int xfs_reflink_inode_has_shared_extents(struct xfs_trans *tp,
33 struct xfs_inode *ip, bool *has_shared); 34 struct xfs_inode *ip, bool *has_shared);
34extern int xfs_reflink_clear_inode_flag(struct xfs_inode *ip, 35extern int xfs_reflink_clear_inode_flag(struct xfs_inode *ip,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 888cef35c7d7..631c28ce1436 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1844,7 +1844,7 @@ extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *,
1844 loff_t, size_t, unsigned int); 1844 loff_t, size_t, unsigned int);
1845extern int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, 1845extern int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in,
1846 struct file *file_out, loff_t pos_out, 1846 struct file *file_out, loff_t pos_out,
1847 u64 *count, bool is_dedupe); 1847 u64 *count, unsigned int remap_flags);
1848extern int do_clone_file_range(struct file *file_in, loff_t pos_in, 1848extern int do_clone_file_range(struct file *file_in, loff_t pos_in,
1849 struct file *file_out, loff_t pos_out, u64 len); 1849 struct file *file_out, loff_t pos_out, u64 len);
1850extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, 1850extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in,