/* * Clean pts sdev_nodes that are no longer valid. */ static void devpts_prunedir(struct sdev_node *ddv) { struct vnode *vp; struct sdev_node *dv, *next = NULL; int (*vtor)(struct sdev_node *) = NULL; ASSERT(ddv->sdev_flags & SDEV_VTOR); vtor = (int (*)(struct sdev_node *))sdev_get_vtor(ddv); ASSERT(vtor); if (rw_tryupgrade(&ddv->sdev_contents) == NULL) { rw_exit(&ddv->sdev_contents); rw_enter(&ddv->sdev_contents, RW_WRITER); } for (dv = ddv->sdev_dot; dv; dv = next) { next = dv->sdev_next; /* skip stale nodes */ if (dv->sdev_flags & SDEV_STALE) continue; /* validate and prune only ready nodes */ if (dv->sdev_state != SDEV_READY) continue; switch (vtor(dv)) { case SDEV_VTOR_VALID: case SDEV_VTOR_SKIP: continue; case SDEV_VTOR_INVALID: sdcmn_err7(("prunedir: destroy invalid " "node: %s(%p)\n", dv->sdev_name, (void *)dv)); break; } vp = SDEVTOV(dv); if (vp->v_count > 0) continue; SDEV_HOLD(dv); /* remove the cache node */ (void) sdev_cache_update(ddv, &dv, dv->sdev_name, SDEV_CACHE_DELETE); } rw_downgrade(&ddv->sdev_contents); }
/* * First step in refreshing directory contents. * Remove each invalid entry and rebuild the link * reference for each stale entry. */ static void devvt_prunedir(struct sdev_node *ddv) { struct vnode *vp; struct sdev_node *dv, *next = NULL; int (*vtor)(struct sdev_node *) = NULL; ASSERT(ddv->sdev_flags & SDEV_VTOR); vtor = (int (*)(struct sdev_node *))sdev_get_vtor(ddv); ASSERT(vtor); for (dv = SDEV_FIRST_ENTRY(ddv); dv; dv = next) { next = SDEV_NEXT_ENTRY(ddv, dv); switch (vtor(dv)) { case SDEV_VTOR_VALID: break; case SDEV_VTOR_SKIP: break; case SDEV_VTOR_INVALID: vp = SDEVTOV(dv); if (vp->v_count != 0) break; /* remove the cached node */ SDEV_HOLD(dv); (void) sdev_cache_update(ddv, &dv, dv->sdev_name, SDEV_CACHE_DELETE); SDEV_RELE(dv); break; case SDEV_VTOR_STALE: devvt_rebuild_stale_link(ddv, dv); break; } } }