diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2018-10-29 19:41:28 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2018-10-29 19:41:28 -0400 |
commit | a91ae49bbaf43910edb09e03fedf26b23875bd52 (patch) | |
tree | 8152c5568a957e47b986e25324846e06a6d1fd57 | |
parent | 2e5dfc99f2e61c42083ba742395e7a7b353513d1 (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.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/refcounttree.c | 4 | ||||
-rw-r--r-- | fs/ocfs2/refcounttree.h | 2 | ||||
-rw-r--r-- | fs/read_write.c | 14 | ||||
-rw-r--r-- | fs/xfs/xfs_file.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_reflink.c | 21 | ||||
-rw-r--r-- | fs/xfs/xfs_reflink.h | 3 | ||||
-rw-r--r-- | include/linux/fs.h | 2 |
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 | ||
2544 | const struct inode_operations ocfs2_file_iops = { | 2544 | const 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 | */ |
1748 | int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, | 1748 | int 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 | ||
938 | STATIC int | 938 | STATIC 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 | ||
1462 | out_unlock: | 1463 | out_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); |
29 | extern int xfs_reflink_recover_cow(struct xfs_mount *mp); | 29 | extern int xfs_reflink_recover_cow(struct xfs_mount *mp); |
30 | extern int xfs_reflink_remap_range(struct file *file_in, loff_t pos_in, | 30 | extern 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); | ||
32 | extern int xfs_reflink_inode_has_shared_extents(struct xfs_trans *tp, | 33 | extern 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); |
34 | extern int xfs_reflink_clear_inode_flag(struct xfs_inode *ip, | 35 | extern 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); |
1845 | extern int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, | 1845 | extern 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); |
1848 | extern int do_clone_file_range(struct file *file_in, loff_t pos_in, | 1848 | extern 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); |
1850 | extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, | 1850 | extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, |