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 <david.chen@osnexus.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Chris Dunlop <chris@onthe.net.au>
Issue #4359
Issue #3508
Issue #4413
Issue #4827
This commit is contained in:
Chunwei Chen 2016-07-05 12:39:47 -07:00 committed by Brian Behlendorf
parent 6c2530647c
commit ddae16a9cf

View File

@ -594,7 +594,7 @@ zfs_purgedir(znode_t *dzp)
if (error) if (error)
skipped += 1; skipped += 1;
dmu_tx_commit(tx); dmu_tx_commit(tx);
set_nlink(ZTOI(xzp), xzp->z_links);
zfs_iput_async(ZTOI(xzp)); zfs_iput_async(ZTOI(xzp));
} }
zap_cursor_fini(&zc); zap_cursor_fini(&zc);
@ -695,6 +695,7 @@ zfs_rmnode(znode_t *zp)
mutex_enter(&xzp->z_lock); mutex_enter(&xzp->z_lock);
xzp->z_unlinked = B_TRUE; /* mark xzp for deletion */ xzp->z_unlinked = B_TRUE; /* mark xzp for deletion */
xzp->z_links = 0; /* no more links to it */ 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), VERIFY(0 == sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zsb),
&xzp->z_links, sizeof (xzp->z_links), tx)); &xzp->z_links, sizeof (xzp->z_links), tx));
mutex_exit(&xzp->z_lock); mutex_exit(&xzp->z_lock);