/*ARGSUSED*/
static void
autofs_zone_destructor(zoneid_t zoneid, void *arg)
{
	struct autofs_globals *fngp = arg;
	vnode_t *vp;

	if (fngp == NULL)
		return;
	ASSERT(fngp->fng_fnnode_count == 1);
	ASSERT(fngp->fng_unmount_threads == 0);
	/*
	 * vn_alloc() initialized the rootnode with a count of 1; we need to
	 * make this 0 to placate auto_freefnnode().
	 */
	vp = fntovn(fngp->fng_rootfnnodep);
	ASSERT(vp->v_count == 1);
	vp->v_count--;
	auto_freefnnode(fngp->fng_rootfnnodep);
	mutex_destroy(&fngp->fng_unmount_threads_lock);
	kmem_free(fngp, sizeof (*fngp));
}
Esempio n. 2
0
/* ARGSUSED */
static void
auto_inactive(vnode_t *vp, cred_t *cred, caller_context_t *ct)
{
	fnnode_t *fnp = vntofn(vp);
	fnnode_t *dfnp = fnp->fn_parent;
	int count;

	AUTOFS_DPRINT((4, "auto_inactive: vp=%p v_count=%u fn_link=%d\n",
	    (void *)vp, vp->v_count, fnp->fn_linkcnt));

	/*
	 * The rwlock should not be already held by this thread.
	 * The assert relies on the fact that the owner field is cleared
	 * when the lock is released.
	 */
	ASSERT(dfnp != NULL);
	ASSERT(rw_owner(&dfnp->fn_rwlock) != curthread);
	rw_enter(&dfnp->fn_rwlock, RW_WRITER);
	mutex_enter(&vp->v_lock);
	ASSERT(vp->v_count > 0);
	count = --vp->v_count;
	mutex_exit(&vp->v_lock);
	if (count == 0) {
		/*
		 * Free only if node has no subdirectories.
		 */
		if (fnp->fn_linkcnt == 1) {
			auto_disconnect(dfnp, fnp);
			rw_exit(&dfnp->fn_rwlock);
			auto_freefnnode(fnp);
			AUTOFS_DPRINT((5, "auto_inactive: (exit) vp=%p freed\n",
			    (void *)vp));
			return;
		}
	}
	rw_exit(&dfnp->fn_rwlock);

	AUTOFS_DPRINT((5, "auto_inactive: (exit) vp=%p v_count=%u fn_link=%d\n",
	    (void *)vp, vp->v_count, fnp->fn_linkcnt));
}