/*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)); }
/* 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)); }