aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_reflink.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_reflink.c')
-rw-r--r--fs/xfs/xfs_reflink.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index 79dec457f7fb..4abb2aea8f31 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -1122,13 +1122,15 @@ xfs_reflink_remap_blocks(
1122 loff_t pos_in, 1122 loff_t pos_in,
1123 struct xfs_inode *dest, 1123 struct xfs_inode *dest,
1124 loff_t pos_out, 1124 loff_t pos_out,
1125 loff_t remap_len) 1125 loff_t remap_len,
1126 loff_t *remapped)
1126{ 1127{
1127 struct xfs_bmbt_irec imap; 1128 struct xfs_bmbt_irec imap;
1128 xfs_fileoff_t srcoff; 1129 xfs_fileoff_t srcoff;
1129 xfs_fileoff_t destoff; 1130 xfs_fileoff_t destoff;
1130 xfs_filblks_t len; 1131 xfs_filblks_t len;
1131 xfs_filblks_t range_len; 1132 xfs_filblks_t range_len;
1133 xfs_filblks_t remapped_len = 0;
1132 xfs_off_t new_isize = pos_out + remap_len; 1134 xfs_off_t new_isize = pos_out + remap_len;
1133 int nimaps; 1135 int nimaps;
1134 int error = 0; 1136 int error = 0;
@@ -1175,10 +1177,13 @@ xfs_reflink_remap_blocks(
1175 srcoff += range_len; 1177 srcoff += range_len;
1176 destoff += range_len; 1178 destoff += range_len;
1177 len -= range_len; 1179 len -= range_len;
1180 remapped_len += range_len;
1178 } 1181 }
1179 1182
1180 if (error) 1183 if (error)
1181 trace_xfs_reflink_remap_blocks_error(dest, error, _RET_IP_); 1184 trace_xfs_reflink_remap_blocks_error(dest, error, _RET_IP_);
1185 *remapped = min_t(loff_t, remap_len,
1186 XFS_FSB_TO_B(src->i_mount, remapped_len));
1182 return error; 1187 return error;
1183} 1188}
1184 1189
@@ -1387,7 +1392,7 @@ out_unlock:
1387/* 1392/*
1388 * Link a range of blocks from one file to another. 1393 * Link a range of blocks from one file to another.
1389 */ 1394 */
1390int 1395loff_t
1391xfs_reflink_remap_range( 1396xfs_reflink_remap_range(
1392 struct file *file_in, 1397 struct file *file_in,
1393 loff_t pos_in, 1398 loff_t pos_in,
@@ -1401,8 +1406,9 @@ xfs_reflink_remap_range(
1401 struct inode *inode_out = file_inode(file_out); 1406 struct inode *inode_out = file_inode(file_out);
1402 struct xfs_inode *dest = XFS_I(inode_out); 1407 struct xfs_inode *dest = XFS_I(inode_out);
1403 struct xfs_mount *mp = src->i_mount; 1408 struct xfs_mount *mp = src->i_mount;
1409 loff_t remapped = 0;
1404 xfs_extlen_t cowextsize; 1410 xfs_extlen_t cowextsize;
1405 ssize_t ret; 1411 int ret;
1406 1412
1407 if (!xfs_sb_version_hasreflink(&mp->m_sb)) 1413 if (!xfs_sb_version_hasreflink(&mp->m_sb))
1408 return -EOPNOTSUPP; 1414 return -EOPNOTSUPP;
@@ -1418,7 +1424,8 @@ xfs_reflink_remap_range(
1418 1424
1419 trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out); 1425 trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out);
1420 1426
1421 ret = xfs_reflink_remap_blocks(src, pos_in, dest, pos_out, len); 1427 ret = xfs_reflink_remap_blocks(src, pos_in, dest, pos_out, len,
1428 &remapped);
1422 if (ret) 1429 if (ret)
1423 goto out_unlock; 1430 goto out_unlock;
1424 1431
@@ -1441,7 +1448,7 @@ out_unlock:
1441 xfs_reflink_remap_unlock(file_in, file_out); 1448 xfs_reflink_remap_unlock(file_in, file_out);
1442 if (ret) 1449 if (ret)
1443 trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_); 1450 trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_);
1444 return ret; 1451 return remapped > 0 ? remapped : ret;
1445} 1452}
1446 1453
1447/* 1454/*