Index: sys/sys/vnode.h =================================================================== --- sys/sys/vnode.h (revision 229979) +++ sys/sys/vnode.h (working copy) @@ -695,6 +695,9 @@ int vop_stdpoll(struct vop_poll_args *); int vop_stdvptocnp(struct vop_vptocnp_args *ap); int vop_stdvptofh(struct vop_vptofh_args *ap); +int vop_stdunpbind(struct vop_unpbind_args *ap); +int vop_stdunpconnect(struct vop_unpconnect_args *ap); +int vop_stdunpdetach(struct vop_unpdetach_args *ap); int vop_eopnotsupp(struct vop_generic_args *ap); int vop_ebadf(struct vop_generic_args *ap); int vop_einval(struct vop_generic_args *ap); Index: sys/kern/uipc_usrreq.c =================================================================== --- sys/kern/uipc_usrreq.c (revision 229979) +++ sys/kern/uipc_usrreq.c (working copy) @@ -542,7 +542,7 @@ UNP_LINK_WLOCK(); UNP_PCB_LOCK(unp); - vp->v_socket = unp->unp_socket; + VOP_UNPBIND(vp, unp->unp_socket); unp->unp_vnode = vp; unp->unp_addr = soun; unp->unp_flags &= ~UNP_BINDING; @@ -638,7 +638,7 @@ * XXXRW: Should assert vp->v_socket == so. */ if ((vp = unp->unp_vnode) != NULL) { - unp->unp_vnode->v_socket = NULL; + VOP_UNPDETACH(vp); unp->unp_vnode = NULL; } unp2 = unp->unp_conn; @@ -1273,8 +1273,8 @@ UNP_PCB_UNLOCK(unp); sa = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK); - NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | LOCKLEAF, UIO_SYSSPACE, buf, - td); + NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | LOCKSHARED | LOCKLEAF, + UIO_SYSSPACE, buf, td); error = namei(&nd); if (error) vp = NULL; @@ -1308,7 +1308,7 @@ * and to protect simultaneous locking of multiple pcbs. */ UNP_LINK_WLOCK(); - so2 = vp->v_socket; + VOP_UNPCONNECT(vp, &so2); if (so2 == NULL) { error = ECONNREFUSED; goto bad2; Index: sys/kern/vfs_default.c =================================================================== --- sys/kern/vfs_default.c (revision 229979) +++ sys/kern/vfs_default.c (working copy) @@ -123,6 +123,9 @@ .vop_unlock = vop_stdunlock, .vop_vptocnp = vop_stdvptocnp, .vop_vptofh = vop_stdvptofh, + .vop_unpbind = vop_stdunpbind, + .vop_unpconnect = vop_stdunpconnect, + .vop_unpdetach = vop_stdunpdetach, }; /* @@ -1037,6 +1040,39 @@ return (error); } +int +vop_stdunpbind(struct vop_unpbind_args *ap) +{ + struct vnode *vp; + + vp = ap->a_vp; + + vp->v_socket = ap->a_socket; + return (0); +} + +int +vop_stdunpconnect(struct vop_unpconnect_args *ap) +{ + struct vnode *vp; + + vp = ap->a_vp; + + *ap->a_socket = vp->v_socket; + return (0); +} + +int +vop_stdunpdetach(struct vop_unpdetach_args *ap) +{ + struct vnode *vp; + + vp = ap->a_vp; + + vp->v_socket = NULL; + return (0); +} + /* * vfs default ops * used to fill the vfs function table to get reasonable default return values. Index: sys/kern/vnode_if.src =================================================================== --- sys/kern/vnode_if.src (revision 229979) +++ sys/kern/vnode_if.src (working copy) @@ -640,6 +640,26 @@ IN int advice; }; +%% unpbind vp E E E + +vop_unpbind { + IN struct vnode *vp; + IN struct socket *socket; +}; + +%% unpconnect vp L L L + +vop_unpconnect { + IN struct vnode *vp; + OUT struct socket **socket; +}; + +%% unpdetach vp = = = + +vop_unpdetach { + IN struct vnode *vp; +}; + # The VOPs below are spares at the end of the table to allow new VOPs to be # added in stable branches without breaking the KBI. New VOPs in HEAD should # be added above these spares. When merging a new VOP to a stable branch,