Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/kern/uipc_socket.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/kern/uipc_socket.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.223 retrieving revision 1.229 diff -u -p -r1.223 -r1.229 --- src/sys/kern/uipc_socket.c 2014/05/18 14:46:15 1.223 +++ src/sys/kern/uipc_socket.c 2014/07/31 03:39:35 1.229 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_socket.c,v 1.223 2014/05/18 14:46:15 rmind Exp $ */ +/* $NetBSD: uipc_socket.c,v 1.229 2014/07/31 03:39:35 rtr Exp $ */ /*- * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.223 2014/05/18 14:46:15 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.229 2014/07/31 03:39:35 rtr Exp $"); #include "opt_compat_netbsd.h" #include "opt_sock_counters.h" @@ -490,7 +490,7 @@ soinit1(void) * * => Caller may specify another socket for lock sharing (must not be held). * => Returns the new socket without lock held. -*/ + */ int socreate(int dom, struct socket **aso, int type, int proto, struct lwp *l, struct socket *lockso) @@ -538,20 +538,23 @@ socreate(int dom, struct socket **aso, i uid = kauth_cred_geteuid(l->l_cred); so->so_uidinfo = uid_find(uid); so->so_cpid = l->l_proc->p_pid; - if (lockso != NULL) { - /* Caller wants us to share a lock. */ + + /* + * Lock assigned and taken during PCB attach, unless we share + * the lock with another socket, e.g. socketpair(2) case. + */ + if (lockso) { lock = lockso->so_lock; so->so_lock = lock; mutex_obj_hold(lock); - /* XXX Why is this not solock, to match sounlock? */ mutex_enter(lock); - } else { - /* Lock assigned and taken during PRU_ATTACH. */ } - error = (*prp->pr_usrreqs->pr_generic)(so, PRU_ATTACH, NULL, - (struct mbuf *)(long)proto, NULL, l); + + /* Attach the PCB (returns with the socket lock held). */ + error = (*prp->pr_usrreqs->pr_attach)(so, proto); KASSERT(solocked(so)); - if (error != 0) { + + if (error) { KASSERT(so->so_pcb == NULL); so->so_state |= SS_NOFDREF; sofree(so); @@ -559,6 +562,7 @@ socreate(int dom, struct socket **aso, i } so->so_cred = kauth_cred_dup(l->l_cred); sounlock(so); + *aso = so; return 0; } @@ -625,8 +629,7 @@ sobind(struct socket *so, struct mbuf *n int error; solock(so); - error = (*so->so_proto->pr_usrreqs->pr_generic)(so, - PRU_BIND, NULL, nam, NULL, l); + error = (*so->so_proto->pr_usrreqs->pr_bind)(so, nam); sounlock(so); return error; } @@ -642,8 +645,7 @@ solisten(struct socket *so, int backlog, sounlock(so); return EINVAL; } - error = (*so->so_proto->pr_usrreqs->pr_generic)(so, - PRU_LISTEN, NULL, NULL, NULL, l); + error = (*so->so_proto->pr_usrreqs->pr_listen)(so); if (error != 0) { sounlock(so); return error; @@ -752,10 +754,8 @@ soclose(struct socket *so) } drop: if (so->so_pcb) { - int error2 = (*so->so_proto->pr_usrreqs->pr_generic)(so, - PRU_DETACH, NULL, NULL, NULL, NULL); - if (error == 0) - error = error2; + KASSERT(solocked(so)); + (*so->so_proto->pr_usrreqs->pr_detach)(so); } discard: KASSERT((so->so_state & SS_NOFDREF) == 0); @@ -800,8 +800,7 @@ soaccept(struct socket *so, struct mbuf so->so_state &= ~SS_NOFDREF; if ((so->so_state & SS_ISDISCONNECTED) == 0 || (so->so_proto->pr_flags & PR_ABRTACPTDIS) == 0) - error = (*so->so_proto->pr_usrreqs->pr_generic)(so, - PRU_ACCEPT, NULL, nam, NULL, NULL); + error = (*so->so_proto->pr_usrreqs->pr_accept)(so, nam); else error = ECONNABORTED; @@ -828,8 +827,7 @@ soconnect(struct socket *so, struct mbuf (error = sodisconnect(so)))) error = EISCONN; else - error = (*so->so_proto->pr_usrreqs->pr_generic)(so, - PRU_CONNECT, NULL, nam, NULL, l); + error = (*so->so_proto->pr_usrreqs->pr_connect)(so, nam); return error; } @@ -855,8 +853,7 @@ sodisconnect(struct socket *so) } else if (so->so_state & SS_ISDISCONNECTING) { error = EALREADY; } else { - error = (*so->so_proto->pr_usrreqs->pr_generic)(so, - PRU_DISCONNECT, NULL, NULL, NULL, NULL); + error = (*so->so_proto->pr_usrreqs->pr_disconnect)(so); } return (error); } @@ -1052,9 +1049,12 @@ sosend(struct socket *so, struct mbuf *a so->so_options |= SO_DONTROUTE; if (resid > 0) so->so_state |= SS_MORETOCOME; - error = (*so->so_proto->pr_usrreqs->pr_generic)(so, - (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND, - top, addr, control, curlwp); + if (flags & MSG_OOB) + error = (*so->so_proto->pr_usrreqs->pr_sendoob)(so, + top, control); + else + error = (*so->so_proto->pr_usrreqs->pr_generic)(so, + PRU_SEND, top, addr, control, curlwp); if (dontroute) so->so_options &= ~SO_DONTROUTE; if (resid > 0) @@ -1166,8 +1166,7 @@ soreceive(struct socket *so, struct mbuf if (flags & MSG_OOB) { m = m_get(M_WAIT, MT_DATA); solock(so); - error = (*pr->pr_usrreqs->pr_generic)(so, PRU_RCVOOB, m, - (struct mbuf *)(long)(flags & MSG_PEEK), NULL, l); + error = (*pr->pr_usrreqs->pr_recvoob)(so, m, flags & MSG_PEEK); sounlock(so); if (error) goto bad; @@ -1611,8 +1610,7 @@ soshutdown(struct socket *so, int how) error = 0; } if (how == SHUT_WR || how == SHUT_RDWR) - error = (*pr->pr_usrreqs->pr_generic)(so, - PRU_SHUTDOWN, NULL, NULL, NULL, NULL); + error = (*pr->pr_usrreqs->pr_shutdown)(so); return error; }