aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-10-29 19:47:26 -0400
committerDave Chinner <david@fromorbit.com>2018-10-29 19:47:26 -0400
commit3fc9f5e409319e994d113cf1327ba6ab147423c2 (patch)
treec4829da4dca97ee610fb059363fef6362ab65bd2 /fs/xfs
parent7a6ccf004e234c01fb2a11771de9837c9ff3d56d (diff)
xfs: remove xfs_reflink_remap_range
Since xfs_file_remap_range is a thin wrapper, move the contents of xfs_reflink_remap_range into the shell. This cuts down on the vfs calls being made from internal xfs code. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_file.c65
-rw-r--r--fs/xfs/xfs_reflink.c70
-rw-r--r--fs/xfs/xfs_reflink.h10
3 files changed, 70 insertions, 75 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 7d42ab8fe6e1..53c9ab8fb777 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -919,20 +919,67 @@ out_unlock:
919 return error; 919 return error;
920} 920}
921 921
922STATIC loff_t 922
923loff_t
923xfs_file_remap_range( 924xfs_file_remap_range(
924 struct file *file_in, 925 struct file *file_in,
925 loff_t pos_in, 926 loff_t pos_in,
926 struct file *file_out, 927 struct file *file_out,
927 loff_t pos_out, 928 loff_t pos_out,
928 loff_t len, 929 loff_t len,
929 unsigned int remap_flags) 930 unsigned int remap_flags)
930{ 931{
932 struct inode *inode_in = file_inode(file_in);
933 struct xfs_inode *src = XFS_I(inode_in);
934 struct inode *inode_out = file_inode(file_out);
935 struct xfs_inode *dest = XFS_I(inode_out);
936 struct xfs_mount *mp = src->i_mount;
937 loff_t remapped = 0;
938 xfs_extlen_t cowextsize;
939 int ret;
940
931 if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY)) 941 if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
932 return -EINVAL; 942 return -EINVAL;
933 943
934 return xfs_reflink_remap_range(file_in, pos_in, file_out, pos_out, 944 if (!xfs_sb_version_hasreflink(&mp->m_sb))
935 len, remap_flags); 945 return -EOPNOTSUPP;
946
947 if (XFS_FORCED_SHUTDOWN(mp))
948 return -EIO;
949
950 /* Prepare and then clone file data. */
951 ret = xfs_reflink_remap_prep(file_in, pos_in, file_out, pos_out,
952 &len, remap_flags);
953 if (ret < 0 || len == 0)
954 return ret;
955
956 trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out);
957
958 ret = xfs_reflink_remap_blocks(src, pos_in, dest, pos_out, len,
959 &remapped);
960 if (ret)
961 goto out_unlock;
962
963 /*
964 * Carry the cowextsize hint from src to dest if we're sharing the
965 * entire source file to the entire destination file, the source file
966 * has a cowextsize hint, and the destination file does not.
967 */
968 cowextsize = 0;
969 if (pos_in == 0 && len == i_size_read(inode_in) &&
970 (src->i_d.di_flags2 & XFS_DIFLAG2_COWEXTSIZE) &&
971 pos_out == 0 && len >= i_size_read(inode_out) &&
972 !(dest->i_d.di_flags2 & XFS_DIFLAG2_COWEXTSIZE))
973 cowextsize = src->i_d.di_cowextsize;
974
975 ret = xfs_reflink_update_dest(dest, pos_out + len, cowextsize,
976 remap_flags);
977
978out_unlock:
979 xfs_reflink_remap_unlock(file_in, file_out);
980 if (ret)
981 trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_);
982 return remapped > 0 ? remapped : ret;
936} 983}
937 984
938STATIC int 985STATIC int
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index bccc66316cc4..84f372f7ea04 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -916,7 +916,7 @@ out_error:
916/* 916/*
917 * Update destination inode size & cowextsize hint, if necessary. 917 * Update destination inode size & cowextsize hint, if necessary.
918 */ 918 */
919STATIC int 919int
920xfs_reflink_update_dest( 920xfs_reflink_update_dest(
921 struct xfs_inode *dest, 921 struct xfs_inode *dest,
922 xfs_off_t newlen, 922 xfs_off_t newlen,
@@ -1116,7 +1116,7 @@ out:
1116/* 1116/*
1117 * Iteratively remap one file's extents (and holes) to another's. 1117 * Iteratively remap one file's extents (and holes) to another's.
1118 */ 1118 */
1119STATIC int 1119int
1120xfs_reflink_remap_blocks( 1120xfs_reflink_remap_blocks(
1121 struct xfs_inode *src, 1121 struct xfs_inode *src,
1122 loff_t pos_in, 1122 loff_t pos_in,
@@ -1232,7 +1232,7 @@ retry:
1232} 1232}
1233 1233
1234/* Unlock both inodes after they've been prepped for a range clone. */ 1234/* Unlock both inodes after they've been prepped for a range clone. */
1235STATIC void 1235void
1236xfs_reflink_remap_unlock( 1236xfs_reflink_remap_unlock(
1237 struct file *file_in, 1237 struct file *file_in,
1238 struct file *file_out) 1238 struct file *file_out)
@@ -1300,7 +1300,7 @@ xfs_reflink_zero_posteof(
1300 * stale data in the destination file. Hence we reject these clone attempts with 1300 * stale data in the destination file. Hence we reject these clone attempts with
1301 * -EINVAL in this case. 1301 * -EINVAL in this case.
1302 */ 1302 */
1303STATIC int 1303int
1304xfs_reflink_remap_prep( 1304xfs_reflink_remap_prep(
1305 struct file *file_in, 1305 struct file *file_in,
1306 loff_t pos_in, 1306 loff_t pos_in,
@@ -1371,68 +1371,6 @@ out_unlock:
1371} 1371}
1372 1372
1373/* 1373/*
1374 * Link a range of blocks from one file to another.
1375 */
1376loff_t
1377xfs_reflink_remap_range(
1378 struct file *file_in,
1379 loff_t pos_in,
1380 struct file *file_out,
1381 loff_t pos_out,
1382 loff_t len,
1383 unsigned int remap_flags)
1384{
1385 struct inode *inode_in = file_inode(file_in);
1386 struct xfs_inode *src = XFS_I(inode_in);
1387 struct inode *inode_out = file_inode(file_out);
1388 struct xfs_inode *dest = XFS_I(inode_out);
1389 struct xfs_mount *mp = src->i_mount;
1390 loff_t remapped = 0;
1391 xfs_extlen_t cowextsize;
1392 int ret;
1393
1394 if (!xfs_sb_version_hasreflink(&mp->m_sb))
1395 return -EOPNOTSUPP;
1396
1397 if (XFS_FORCED_SHUTDOWN(mp))
1398 return -EIO;
1399
1400 /* Prepare and then clone file data. */
1401 ret = xfs_reflink_remap_prep(file_in, pos_in, file_out, pos_out,
1402 &len, remap_flags);
1403 if (ret < 0 || len == 0)
1404 return ret;
1405
1406 trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out);
1407
1408 ret = xfs_reflink_remap_blocks(src, pos_in, dest, pos_out, len,
1409 &remapped);
1410 if (ret)
1411 goto out_unlock;
1412
1413 /*
1414 * Carry the cowextsize hint from src to dest if we're sharing the
1415 * entire source file to the entire destination file, the source file
1416 * has a cowextsize hint, and the destination file does not.
1417 */
1418 cowextsize = 0;
1419 if (pos_in == 0 && len == i_size_read(inode_in) &&
1420 (src->i_d.di_flags2 & XFS_DIFLAG2_COWEXTSIZE) &&
1421 pos_out == 0 && len >= i_size_read(inode_out) &&
1422 !(dest->i_d.di_flags2 & XFS_DIFLAG2_COWEXTSIZE))
1423 cowextsize = src->i_d.di_cowextsize;
1424
1425 ret = xfs_reflink_update_dest(dest, pos_out + len, cowextsize,
1426 remap_flags);
1427
1428out_unlock:
1429 xfs_reflink_remap_unlock(file_in, file_out);
1430 if (ret)
1431 trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_);
1432 return remapped > 0 ? remapped : ret;
1433}
1434
1435/*
1436 * The user wants to preemptively CoW all shared blocks in this file, 1374 * The user wants to preemptively CoW all shared blocks in this file,
1437 * which enables us to turn off the reflink flag. Iterate all 1375 * which enables us to turn off the reflink flag. Iterate all
1438 * extents which are not prealloc/delalloc to see which ranges are 1376 * extents which are not prealloc/delalloc to see which ranges are
diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h
index cbc26ff79a8f..28a84edda889 100644
--- a/fs/xfs/xfs_reflink.h
+++ b/fs/xfs/xfs_reflink.h
@@ -36,5 +36,15 @@ extern int xfs_reflink_clear_inode_flag(struct xfs_inode *ip,
36 struct xfs_trans **tpp); 36 struct xfs_trans **tpp);
37extern int xfs_reflink_unshare(struct xfs_inode *ip, xfs_off_t offset, 37extern int xfs_reflink_unshare(struct xfs_inode *ip, xfs_off_t offset,
38 xfs_off_t len); 38 xfs_off_t len);
39extern int xfs_reflink_remap_prep(struct file *file_in, loff_t pos_in,
40 struct file *file_out, loff_t pos_out, loff_t *len,
41 unsigned int remap_flags);
42extern int xfs_reflink_remap_blocks(struct xfs_inode *src, loff_t pos_in,
43 struct xfs_inode *dest, loff_t pos_out, loff_t remap_len,
44 loff_t *remapped);
45extern int xfs_reflink_update_dest(struct xfs_inode *dest, xfs_off_t newlen,
46 xfs_extlen_t cowextsize, unsigned int remap_flags);
47extern void xfs_reflink_remap_unlock(struct file *file_in,
48 struct file *file_out);
39 49
40#endif /* __XFS_REFLINK_H */ 50#endif /* __XFS_REFLINK_H */