diff options
Diffstat (limited to 'fs/xfs/xfs_reflink.c')
-rw-r--r-- | fs/xfs/xfs_reflink.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index cc041a29eb70..47aea2e82c26 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c | |||
@@ -49,8 +49,6 @@ | |||
49 | #include "xfs_alloc.h" | 49 | #include "xfs_alloc.h" |
50 | #include "xfs_quota_defs.h" | 50 | #include "xfs_quota_defs.h" |
51 | #include "xfs_quota.h" | 51 | #include "xfs_quota.h" |
52 | #include "xfs_btree.h" | ||
53 | #include "xfs_bmap_btree.h" | ||
54 | #include "xfs_reflink.h" | 52 | #include "xfs_reflink.h" |
55 | #include "xfs_iomap.h" | 53 | #include "xfs_iomap.h" |
56 | #include "xfs_rmap_btree.h" | 54 | #include "xfs_rmap_btree.h" |
@@ -456,6 +454,8 @@ retry: | |||
456 | if (error) | 454 | if (error) |
457 | goto out_bmap_cancel; | 455 | goto out_bmap_cancel; |
458 | 456 | ||
457 | xfs_inode_set_cowblocks_tag(ip); | ||
458 | |||
459 | /* Finish up. */ | 459 | /* Finish up. */ |
460 | error = xfs_defer_finish(&tp, &dfops); | 460 | error = xfs_defer_finish(&tp, &dfops); |
461 | if (error) | 461 | if (error) |
@@ -492,8 +492,9 @@ xfs_reflink_find_cow_mapping( | |||
492 | struct xfs_iext_cursor icur; | 492 | struct xfs_iext_cursor icur; |
493 | 493 | ||
494 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)); | 494 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)); |
495 | ASSERT(xfs_is_reflink_inode(ip)); | ||
496 | 495 | ||
496 | if (!xfs_is_reflink_inode(ip)) | ||
497 | return false; | ||
497 | offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset); | 498 | offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset); |
498 | if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got)) | 499 | if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got)) |
499 | return false; | 500 | return false; |
@@ -612,6 +613,9 @@ xfs_reflink_cancel_cow_blocks( | |||
612 | 613 | ||
613 | /* Remove the mapping from the CoW fork. */ | 614 | /* Remove the mapping from the CoW fork. */ |
614 | xfs_bmap_del_extent_cow(ip, &icur, &got, &del); | 615 | xfs_bmap_del_extent_cow(ip, &icur, &got, &del); |
616 | } else { | ||
617 | /* Didn't do anything, push cursor back. */ | ||
618 | xfs_iext_prev(ifp, &icur); | ||
615 | } | 619 | } |
616 | next_extent: | 620 | next_extent: |
617 | if (!xfs_iext_get_extent(ifp, &icur, &got)) | 621 | if (!xfs_iext_get_extent(ifp, &icur, &got)) |
@@ -727,7 +731,7 @@ xfs_reflink_end_cow( | |||
727 | (unsigned int)(end_fsb - offset_fsb), | 731 | (unsigned int)(end_fsb - offset_fsb), |
728 | XFS_DATA_FORK); | 732 | XFS_DATA_FORK); |
729 | error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_write, | 733 | error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_write, |
730 | resblks, 0, 0, &tp); | 734 | resblks, 0, XFS_TRANS_RESERVE, &tp); |
731 | if (error) | 735 | if (error) |
732 | goto out; | 736 | goto out; |
733 | 737 | ||
@@ -1293,6 +1297,17 @@ xfs_reflink_remap_range( | |||
1293 | 1297 | ||
1294 | trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out); | 1298 | trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out); |
1295 | 1299 | ||
1300 | /* | ||
1301 | * Clear out post-eof preallocations because we don't have page cache | ||
1302 | * backing the delayed allocations and they'll never get freed on | ||
1303 | * their own. | ||
1304 | */ | ||
1305 | if (xfs_can_free_eofblocks(dest, true)) { | ||
1306 | ret = xfs_free_eofblocks(dest); | ||
1307 | if (ret) | ||
1308 | goto out_unlock; | ||
1309 | } | ||
1310 | |||
1296 | /* Set flags and remap blocks. */ | 1311 | /* Set flags and remap blocks. */ |
1297 | ret = xfs_reflink_set_inode_flag(src, dest); | 1312 | ret = xfs_reflink_set_inode_flag(src, dest); |
1298 | if (ret) | 1313 | if (ret) |