diff options
Diffstat (limited to 'fs/xfs/xfs_reflink.c')
-rw-r--r-- | fs/xfs/xfs_reflink.c | 37 |
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: | |||
1119 | STATIC int | 1119 | STATIC int |
1120 | xfs_reflink_remap_blocks( | 1120 | xfs_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_); | |
1175 | err: | ||
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 | ||