]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: adjust refcount when unmapping file blocks
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 25 Oct 2016 01:26:48 +0000 (12:26 +1100)
committerDave Chinner <david@fromorbit.com>
Tue, 25 Oct 2016 01:26:48 +0000 (12:26 +1100)
Source kernel commit: 62aab20f08758b1b171a73a54e0c72dd12beb980

When we're unmapping blocks from a reflinked file, decrease the
refcount of the affected blocks and free the extents that are no
longer in use.

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

index 0a8edeb4b8c548d1a92fbb533c03e063e12c5f3f..a97024d6485cfcbd030eab571dc894be801c2727 100644 (file)
@@ -122,6 +122,11 @@ xfs_set_projid(struct xfs_icdinode *id, prid_t projid)
        id->di_projid_lo = (__uint16_t) (projid & 0xffff);
 }
 
+static inline bool xfs_is_reflink_inode(struct xfs_inode *ip)
+{
+       return ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK;
+}
+
 typedef struct cred {
        uid_t   cr_uid;
        gid_t   cr_gid;
index bd1d2d9d8ee8954fa3375dcc77686e7878e37f5a..9a911e848bec8a814b2b951a659d519f489fcb22 100644 (file)
@@ -40,6 +40,7 @@
 #include "xfs_quota_defs.h"
 #include "xfs_rmap.h"
 #include "xfs_ag_resv.h"
+#include "xfs_refcount.h"
 
 
 kmem_zone_t            *xfs_bmap_free_item_zone;
@@ -4980,9 +4981,16 @@ xfs_bmap_del_extent(
        /*
         * If we need to, add to list of extents to delete.
         */
-       if (do_fx)
-               xfs_bmap_add_free(mp, dfops, del->br_startblock,
-                               del->br_blockcount, NULL);
+       if (do_fx) {
+               if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) {
+                       error = xfs_refcount_decrease_extent(mp, dfops, del);
+                       if (error)
+                               goto done;
+               } else
+                       xfs_bmap_add_free(mp, dfops, del->br_startblock,
+                                       del->br_blockcount, NULL);
+       }
+
        /*
         * Adjust inode # blocks in the file.
         */