summaryrefslogtreecommitdiff
path: root/fs/xfs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2016-10-03 09:11:38 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2016-10-05 16:26:05 -0700
commit5e7e605c4d1b5229c7df8a71798df00a4300428b (patch)
treea2a5bf635cbb051bf86f0f5f533309b15a3db0ba /fs/xfs
parentaa8968f227a8c6c7468c9d498daf06f8dbc30af0 (diff)
xfs: cancel pending CoW reservations when destroying inodes
When destroying the inode, cancel all pending reservations in the CoW fork so that all the reserved blocks go back to the free pile. In theory this sort of cleanup is only needed to clean up after write errors. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_super.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 35c04a790754..b65b97997f99 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -49,6 +49,7 @@
#include "xfs_rmap_item.h"
#include "xfs_refcount_item.h"
#include "xfs_bmap_item.h"
+#include "xfs_reflink.h"
#include <linux/namei.h>
#include <linux/init.h>
@@ -938,6 +939,7 @@ xfs_fs_destroy_inode(
struct inode *inode)
{
struct xfs_inode *ip = XFS_I(inode);
+ int error;
trace_xfs_destroy_inode(ip);
@@ -945,6 +947,12 @@ xfs_fs_destroy_inode(
XFS_STATS_INC(ip->i_mount, vn_rele);
XFS_STATS_INC(ip->i_mount, vn_remove);
+ error = xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF);
+ if (error && !XFS_FORCED_SHUTDOWN(ip->i_mount))
+ xfs_warn(ip->i_mount, "Error %d while evicting CoW blocks "
+ "for inode %llu.",
+ error, ip->i_ino);
+
xfs_inactive(ip);
ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);