aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_inode.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index b41952a4ddd8..6f95bdb408ce 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1487,6 +1487,24 @@ xfs_link(
1487 return error; 1487 return error;
1488} 1488}
1489 1489
1490/* Clear the reflink flag and the cowblocks tag if possible. */
1491static void
1492xfs_itruncate_clear_reflink_flags(
1493 struct xfs_inode *ip)
1494{
1495 struct xfs_ifork *dfork;
1496 struct xfs_ifork *cfork;
1497
1498 if (!xfs_is_reflink_inode(ip))
1499 return;
1500 dfork = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1501 cfork = XFS_IFORK_PTR(ip, XFS_COW_FORK);
1502 if (dfork->if_bytes == 0 && cfork->if_bytes == 0)
1503 ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
1504 if (cfork->if_bytes == 0)
1505 xfs_inode_clear_cowblocks_tag(ip);
1506}
1507
1490/* 1508/*
1491 * Free up the underlying blocks past new_size. The new size must be smaller 1509 * Free up the underlying blocks past new_size. The new size must be smaller
1492 * than the current size. This routine can be used both for the attribute and 1510 * than the current size. This routine can be used both for the attribute and
@@ -1583,15 +1601,7 @@ xfs_itruncate_extents(
1583 if (error) 1601 if (error)
1584 goto out; 1602 goto out;
1585 1603
1586 /* 1604 xfs_itruncate_clear_reflink_flags(ip);
1587 * Clear the reflink flag if there are no data fork blocks and
1588 * there are no extents staged in the cow fork.
1589 */
1590 if (xfs_is_reflink_inode(ip) && ip->i_cnextents == 0) {
1591 if (ip->i_d.di_nblocks == 0)
1592 ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
1593 xfs_inode_clear_cowblocks_tag(ip);
1594 }
1595 1605
1596 /* 1606 /*
1597 * Always re-log the inode so that our permanent transaction can keep 1607 * Always re-log the inode so that our permanent transaction can keep