aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_reflink.c37
1 files changed, 18 insertions, 19 deletions
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index e8e86646bb4b..79dec457f7fb 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -1119,16 +1119,23 @@ out:
1119STATIC int 1119STATIC int
1120xfs_reflink_remap_blocks( 1120xfs_reflink_remap_blocks(
1121 struct xfs_inode *src, 1121 struct xfs_inode *src,
1122 xfs_fileoff_t srcoff, 1122 loff_t pos_in,
1123 struct xfs_inode *dest, 1123 struct xfs_inode *dest,
1124 xfs_fileoff_t destoff, 1124 loff_t pos_out,
1125 xfs_filblks_t len, 1125 loff_t remap_len)
1126 xfs_off_t new_isize)
1127{ 1126{
1128 struct xfs_bmbt_irec imap; 1127 struct xfs_bmbt_irec imap;
1128 xfs_fileoff_t srcoff;
1129 xfs_fileoff_t destoff;
1130 xfs_filblks_t len;
1131 xfs_filblks_t range_len;
1132 xfs_off_t new_isize = pos_out + remap_len;
1129 int nimaps; 1133 int nimaps;
1130 int error = 0; 1134 int error = 0;
1131 xfs_filblks_t range_len; 1135
1136 destoff = XFS_B_TO_FSBT(src->i_mount, pos_out);
1137 srcoff = XFS_B_TO_FSBT(src->i_mount, pos_in);
1138 len = XFS_B_TO_FSB(src->i_mount, remap_len);
1132 1139
1133 /* drange = (destoff, destoff + len); srange = (srcoff, srcoff + len) */ 1140 /* drange = (destoff, destoff + len); srange = (srcoff, srcoff + len) */
1134 while (len) { 1141 while (len) {
@@ -1143,7 +1150,7 @@ xfs_reflink_remap_blocks(
1143 error = xfs_bmapi_read(src, srcoff, len, &imap, &nimaps, 0); 1150 error = xfs_bmapi_read(src, srcoff, len, &imap, &nimaps, 0);
1144 xfs_iunlock(src, lock_mode); 1151 xfs_iunlock(src, lock_mode);
1145 if (error) 1152 if (error)
1146 goto err; 1153 break;
1147 ASSERT(nimaps == 1); 1154 ASSERT(nimaps == 1);
1148 1155
1149 trace_xfs_reflink_remap_imap(src, srcoff, len, XFS_IO_OVERWRITE, 1156 trace_xfs_reflink_remap_imap(src, srcoff, len, XFS_IO_OVERWRITE,
@@ -1157,11 +1164,11 @@ xfs_reflink_remap_blocks(
1157 error = xfs_reflink_remap_extent(dest, &imap, destoff, 1164 error = xfs_reflink_remap_extent(dest, &imap, destoff,
1158 new_isize); 1165 new_isize);
1159 if (error) 1166 if (error)
1160 goto err; 1167 break;
1161 1168
1162 if (fatal_signal_pending(current)) { 1169 if (fatal_signal_pending(current)) {
1163 error = -EINTR; 1170 error = -EINTR;
1164 goto err; 1171 break;
1165 } 1172 }
1166 1173
1167 /* Advance drange/srange */ 1174 /* Advance drange/srange */
@@ -1170,10 +1177,8 @@ xfs_reflink_remap_blocks(
1170 len -= range_len; 1177 len -= range_len;
1171 } 1178 }
1172 1179
1173 return 0; 1180 if (error)
1174 1181 trace_xfs_reflink_remap_blocks_error(dest, error, _RET_IP_);
1175err:
1176 trace_xfs_reflink_remap_blocks_error(dest, error, _RET_IP_);
1177 return error; 1182 return error;
1178} 1183}
1179 1184
@@ -1396,8 +1401,6 @@ xfs_reflink_remap_range(
1396 struct inode *inode_out = file_inode(file_out); 1401 struct inode *inode_out = file_inode(file_out);
1397 struct xfs_inode *dest = XFS_I(inode_out); 1402 struct xfs_inode *dest = XFS_I(inode_out);
1398 struct xfs_mount *mp = src->i_mount; 1403 struct xfs_mount *mp = src->i_mount;
1399 xfs_fileoff_t sfsbno, dfsbno;
1400 xfs_filblks_t fsblen;
1401 xfs_extlen_t cowextsize; 1404 xfs_extlen_t cowextsize;
1402 ssize_t ret; 1405 ssize_t ret;
1403 1406
@@ -1415,11 +1418,7 @@ xfs_reflink_remap_range(
1415 1418
1416 trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out); 1419 trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out);
1417 1420
1418 dfsbno = XFS_B_TO_FSBT(mp, pos_out); 1421 ret = xfs_reflink_remap_blocks(src, pos_in, dest, pos_out, len);
1419 sfsbno = XFS_B_TO_FSBT(mp, pos_in);
1420 fsblen = XFS_B_TO_FSB(mp, len);
1421 ret = xfs_reflink_remap_blocks(src, sfsbno, dest, dfsbno, fsblen,
1422 pos_out + len);
1423 if (ret) 1422 if (ret)
1424 goto out_unlock; 1423 goto out_unlock;
1425 1424