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.c23
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 }
616next_extent: 620next_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)