diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/sys_generic.c | 4 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 32 | ||||
-rw-r--r-- | sys/kern/uipc_socket2.c | 52 | ||||
-rw-r--r-- | sys/kern/uipc_usrreq.c | 10 |
4 files changed, 57 insertions, 41 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index b1d3f7b6951..8afc08f8d17 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_generic.c,v 1.114 2017/01/24 00:58:55 mpi Exp $ */ +/* $OpenBSD: sys_generic.c,v 1.115 2017/06/26 09:32:31 mpi Exp $ */ /* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */ /* @@ -799,7 +799,7 @@ selwakeup(struct selinfo *sip) struct proc *p; int s; - KNOTE(&sip->si_note, 0); + KNOTE(&sip->si_note, NOTE_SUBMIT); if (sip->si_seltid == 0) return; if (sip->si_flags & SI_COLL) { diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 82b14796a21..dfdc62b78b4 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.188 2017/06/20 17:13:21 bluhm Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.189 2017/06/26 09:32:31 mpi Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -216,7 +216,7 @@ sofree(struct socket *so) so->so_sp = NULL; } #endif /* SOCKET_SPLICE */ - sbrelease(&so->so_snd); + sbrelease(so, &so->so_snd); sorflush(so); pool_put(&socket_pool, so); } @@ -440,7 +440,7 @@ restart: } else if (addr == 0) snderr(EDESTADDRREQ); } - space = sbspace(&so->so_snd); + space = sbspace(so, &so->so_snd); if (flags & MSG_OOB) space += 1024; if ((atomic && resid > so->so_snd.sb_hiwat) || @@ -1041,7 +1041,7 @@ sorflush(struct socket *so) struct sockbuf *sb = &so->so_rcv; struct protosw *pr = so->so_proto; sa_family_t af = pr->pr_domain->dom_family; - struct sockbuf asb; + struct socket aso; sb->sb_flags |= SB_NOINTR; sblock(sb, M_WAITOK, @@ -1049,16 +1049,17 @@ sorflush(struct socket *so) &netlock : NULL); socantrcvmore(so); sbunlock(sb); - asb = *sb; + aso.so_proto = pr; + aso.so_rcv = *sb; memset(sb, 0, sizeof (*sb)); /* XXX - the memset stomps all over so_rcv */ - if (asb.sb_flags & SB_KNOTE) { - sb->sb_sel.si_note = asb.sb_sel.si_note; + if (aso.so_rcv.sb_flags & SB_KNOTE) { + sb->sb_sel.si_note = aso.so_rcv.sb_sel.si_note; sb->sb_flags = SB_KNOTE; } if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose) - (*pr->pr_domain->dom_dispose)(asb.sb_mb); - sbrelease(&asb); + (*pr->pr_domain->dom_dispose)(aso.so_rcv.sb_mb); + sbrelease(&aso, &aso.so_rcv); } #ifdef SOCKET_SPLICE @@ -1270,7 +1271,7 @@ somove(struct socket *so, int wait) maxreached = 1; } } - space = sbspace(&sosp->so_snd); + space = sbspace(sosp, &sosp->so_snd); if (so->so_oobmark && so->so_oobmark < len && so->so_oobmark < space + 1024) space += 1024; @@ -1635,7 +1636,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0) goto bad; } if (sbcheckreserve(cnt, so->so_snd.sb_wat) || - sbreserve(&so->so_snd, cnt)) { + sbreserve(so, &so->so_snd, cnt)) { error = ENOBUFS; goto bad; } @@ -1648,7 +1649,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0) goto bad; } if (sbcheckreserve(cnt, so->so_rcv.sb_wat) || - sbreserve(&so->so_rcv, cnt)) { + sbreserve(so, &so->so_rcv, cnt)) { error = ENOBUFS; goto bad; } @@ -1990,8 +1991,13 @@ int filt_sowrite(struct knote *kn, long hint) { struct socket *so = kn->kn_fp->f_data; + int s; - kn->kn_data = sbspace(&so->so_snd); + if (!(hint & NOTE_SUBMIT)) + s = solock(so); + kn->kn_data = sbspace(so, &so->so_snd); + if (!(hint & NOTE_SUBMIT)) + sounlock(s); if (so->so_state & SS_CANTSENDMORE) { kn->kn_flags |= EV_EOF; kn->kn_fflags = so->so_error; diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 0ba476bcf51..65c5dd74f65 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket2.c,v 1.78 2017/06/07 13:41:02 mpi Exp $ */ +/* $OpenBSD: uipc_socket2.c,v 1.79 2017/06/26 09:32:31 mpi Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* @@ -436,9 +436,9 @@ int soreserve(struct socket *so, u_long sndcc, u_long rcvcc) { - if (sbreserve(&so->so_snd, sndcc)) + if (sbreserve(so, &so->so_snd, sndcc)) goto bad; - if (sbreserve(&so->so_rcv, rcvcc)) + if (sbreserve(so, &so->so_rcv, rcvcc)) goto bad2; so->so_snd.sb_wat = sndcc; so->so_rcv.sb_wat = rcvcc; @@ -450,7 +450,7 @@ soreserve(struct socket *so, u_long sndcc, u_long rcvcc) so->so_snd.sb_lowat = so->so_snd.sb_hiwat; return (0); bad2: - sbrelease(&so->so_snd); + sbrelease(so, &so->so_snd); bad: return (ENOBUFS); } @@ -461,8 +461,10 @@ bad: * if buffering efficiency is near the normal case. */ int -sbreserve(struct sockbuf *sb, u_long cc) +sbreserve(struct socket *so, struct sockbuf *sb, u_long cc) { + KASSERT(sb == &so->so_rcv || sb == &so->so_snd); + soassertlocked(so); if (cc == 0 || cc > sb_max) return (1); @@ -503,10 +505,10 @@ sbchecklowmem(void) * Free mbufs held by a socket, and reserved mbuf space. */ void -sbrelease(struct sockbuf *sb) +sbrelease(struct socket *so, struct sockbuf *sb) { - sbflush(sb); + sbflush(so, sb); sb->sb_hiwat = sb->sb_mbmax = 0; } @@ -597,7 +599,7 @@ do { \ * discarded and mbufs are compacted where possible. */ void -sbappend(struct sockbuf *sb, struct mbuf *m) +sbappend(struct socket *so, struct sockbuf *sb, struct mbuf *m) { struct mbuf *n; @@ -614,7 +616,7 @@ sbappend(struct sockbuf *sb, struct mbuf *m) */ do { if (n->m_flags & M_EOR) { - sbappendrecord(sb, m); /* XXXXXX!!!! */ + sbappendrecord(so, sb, m); /* XXXXXX!!!! */ return; } } while (n->m_next && (n = n->m_next)); @@ -635,9 +637,10 @@ sbappend(struct sockbuf *sb, struct mbuf *m) * in the socket buffer, that is, a stream protocol (such as TCP). */ void -sbappendstream(struct sockbuf *sb, struct mbuf *m) +sbappendstream(struct socket *so, struct sockbuf *sb, struct mbuf *m) { - + KASSERT(sb == &so->so_rcv || sb == &so->so_snd); + soassertlocked(so); KDASSERT(m->m_nextpkt == NULL); KASSERT(sb->sb_mb == sb->sb_lastrecord); @@ -679,10 +682,13 @@ sbcheck(struct sockbuf *sb) * begins a new record. */ void -sbappendrecord(struct sockbuf *sb, struct mbuf *m0) +sbappendrecord(struct socket *so, struct sockbuf *sb, struct mbuf *m0) { struct mbuf *m; + KASSERT(sb == &so->so_rcv || sb == &so->so_snd); + soassertlocked(so); + if (m0 == NULL) return; @@ -759,8 +765,8 @@ sbinsertoob(struct sockbuf *sb, struct mbuf *m0) * Returns 0 if no space in sockbuf or insufficient mbufs. */ int -sbappendaddr(struct sockbuf *sb, struct sockaddr *asa, struct mbuf *m0, - struct mbuf *control) +sbappendaddr(struct socket *so, struct sockbuf *sb, struct sockaddr *asa, + struct mbuf *m0, struct mbuf *control) { struct mbuf *m, *n, *nlast; int space = asa->sa_len; @@ -774,7 +780,7 @@ sbappendaddr(struct sockbuf *sb, struct sockaddr *asa, struct mbuf *m0, if (n->m_next == NULL) /* keep pointer to last control buf */ break; } - if (space > sbspace(sb)) + if (space > sbspace(so, sb)) return (0); if (asa->sa_len > MLEN) return (0); @@ -806,7 +812,8 @@ sbappendaddr(struct sockbuf *sb, struct sockaddr *asa, struct mbuf *m0, } int -sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control) +sbappendcontrol(struct socket *so, struct sockbuf *sb, struct mbuf *m0, + struct mbuf *control) { struct mbuf *m, *mlast, *n; int space = 0; @@ -821,7 +828,7 @@ sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control) n = m; /* save pointer to last control buffer */ for (m = m0; m; m = m->m_next) space += m->m_len; - if (space > sbspace(sb)) + if (space > sbspace(so, sb)) return (0); n->m_next = m0; /* concatenate data to control */ @@ -902,13 +909,13 @@ sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n) * Check that all resources are reclaimed. */ void -sbflush(struct sockbuf *sb) +sbflush(struct socket *so, struct sockbuf *sb) { - + KASSERT(sb == &so->so_rcv || sb == &so->so_snd); KASSERT((sb->sb_flags & SB_LOCK) == 0); while (sb->sb_mbcnt) - sbdrop(sb, (int)sb->sb_cc); + sbdrop(so, sb, (int)sb->sb_cc); KASSERT(sb->sb_cc == 0); KASSERT(sb->sb_datacc == 0); @@ -921,11 +928,14 @@ sbflush(struct sockbuf *sb) * Drop data from (the front of) a sockbuf. */ void -sbdrop(struct sockbuf *sb, int len) +sbdrop(struct socket *so, struct sockbuf *sb, int len) { struct mbuf *m, *mn; struct mbuf *next; + KASSERT(sb == &so->so_rcv || sb == &so->so_snd); + soassertlocked(so); + next = (m = sb->sb_mb) ? m->m_nextpkt : 0; while (len > 0) { if (m == NULL) { diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 9a6d192ac62..d2df74e3236 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_usrreq.c,v 1.117 2017/03/13 20:18:21 claudio Exp $ */ +/* $OpenBSD: uipc_usrreq.c,v 1.118 2017/06/26 09:32:31 mpi Exp $ */ /* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */ /* @@ -222,7 +222,7 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, from = mtod(unp->unp_addr, struct sockaddr *); else from = &sun_noname; - if (sbappendaddr(&so2->so_rcv, from, m, control)) { + if (sbappendaddr(so2, &so2->so_rcv, from, m, control)) { sorwakeup(so2); m = NULL; control = NULL; @@ -252,16 +252,16 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, * Wake up readers. */ if (control) { - if (sbappendcontrol(rcv, m, control)) + if (sbappendcontrol(so2, rcv, m, control)) control = NULL; else { error = ENOBUFS; break; } } else if (so->so_type == SOCK_SEQPACKET) - sbappendrecord(rcv, m); + sbappendrecord(so2, rcv, m); else - sbappend(rcv, m); + sbappend(so2, rcv, m); snd->sb_mbcnt = rcv->sb_mbcnt; snd->sb_cc = rcv->sb_cc; sorwakeup(so2); |