/* * Reclaims the node resources that are linked to a given vnode * when the vnode is being reclaimed. Removes the procfsnode_t from * the hash table, removes the file system reference and breaks the * link between the vnode and the procfsnode_t. */ void procfsnode_reclaim(vnode_t vp) { procfsnode_t *pnp = vnode_to_procfsnode(vp); if (pnp != NULL) { // Lock to manipulate the hash table. lck_mtx_lock(procfsnode_hash_mutex); // Remove the node from the hash table and free it. procfsnode_free_node(pnp); // CAUTION: pnp is now invalid. Null it out to cause a panic // if it gets referenced beyond this point. pnp = NULL; lck_mtx_unlock(procfsnode_hash_mutex); } // Remove the file system reference that we added when // we created the vnode. vnode_removefsref(vp); // Clear the link to the procfsnode_t since the // vnode will no longer be linked to it. vnode_clearfsnode(vp); }
static int null_reclaim(struct vnop_reclaim_args * ap) { struct vnode * vp; struct null_node * xp; struct vnode * lowervp; struct null_mount * null_mp = MOUNTTONULLMOUNT(vnode_mount(ap->a_vp)); NULLFSDEBUG("%s %p\n", __FUNCTION__, ap->a_vp); vp = ap->a_vp; xp = VTONULL(vp); lowervp = xp->null_lowervp; lck_mtx_lock(&null_mp->nullm_lock); vnode_removefsref(vp); if (lowervp != NULL) { /* root and second don't have a lowervp, so nothing to release and nothing * got hashed */ if (xp->null_flags & NULL_FLAG_HASHED) { /* only call this if we actually made it into the hash list. reclaim gets called also to clean up a vnode that got created when it didn't need to under race conditions */ null_hashrem(xp); } vnode_getwithref(lowervp); vnode_rele(lowervp); vnode_put(lowervp); } if (vp == null_mp->nullm_rootvp) { null_mp->nullm_rootvp = NULL; } else if (vp == null_mp->nullm_secondvp) { null_mp->nullm_secondvp = NULL; } else if (vp == null_mp->nullm_thirdcovervp) { null_mp->nullm_thirdcovervp = NULL; } lck_mtx_unlock(&null_mp->nullm_lock); cache_purge(vp); vnode_clearfsnode(vp); FREE(xp, M_TEMP); return 0; }
static int vnop_reclaim_9p(struct vnop_reclaim_args *ap) { vnode_t vp; node_9p *np; TRACE(); vp = ap->a_vp; np = NTO9P(vp); nlock_9p(np, NODE_LCK_EXCLUSIVE); { SET(np->flags, NODE_RECL); ndel_9p(np); /* balance the ref added in nget_9p() */ vnode_removefsref(vp); vnode_clearfsnode(vp); cache_purge(vp); } nunlock_9p(np); /* root gets clunk in vfs_unmount_9p() */ if (!ISSET(np->nmp->flags, F_UNMOUNTING)) clunk_9p(np->nmp, np->fid); /* free it */ CLR(np->flags, NODE_RECL); if (ISSET(np->flags, NODE_WAITRECL)) { CLR(np->flags, NODE_WAITRECL); wakeup(np); } lck_rw_free(np->lck, lck_grp_9p); free_9p(np->direntries); free_9p(np); return 0; }