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:
parent
5acbedbbe8
commit
f7923f4ada
|
@ -593,7 +593,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);
|
||||||
|
@ -694,6 +694,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);
|
||||||
|
|
Loading…
Reference in New Issue