xfs: cancel CoW reservations and clear inode reflink flag when freeing blocks
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 3 Oct 2016 16:11:38 +0000 (09:11 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 5 Oct 2016 23:26:04 +0000 (16:26 -0700)
When we're freeing blocks (truncate, punch, etc.), clear all CoW
reservations in the range being freed.  If the file block count
drops to zero, also clear the inode reflink flag.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/xfs_inode.c

index edb453d531e14f31500b194a4c45f0039d2e57ea..f072f48b3c04aa8a644dc212f59a7605478d617d 100644 (file)
@@ -49,6 +49,7 @@
 #include "xfs_trans_priv.h"
 #include "xfs_log.h"
 #include "xfs_bmap_btree.h"
+#include "xfs_reflink.h"
 
 kmem_zone_t *xfs_inode_zone;
 
@@ -1586,6 +1587,18 @@ xfs_itruncate_extents(
                        goto out;
        }
 
+       /* Remove all pending CoW reservations. */
+       error = xfs_reflink_cancel_cow_blocks(ip, &tp, first_unmap_block,
+                       last_block);
+       if (error)
+               goto out;
+
+       /*
+        * Clear the reflink flag if we truncated everything.
+        */
+       if (ip->i_d.di_nblocks == 0 && xfs_is_reflink_inode(ip))
+               ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
+
        /*
         * Always re-log the inode so that our permanent transaction can keep
         * on rolling it forward in the log.