diff options
Diffstat (limited to 'fs/xfs/xfs_reflink.c')
-rw-r--r-- | fs/xfs/xfs_reflink.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index da1a447bef51..f135748d8282 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c | |||
@@ -1241,6 +1241,26 @@ xfs_reflink_remap_unlock( | |||
1241 | } | 1241 | } |
1242 | 1242 | ||
1243 | /* | 1243 | /* |
1244 | * If we're reflinking to a point past the destination file's EOF, we must | ||
1245 | * zero any speculative post-EOF preallocations that sit between the old EOF | ||
1246 | * and the destination file offset. | ||
1247 | */ | ||
1248 | static int | ||
1249 | xfs_reflink_zero_posteof( | ||
1250 | struct xfs_inode *ip, | ||
1251 | loff_t pos) | ||
1252 | { | ||
1253 | loff_t isize = i_size_read(VFS_I(ip)); | ||
1254 | |||
1255 | if (pos <= isize) | ||
1256 | return 0; | ||
1257 | |||
1258 | trace_xfs_zero_eof(ip, isize, pos - isize); | ||
1259 | return iomap_zero_range(VFS_I(ip), isize, pos - isize, NULL, | ||
1260 | &xfs_iomap_ops); | ||
1261 | } | ||
1262 | |||
1263 | /* | ||
1244 | * Prepare two files for range cloning. Upon a successful return both inodes | 1264 | * Prepare two files for range cloning. Upon a successful return both inodes |
1245 | * will have the iolock and mmaplock held, the page cache of the out file | 1265 | * will have the iolock and mmaplock held, the page cache of the out file |
1246 | * will be truncated, and any leases on the out file will have been broken. | 1266 | * will be truncated, and any leases on the out file will have been broken. |
@@ -1292,15 +1312,12 @@ xfs_reflink_remap_prep( | |||
1292 | goto out_unlock; | 1312 | goto out_unlock; |
1293 | 1313 | ||
1294 | /* | 1314 | /* |
1295 | * Clear out post-eof preallocations because we don't have page cache | 1315 | * Zero existing post-eof speculative preallocations in the destination |
1296 | * backing the delayed allocations and they'll never get freed on | 1316 | * file. |
1297 | * their own. | ||
1298 | */ | 1317 | */ |
1299 | if (xfs_can_free_eofblocks(dest, true)) { | 1318 | ret = xfs_reflink_zero_posteof(dest, pos_out); |
1300 | ret = xfs_free_eofblocks(dest); | 1319 | if (ret) |
1301 | if (ret) | 1320 | goto out_unlock; |
1302 | goto out_unlock; | ||
1303 | } | ||
1304 | 1321 | ||
1305 | /* Set flags and remap blocks. */ | 1322 | /* Set flags and remap blocks. */ |
1306 | ret = xfs_reflink_set_inode_flag(src, dest); | 1323 | ret = xfs_reflink_set_inode_flag(src, dest); |