summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/sys_generic.c4
-rw-r--r--sys/kern/uipc_socket.c32
-rw-r--r--sys/kern/uipc_socket2.c52
-rw-r--r--sys/kern/uipc_usrreq.c10
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);