From owner-svn-src-head@FreeBSD.ORG Wed Feb 29 21:38:32 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2FD0C1065687; Wed, 29 Feb 2012 21:38:32 +0000 (UTC) (envelope-from trociny@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 14CBB8FC13; Wed, 29 Feb 2012 21:38:32 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q1TLcV7W046110; Wed, 29 Feb 2012 21:38:31 GMT (envelope-from trociny@svn.freebsd.org) Received: (from trociny@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q1TLcVFv046104; Wed, 29 Feb 2012 21:38:31 GMT (envelope-from trociny@svn.freebsd.org) Message-Id: <201202292138.q1TLcVFv046104@svn.freebsd.org> From: Mikolaj Golub Date: Wed, 29 Feb 2012 21:38:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r232317 - in head: . sys/kern sys/sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Feb 2012 21:38:32 -0000 Author: trociny Date: Wed Feb 29 21:38:31 2012 New Revision: 232317 URL: http://svn.freebsd.org/changeset/base/232317 Log: 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 Modified: head/UPDATING head/sys/kern/uipc_usrreq.c head/sys/kern/vfs_default.c head/sys/kern/vnode_if.src head/sys/sys/vnode.h Modified: head/UPDATING ============================================================================== --- head/UPDATING Wed Feb 29 21:11:02 2012 (r232316) +++ head/UPDATING Wed Feb 29 21:38:31 2012 (r232317) @@ -22,6 +22,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10 machines to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20120229: + Now unix domain sockets behave "as expected" on nullfs(5). Previously + nullfs(5) did not pass through all behaviours to the underlying layer, + as a result 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. + 20120211: The getifaddrs upgrade path broken with 20111215 has been restored. If you have upgraded in between 20111215 and 20120209 you need to Modified: head/sys/kern/uipc_usrreq.c ============================================================================== --- head/sys/kern/uipc_usrreq.c Wed Feb 29 21:11:02 2012 (r232316) +++ head/sys/kern/uipc_usrreq.c Wed Feb 29 21:38:31 2012 (r232317) @@ -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 so * 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; } Modified: head/sys/kern/vfs_default.c ============================================================================== --- head/sys/kern/vfs_default.c Wed Feb 29 21:11:02 2012 (r232316) +++ head/sys/kern/vfs_default.c Wed Feb 29 21:38:31 2012 (r232317) @@ -123,6 +123,9 @@ struct vop_vector default_vnodeops = { .vop_unlock = vop_stdunlock, .vop_vptocnp = vop_stdvptocnp, .vop_vptofh = vop_stdvptofh, + .vop_unp_bind = vop_stdunp_bind, + .vop_unp_connect = vop_stdunp_connect, + .vop_unp_detach = vop_stdunp_detach, }; /* @@ -1037,6 +1040,30 @@ vop_stdadvise(struct vop_advise_args *ap return (error); } +int +vop_stdunp_bind(struct vop_unp_bind_args *ap) +{ + + ap->a_vp->v_socket = ap->a_socket; + return (0); +} + +int +vop_stdunp_connect(struct vop_unp_connect_args *ap) +{ + + *ap->a_socket = ap->a_vp->v_socket; + return (0); +} + +int +vop_stdunp_detach(struct vop_unp_detach_args *ap) +{ + + ap->a_vp->v_socket = NULL; + return (0); +} + /* * vfs default ops * used to fill the vfs function table to get reasonable default return values. Modified: head/sys/kern/vnode_if.src ============================================================================== --- head/sys/kern/vnode_if.src Wed Feb 29 21:11:02 2012 (r232316) +++ head/sys/kern/vnode_if.src Wed Feb 29 21:38:31 2012 (r232317) @@ -640,6 +640,26 @@ vop_advise { IN int advice; }; +%% unp_bind vp E E E + +vop_unp_bind { + IN struct vnode *vp; + IN struct socket *socket; +}; + +%% unp_connect vp L L L + +vop_unp_connect { + IN struct vnode *vp; + OUT struct socket **socket; +}; + +%% unp_detach vp = = = + +vop_unp_detach { + 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, Modified: head/sys/sys/vnode.h ============================================================================== --- head/sys/sys/vnode.h Wed Feb 29 21:11:02 2012 (r232316) +++ head/sys/sys/vnode.h Wed Feb 29 21:38:31 2012 (r232317) @@ -703,6 +703,9 @@ int vop_stdpathconf(struct vop_pathconf_ 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_stdunp_bind(struct vop_unp_bind_args *ap); +int vop_stdunp_connect(struct vop_unp_connect_args *ap); +int vop_stdunp_detach(struct vop_unp_detach_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);