summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorChunwei Chen <[email protected]>2016-07-05 12:39:47 -0700
committerNed Bass <[email protected]>2016-09-09 13:21:09 -0700
commitf7923f4adadb25d8e95c93c9abc35cfa9cd9f86b (patch)
treefbdc565f1f5cba4770897f14fafba99a77b88d67 /module/zfs
parent5acbedbbe882319cd8877a5870835a68801ad784 (diff)
xattr dir doesn't get purged during iput
We need to set inode->i_nlink to zero so iput will purge it. Without this, it will get purged during shrink cache or umount, which would likely result in deadlock due to zfs_zget waiting forever on its children which are in the dispose_list of the same thread. Signed-off-by: Chunwei Chen <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Signed-off-by: Chris Dunlop <[email protected]> Issue #4359 Issue #3508 Issue #4413 Issue #4827
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/zfs_dir.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/module/zfs/zfs_dir.c b/module/zfs/zfs_dir.c
index c1eadd0dc..b0c8e3658 100644
--- a/module/zfs/zfs_dir.c
+++ b/module/zfs/zfs_dir.c
@@ -593,7 +593,7 @@ zfs_purgedir(znode_t *dzp)
if (error)
skipped += 1;
dmu_tx_commit(tx);
-
+ set_nlink(ZTOI(xzp), xzp->z_links);
zfs_iput_async(ZTOI(xzp));
}
zap_cursor_fini(&zc);
@@ -694,6 +694,7 @@ zfs_rmnode(znode_t *zp)
mutex_enter(&xzp->z_lock);
xzp->z_unlinked = B_TRUE; /* mark xzp for deletion */
xzp->z_links = 0; /* no more links to it */
+ set_nlink(ZTOI(xzp), 0); /* this will let iput purge us */
VERIFY(0 == sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zsb),
&xzp->z_links, sizeof (xzp->z_links), tx));
mutex_exit(&xzp->z_lock);