summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2004-06-17 22:48:11 +0000
committerRobert Watson <rwatson@FreeBSD.org>2004-06-17 22:48:11 +0000
commit9535efc00de36129762534223a2f5782cc5fe472 (patch)
tree743d1903dca8bb885b1a5cafc69c5ea6ff190d62
parentb2c082c98b71834582bad5480fdea168a89691c5 (diff)
Notes
-rw-r--r--sys/fs/fifofs/fifo_vnops.c2
-rw-r--r--sys/fs/portalfs/portal_vnops.c4
-rw-r--r--sys/kern/sys_socket.c20
-rw-r--r--sys/kern/uipc_sockbuf.c24
-rw-r--r--sys/kern/uipc_socket.c39
-rw-r--r--sys/kern/uipc_socket2.c24
-rw-r--r--sys/kern/vfs_aio.c17
-rw-r--r--sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c12
-rw-r--r--sys/netgraph/ng_ksocket.c14
-rw-r--r--sys/netsmb/smb_trantcp.c6
-rw-r--r--sys/nfsserver/nfs_syscalls.c8
11 files changed, 154 insertions, 16 deletions
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
index c35a8a08ba8ca..da9716b4d5187 100644
--- a/sys/fs/fifofs/fifo_vnops.c
+++ b/sys/fs/fifofs/fifo_vnops.c
@@ -431,8 +431,10 @@ fifo_kqfilter(ap)
ap->a_kn->kn_hook = (caddr_t)so;
+ SOCKBUF_LOCK(sb);
SLIST_INSERT_HEAD(&sb->sb_sel.si_note, ap->a_kn, kn_selnext);
sb->sb_flags |= SB_KNOTE;
+ SOCKBUF_UNLOCK(sb);
return (0);
}
diff --git a/sys/fs/portalfs/portal_vnops.c b/sys/fs/portalfs/portal_vnops.c
index 5696c1e9642b6..169fbafe5c43b 100644
--- a/sys/fs/portalfs/portal_vnops.c
+++ b/sys/fs/portalfs/portal_vnops.c
@@ -304,8 +304,12 @@ portal_open(ap)
*/
so->so_rcv.sb_timeo = 0;
so->so_snd.sb_timeo = 0;
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags |= SB_NOINTR;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags |= SB_NOINTR;
+ SOCKBUF_UNLOCK(&so->so_snd);
pcred.pcr_flag = ap->a_mode;
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index a580b43c9ae2a..986edf7ed5b79 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -131,21 +131,41 @@ soo_ioctl(fp, cmd, data, active_cred, td)
switch (cmd) {
case FIONBIO:
+ SOCK_LOCK(so);
if (*(int *)data)
so->so_state |= SS_NBIO;
else
so->so_state &= ~SS_NBIO;
+ SOCK_UNLOCK(so);
return (0);
case FIOASYNC:
+ /*
+ * XXXRW: This code separately acquires SOCK_LOCK(so)
+ * and SOCKBUF_LOCK(&so->so_rcv) even though they are
+ * the same mutex to avoid introducing the assumption
+ * that they are the same.
+ */
if (*(int *)data) {
+ SOCK_LOCK(so);
so->so_state |= SS_ASYNC;
+ SOCK_UNLOCK(so);
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags |= SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags |= SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_snd);
} else {
+ SOCK_LOCK(so);
so->so_state &= ~SS_ASYNC;
+ SOCK_UNLOCK(so);
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags &= ~SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags &= ~SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_snd);
}
return (0);
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 9b02fec7db2b4..c3852535c5c97 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -105,8 +105,10 @@ soisconnecting(so)
register struct socket *so;
{
+ SOCK_LOCK(so);
so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
so->so_state |= SS_ISCONNECTING;
+ SOCK_UNLOCK(so);
}
void
@@ -115,8 +117,10 @@ soisconnected(so)
{
struct socket *head;
+ SOCK_LOCK(so);
so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
so->so_state |= SS_ISCONNECTED;
+ SOCK_UNLOCK(so);
ACCEPT_LOCK();
head = so->so_head;
if (head != NULL && (so->so_qstate & SQ_INCOMP)) {
@@ -132,11 +136,13 @@ soisconnected(so)
wakeup_one(&head->so_timeo);
} else {
ACCEPT_UNLOCK();
+ SOCK_LOCK(so);
so->so_upcall =
head->so_accf->so_accept_filter->accf_callback;
so->so_upcallarg = head->so_accf->so_accept_filter_arg;
so->so_rcv.sb_flags |= SB_UPCALL;
so->so_options &= ~SO_ACCEPTFILTER;
+ SOCK_UNLOCK(so);
so->so_upcall(so, so->so_upcallarg, M_TRYWAIT);
}
return;
@@ -152,8 +158,15 @@ soisdisconnecting(so)
register struct socket *so;
{
+ /*
+ * XXXRW: This code separately acquires SOCK_LOCK(so) and
+ * SOCKBUF_LOCK(&so->so_rcv) even though they are the same mutex to
+ * avoid introducing the assumption that they are the same.
+ */
+ SOCK_LOCK(so);
so->so_state &= ~SS_ISCONNECTING;
so->so_state |= SS_ISDISCONNECTING;
+ SOCK_UNLOCK(so);
SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_state |= SBS_CANTRCVMORE;
SOCKBUF_UNLOCK(&so->so_rcv);
@@ -170,8 +183,15 @@ soisdisconnected(so)
register struct socket *so;
{
+ /*
+ * XXXRW: This code separately acquires SOCK_LOCK(so) and
+ * SOCKBUF_LOCK(&so->so_rcv) even though they are the same mutex to
+ * avoid introducing the assumption that they are the same.
+ */
+ SOCK_LOCK(so);
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
so->so_state |= SS_ISDISCONNECTED;
+ SOCK_UNLOCK(so);
SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_state |= SBS_CANTRCVMORE;
SOCKBUF_UNLOCK(&so->so_rcv);
@@ -400,12 +420,16 @@ soreserve(so, sndcc, rcvcc)
goto bad;
if (sbreserve(&so->so_rcv, rcvcc, so, td) == 0)
goto bad2;
+ SOCKBUF_LOCK(&so->so_rcv);
if (so->so_rcv.sb_lowat == 0)
so->so_rcv.sb_lowat = 1;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
if (so->so_snd.sb_lowat == 0)
so->so_snd.sb_lowat = MCLBYTES;
if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
+ SOCKBUF_UNLOCK(&so->so_snd);
return (0);
bad2:
sbrelease(&so->so_snd, so);
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index fb9043c89f8bd..66061384d32cb 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -277,8 +277,11 @@ solisten(so, backlog, td)
return (error);
}
ACCEPT_LOCK();
- if (TAILQ_EMPTY(&so->so_comp))
+ if (TAILQ_EMPTY(&so->so_comp)) {
+ SOCK_LOCK(so);
so->so_options |= SO_ACCEPTCONN;
+ SOCK_UNLOCK(so);
+ }
if (backlog < 0 || backlog > somaxconn)
backlog = somaxconn;
so->so_qlimit = backlog;
@@ -448,14 +451,13 @@ soaccept(so, nam)
struct socket *so;
struct sockaddr **nam;
{
- int s = splnet();
int error;
- if ((so->so_state & SS_NOFDREF) == 0)
- panic("soaccept: !NOFDREF");
+ SOCK_LOCK(so);
+ KASSERT((so->so_state & SS_NOFDREF) != 0, ("soaccept: !NOFDREF"));
so->so_state &= ~SS_NOFDREF;
+ SOCK_UNLOCK(so);
error = (*so->so_proto->pr_usrreqs->pru_accept)(so, nam);
- splx(s);
return (error);
}
@@ -754,9 +756,11 @@ restart:
break;
}
} while (space > 0 && atomic);
- if (dontroute)
+ if (dontroute) {
+ SOCK_LOCK(so);
so->so_options |= SO_DONTROUTE;
- s = splnet(); /* XXX */
+ SOCK_UNLOCK(so);
+ }
/*
* XXX all the SBS_CANTSENDMORE checks previously
* done could be out of date. We could have recieved
@@ -1396,11 +1400,13 @@ sosetopt(so, sopt)
if (error)
goto bad;
+ SOCK_LOCK(so);
so->so_linger = l.l_linger;
if (l.l_onoff)
so->so_options |= SO_LINGER;
else
so->so_options &= ~SO_LINGER;
+ SOCK_UNLOCK(so);
break;
case SO_DEBUG:
@@ -1418,10 +1424,12 @@ sosetopt(so, sopt)
sizeof optval);
if (error)
goto bad;
+ SOCK_LOCK(so);
if (optval)
so->so_options |= sopt->sopt_name;
else
so->so_options &= ~sopt->sopt_name;
+ SOCK_UNLOCK(so);
break;
case SO_SNDBUF:
@@ -1842,12 +1850,16 @@ sopoll(struct socket *so, int events, struct ucred *active_cred,
(POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM |
POLLRDBAND)) {
selrecord(td, &so->so_rcv.sb_sel);
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags |= SB_SEL;
+ SOCKBUF_UNLOCK(&so->so_rcv);
}
if (events & (POLLOUT | POLLWRNORM)) {
selrecord(td, &so->so_snd.sb_sel);
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags |= SB_SEL;
+ SOCKBUF_UNLOCK(&so->so_snd);
}
}
@@ -1860,7 +1872,6 @@ soo_kqfilter(struct file *fp, struct knote *kn)
{
struct socket *so = kn->kn_fp->f_data;
struct sockbuf *sb;
- int s;
switch (kn->kn_filter) {
case EVFILT_READ:
@@ -1878,10 +1889,10 @@ soo_kqfilter(struct file *fp, struct knote *kn)
return (1);
}
- s = splnet();
+ SOCKBUF_LOCK(sb);
SLIST_INSERT_HEAD(&sb->sb_sel.si_note, kn, kn_selnext);
sb->sb_flags |= SB_KNOTE;
- splx(s);
+ SOCKBUF_UNLOCK(sb);
return (0);
}
@@ -1889,12 +1900,12 @@ static void
filt_sordetach(struct knote *kn)
{
struct socket *so = kn->kn_fp->f_data;
- int s = splnet();
+ SOCKBUF_LOCK(&so->so_rcv);
SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext);
if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note))
so->so_rcv.sb_flags &= ~SB_KNOTE;
- splx(s);
+ SOCKBUF_UNLOCK(&so->so_rcv);
}
/*ARGSUSED*/
@@ -1922,12 +1933,12 @@ static void
filt_sowdetach(struct knote *kn)
{
struct socket *so = kn->kn_fp->f_data;
- int s = splnet();
+ SOCKBUF_LOCK(&so->so_snd);
SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext);
if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note))
so->so_snd.sb_flags &= ~SB_KNOTE;
- splx(s);
+ SOCKBUF_UNLOCK(&so->so_snd);
}
/*ARGSUSED*/
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index 9b02fec7db2b4..c3852535c5c97 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -105,8 +105,10 @@ soisconnecting(so)
register struct socket *so;
{
+ SOCK_LOCK(so);
so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
so->so_state |= SS_ISCONNECTING;
+ SOCK_UNLOCK(so);
}
void
@@ -115,8 +117,10 @@ soisconnected(so)
{
struct socket *head;
+ SOCK_LOCK(so);
so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
so->so_state |= SS_ISCONNECTED;
+ SOCK_UNLOCK(so);
ACCEPT_LOCK();
head = so->so_head;
if (head != NULL && (so->so_qstate & SQ_INCOMP)) {
@@ -132,11 +136,13 @@ soisconnected(so)
wakeup_one(&head->so_timeo);
} else {
ACCEPT_UNLOCK();
+ SOCK_LOCK(so);
so->so_upcall =
head->so_accf->so_accept_filter->accf_callback;
so->so_upcallarg = head->so_accf->so_accept_filter_arg;
so->so_rcv.sb_flags |= SB_UPCALL;
so->so_options &= ~SO_ACCEPTFILTER;
+ SOCK_UNLOCK(so);
so->so_upcall(so, so->so_upcallarg, M_TRYWAIT);
}
return;
@@ -152,8 +158,15 @@ soisdisconnecting(so)
register struct socket *so;
{
+ /*
+ * XXXRW: This code separately acquires SOCK_LOCK(so) and
+ * SOCKBUF_LOCK(&so->so_rcv) even though they are the same mutex to
+ * avoid introducing the assumption that they are the same.
+ */
+ SOCK_LOCK(so);
so->so_state &= ~SS_ISCONNECTING;
so->so_state |= SS_ISDISCONNECTING;
+ SOCK_UNLOCK(so);
SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_state |= SBS_CANTRCVMORE;
SOCKBUF_UNLOCK(&so->so_rcv);
@@ -170,8 +183,15 @@ soisdisconnected(so)
register struct socket *so;
{
+ /*
+ * XXXRW: This code separately acquires SOCK_LOCK(so) and
+ * SOCKBUF_LOCK(&so->so_rcv) even though they are the same mutex to
+ * avoid introducing the assumption that they are the same.
+ */
+ SOCK_LOCK(so);
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
so->so_state |= SS_ISDISCONNECTED;
+ SOCK_UNLOCK(so);
SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_state |= SBS_CANTRCVMORE;
SOCKBUF_UNLOCK(&so->so_rcv);
@@ -400,12 +420,16 @@ soreserve(so, sndcc, rcvcc)
goto bad;
if (sbreserve(&so->so_rcv, rcvcc, so, td) == 0)
goto bad2;
+ SOCKBUF_LOCK(&so->so_rcv);
if (so->so_rcv.sb_lowat == 0)
so->so_rcv.sb_lowat = 1;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
if (so->so_snd.sb_lowat == 0)
so->so_snd.sb_lowat = MCLBYTES;
if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
+ SOCKBUF_UNLOCK(&so->so_snd);
return (0);
bad2:
sbrelease(&so->so_snd, so);
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index 3978203c3c480..a56a54f31da32 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -566,8 +566,12 @@ aio_proc_rundown(void *arg, struct proc *p)
so = fp->f_data;
TAILQ_REMOVE(&so->so_aiojobq, aiocbe, list);
if (TAILQ_EMPTY(&so->so_aiojobq)) {
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags &= ~SB_AIO;
+ SOCKBUF_UNLOCK(&so->so_snd);
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags &= ~SB_AIO;
+ SOCKBUF_UNLOCK(&so->so_rcv);
}
}
TAILQ_REMOVE(&ki->kaio_sockqueue, aiocbe, plist);
@@ -1231,10 +1235,14 @@ aio_swake_cb(struct socket *so, struct sockbuf *sb)
if (sb == &so->so_snd) {
opcode = LIO_WRITE;
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags &= ~SB_AIO;
+ SOCKBUF_UNLOCK(&so->so_snd);
} else {
opcode = LIO_READ;
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags &= ~SB_AIO;
+ SOCKBUF_UNLOCK(&so->so_rcv);
}
for (cb = TAILQ_FIRST(&so->so_aiojobq); cb; cb = cbn) {
@@ -1443,10 +1451,15 @@ no_kqueue:
LIO_WRITE) && (!sowriteable(so)))) {
TAILQ_INSERT_TAIL(&so->so_aiojobq, aiocbe, list);
TAILQ_INSERT_TAIL(&ki->kaio_sockqueue, aiocbe, plist);
- if (opcode == LIO_READ)
+ if (opcode == LIO_READ) {
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags |= SB_AIO;
- else
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ } else {
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags |= SB_AIO;
+ SOCKBUF_UNLOCK(&so->so_snd);
+ }
aiocbe->jobstate = JOBST_JOBQGLOBAL; /* XXX */
ki->kaio_queue_count++;
num_queue_count++;
diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
index 09cb139746d25..c4c29a34eefa5 100644
--- a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
+++ b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
@@ -997,8 +997,12 @@ ng_btsocket_rfcomm_sessions_task(void *ctx, int pending)
/* Close L2CAP socket */
s->l2so->so_upcallarg = NULL;
s->l2so->so_upcall = NULL;
+ SOCKBUF_LOCK(&s->l2so->so_rcv);
s->l2so->so_rcv.sb_flags &= ~SB_UPCALL;
+ SOCKBUF_UNLOCK(&s->l2so->so_rcv);
+ SOCKBUF_LOCK(&s->l2so->so_snd);
s->l2so->so_snd.sb_flags &= ~SB_UPCALL;
+ SOCKBUF_UNLOCK(&s->l2so->so_snd);
soclose(s->l2so);
mtx_unlock(&s->session_mtx);
@@ -1237,8 +1241,12 @@ ng_btsocket_rfcomm_session_create(ng_btsocket_rfcomm_session_p *sp,
/* Prepare L2CAP socket */
l2so->so_upcallarg = NULL;
l2so->so_upcall = ng_btsocket_rfcomm_upcall;
+ SOCKBUF_LOCK(&l2so->so_rcv);
l2so->so_rcv.sb_flags |= SB_UPCALL;
+ SOCKBUF_UNLOCK(&l2so->so_rcv);
+ SOCKBUF_LOCK(&l2so->so_snd);
l2so->so_snd.sb_flags |= SB_UPCALL;
+ SOCKBUF_UNLOCK(&l2so->so_snd);
l2so->so_state |= SS_NBIO;
s->l2so = l2so;
@@ -1317,8 +1325,12 @@ bad:
/* Return L2CAP socket back to its original state */
l2so->so_upcallarg = NULL;
l2so->so_upcall = NULL;
+ SOCKBUF_LOCK(&l2so->so_rcv);
l2so->so_rcv.sb_flags &= ~SB_UPCALL;
+ SOCKBUF_LOCK(&l2so->so_rcv);
+ SOCKBUF_LOCK(&l2so->so_snd);
l2so->so_snd.sb_flags &= ~SB_UPCALL;
+ SOCKBUF_LOCK(&l2so->so_snd);
l2so->so_state &= ~SS_NBIO;
mtx_destroy(&s->session_mtx);
diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c
index f24331889e324..458bbdee41e92 100644
--- a/sys/netgraph/ng_ksocket.c
+++ b/sys/netgraph/ng_ksocket.c
@@ -609,9 +609,15 @@ ng_ksocket_connect(hook_p hook)
/* Add our hook for incoming data and other events */
priv->so->so_upcallarg = (caddr_t)node;
priv->so->so_upcall = ng_ksocket_incoming;
+ SOCKBUF_LOCK(&priv->so->so_rcv);
priv->so->so_rcv.sb_flags |= SB_UPCALL;
+ SOCKBUF_UNLOCK(&priv->so->so_rcv);
+ SOCKBUF_LOCK(&priv->so->so_snd);
priv->so->so_snd.sb_flags |= SB_UPCALL;
+ SOCKBUF_UNLOCK(&priv->so->so_snd);
+ SOCK_LOCK(priv->so);
priv->so->so_state |= SS_NBIO;
+ SOCK_UNLOCK(priv->so);
/*
* --Original comment--
* On a cloned socket we may have already received one or more
@@ -941,8 +947,12 @@ ng_ksocket_shutdown(node_p node)
/* Close our socket (if any) */
if (priv->so != NULL) {
priv->so->so_upcall = NULL;
+ SOCKBUF_LOCK(&priv->so->so_rcv);
priv->so->so_rcv.sb_flags &= ~SB_UPCALL;
+ SOCKBUF_UNLOCK(&priv->so->so_rcv);
+ SOCKBUF_LOCK(&priv->so->so_snd);
priv->so->so_snd.sb_flags &= ~SB_UPCALL;
+ SOCKBUF_UNLOCK(&priv->so->so_snd);
soclose(priv->so);
priv->so = NULL;
}
@@ -1257,8 +1267,12 @@ ng_ksocket_finish_accept(priv_p priv)
so->so_upcallarg = (caddr_t)node;
so->so_upcall = ng_ksocket_incoming;
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags |= SB_UPCALL;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags |= SB_UPCALL;
+ SOCKBUF_UNLOCK(&so->so_snd);
/* Fill in the response data and send it or return it to the caller */
resp_data = (struct ng_ksocket_accept *)resp->data;
diff --git a/sys/netsmb/smb_trantcp.c b/sys/netsmb/smb_trantcp.c
index 5972dee7350b8..5029ad5a1ba64 100644
--- a/sys/netsmb/smb_trantcp.c
+++ b/sys/netsmb/smb_trantcp.c
@@ -238,7 +238,9 @@ nb_connect_in(struct nbpcb *nbp, struct sockaddr_in *to, struct thread *td)
nbp->nbp_tso = so;
so->so_upcallarg = (caddr_t)nbp;
so->so_upcall = nb_upcall;
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags |= SB_UPCALL;
+ SOCKBUF_UNLOCK(&so->so_rcv);
so->so_rcv.sb_timeo = (5 * hz);
so->so_snd.sb_timeo = (5 * hz);
error = soreserve(so, nbp->nbp_sndbuf, nbp->nbp_rcvbuf);
@@ -246,8 +248,12 @@ nb_connect_in(struct nbpcb *nbp, struct sockaddr_in *to, struct thread *td)
goto bad;
nb_setsockopt_int(so, SOL_SOCKET, SO_KEEPALIVE, 1);
nb_setsockopt_int(so, IPPROTO_TCP, TCP_NODELAY, 1);
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags &= ~SB_NOINTR;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags &= ~SB_NOINTR;
+ SOCKBUF_UNLOCK(&so->so_snd);
error = soconnect(so, (struct sockaddr*)to, td);
if (error)
goto bad;
diff --git a/sys/nfsserver/nfs_syscalls.c b/sys/nfsserver/nfs_syscalls.c
index 3c6bd562c8043..d58fce4f6215c 100644
--- a/sys/nfsserver/nfs_syscalls.c
+++ b/sys/nfsserver/nfs_syscalls.c
@@ -263,10 +263,14 @@ nfssvc_addsock(struct file *fp, struct sockaddr *mynam, struct thread *td)
val = 1;
sosetopt(so, &sopt);
}
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags &= ~SB_NOINTR;
so->so_rcv.sb_timeo = 0;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags &= ~SB_NOINTR;
so->so_snd.sb_timeo = 0;
+ SOCKBUF_UNLOCK(&so->so_snd);
slp = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC,
@@ -285,7 +289,9 @@ nfssvc_addsock(struct file *fp, struct sockaddr *mynam, struct thread *td)
s = splnet();
so->so_upcallarg = (caddr_t)slp;
so->so_upcall = nfsrv_rcv;
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags |= SB_UPCALL;
+ SOCKBUF_UNLOCK(&so->so_rcv);
slp->ns_flag = (SLP_VALID | SLP_NEEDQ);
nfsrv_wakenfsd(slp);
splx(s);
@@ -601,7 +607,9 @@ nfsrv_zapsock(struct nfssvc_sock *slp)
NFSD_UNLOCK();
slp->ns_fp = NULL;
so = slp->ns_so;
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags &= ~SB_UPCALL;
+ SOCKBUF_UNLOCK(&so->so_rcv);
so->so_upcall = NULL;
so->so_upcallarg = NULL;
soshutdown(so, SHUT_RDWR);