diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 4db124f..7fe68ac 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -448,6 +448,42 @@ uipc_attach(struct socket *so, int proto, struct thread *td) return (0); } +void uipc_prepare_reclaim(struct vnode *vp); + +void +uipc_prepare_reclaim(struct vnode *vp) +{ + struct socket *so; + struct unpcb *unp; + int active; + + ASSERT_VOP_ELOCKED(vp, "uipc_prepare_reclaim"); + ASSERT_VI_LOCKED(vp, "uipc_prepare_reclaim"); + KASSERT(vp->v_type == VSOCK, + ("uipc_prepare_reclaim: vp->v_type != VSOCK")); + + VI_UNLOCK(vp); + UNP_LINK_RLOCK(); + active = 0; + if ((so = vp->v_socket) == NULL) + goto done; + if ((unp = sotounpcb(so)) != NULL) { + UNP_PCB_LOCK(unp); + if (unp->unp_vnode != NULL) { + KASSERT(unp->unp_vnode == vp, + ("uipc_prepare_reclaim: vp != unp->unp_vnode")); + unp->unp_vnode = NULL; + active = 1; + } + UNP_PCB_UNLOCK(unp); + } +done: + UNP_LINK_RUNLOCK(); + if (active) + vunref(vp); + VI_LOCK(vp); +} + static int uipc_bind(struct socket *so, struct sockaddr *nam, struct thread *td) { diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 544b1cc..ed5b6ec 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2445,6 +2445,9 @@ static int busyprt = 0; /* print out busy vnodes */ SYSCTL_INT(_debug, OID_AUTO, busyprt, CTLFLAG_RW, &busyprt, 0, "Print out busy vnodes"); #endif +struct vnode; +void uipc_prepare_reclaim(struct vnode *vp); + int vflush(struct mount *mp, int rootrefs, int flags, struct thread *td) { @@ -2519,6 +2522,8 @@ loop: VNASSERT(vp->v_usecount == 0 || (vp->v_type != VCHR && vp->v_type != VBLK), vp, ("device VNODE %p is FORCECLOSED", vp)); + if (vp->v_type == VSOCK) + uipc_prepare_reclaim(vp); vgonel(vp); } else { busy++;