summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_usrreq.c
diff options
context:
space:
mode:
authortrociny <trociny@FreeBSD.org>2012-02-29 21:38:31 +0000
committertrociny <trociny@FreeBSD.org>2012-02-29 21:38:31 +0000
commit1aad0004eef0a2c8cc3f79dd3a6f03dd46dd047a (patch)
tree68c4dc3240253dab5bf3767c81e64d876b2ec226 /sys/kern/uipc_usrreq.c
parent7f479f0242bfa3392b0ad6d21188de6300c5576f (diff)
downloadFreeBSD-src-1aad0004eef0a2c8cc3f79dd3a6f03dd46dd047a.zip
FreeBSD-src-1aad0004eef0a2c8cc3f79dd3a6f03dd46dd047a.tar.gz
Introduce VOP_UNP_BIND(), VOP_UNP_CONNECT(), and VOP_UNP_DETACH()
operations for setting and accessing vnode's v_socket field. The operations are necessary to implement proper unix socket handling on layered file systems like nullfs(5). This change fixes the long standing issue with nullfs(5) being in that unix sockets did not work between lower and upper layers: if we bound to a socket on the lower layer we could connect only to the lower path; if we bound to the upper layer we could connect only to the upper path. The new behavior is one can connect to both the lower and the upper paths regardless what layer path one binds to. PR: kern/51583, kern/159663 Suggested by: kib Reviewed by: arch MFC after: 2 weeks
Diffstat (limited to 'sys/kern/uipc_usrreq.c')
-rw-r--r--sys/kern/uipc_usrreq.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 8f329fd..72cc483 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -542,7 +542,7 @@ restart:
UNP_LINK_WLOCK();
UNP_PCB_LOCK(unp);
- vp->v_socket = unp->unp_socket;
+ VOP_UNP_BIND(vp, unp->unp_socket);
unp->unp_vnode = vp;
unp->unp_addr = soun;
unp->unp_flags &= ~UNP_BINDING;
@@ -638,7 +638,7 @@ uipc_detach(struct socket *so)
* XXXRW: Should assert vp->v_socket == so.
*/
if ((vp = unp->unp_vnode) != NULL) {
- unp->unp_vnode->v_socket = NULL;
+ VOP_UNP_DETACH(vp);
unp->unp_vnode = NULL;
}
unp2 = unp->unp_conn;
@@ -1308,7 +1308,7 @@ unp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
* and to protect simultaneous locking of multiple pcbs.
*/
UNP_LINK_WLOCK();
- so2 = vp->v_socket;
+ VOP_UNP_CONNECT(vp, &so2);
if (so2 == NULL) {
error = ECONNREFUSED;
goto bad2;
@@ -2318,17 +2318,15 @@ vfs_unp_reclaim(struct vnode *vp)
active = 0;
UNP_LINK_WLOCK();
- so = vp->v_socket;
+ VOP_UNP_CONNECT(vp, &so);
if (so == NULL)
goto done;
unp = sotounpcb(so);
if (unp == NULL)
goto done;
UNP_PCB_LOCK(unp);
- if (unp->unp_vnode != NULL) {
- KASSERT(unp->unp_vnode == vp,
- ("vfs_unp_reclaim: vp != unp->unp_vnode"));
- vp->v_socket = NULL;
+ if (unp->unp_vnode == vp) {
+ VOP_UNP_DETACH(vp);
unp->unp_vnode = NULL;
active = 1;
}
OpenPOWER on IntegriCloud