aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2016-01-08 19:03:20 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2016-01-08 19:03:20 +0000
commit829fae9063685b393b1fc5670abd9c0d2c3686a1 (patch)
tree7e34220d682ecdb8ec0c873042ddf508bd1c612c
parent638b3cc8ce1f229dd1b71e0fdc7e4a5b940b6f2d (diff)
downloadsrc-829fae9063685b393b1fc5670abd9c0d2c3686a1.tar.gz
src-829fae9063685b393b1fc5670abd9c0d2c3686a1.zip
Make it possible for sbappend() to preserve M_NOTREADY on mbufs, just like
sbappendstream() does. Although, M_NOTREADY may appear only on SOCK_STREAM sockets, due to sendfile(2) supporting only the latter, there is a corner case of AF_UNIX/SOCK_STREAM socket, that still uses records for the sake of control data, albeit being stream socket. Provide private version of m_clrprotoflags(), which understands PRUS_NOTREADY, similar to m_demote().
Notes
Notes: svn path=/head/; revision=293432
-rw-r--r--sys/kern/uipc_sockbuf.c25
-rw-r--r--sys/kern/uipc_usrreq.c2
-rw-r--r--sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c4
-rw-r--r--sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c2
-rw-r--r--sys/sys/sockbuf.h4
5 files changed, 27 insertions, 10 deletions
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 243450d0d638..ba77fcaca92a 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -69,6 +69,23 @@ static struct mbuf *sbcut_internal(struct sockbuf *sb, int len);
static void sbflush_internal(struct sockbuf *sb);
/*
+ * Our own version of m_clrprotoflags(), that can preserve M_NOTREADY.
+ */
+static void
+sbm_clrprotoflags(struct mbuf *m, int flags)
+{
+ int mask;
+
+ mask = ~M_PROTOFLAGS;
+ if (flags & PRUS_NOTREADY)
+ mask |= M_NOTREADY;
+ while (m) {
+ m->m_flags &= mask;
+ m = m->m_next;
+ }
+}
+
+/*
* Mark ready "count" mbufs starting with "m".
*/
int
@@ -569,7 +586,7 @@ sblastmbufchk(struct sockbuf *sb, const char *file, int line)
* are discarded and mbufs are compacted where possible.
*/
void
-sbappend_locked(struct sockbuf *sb, struct mbuf *m)
+sbappend_locked(struct sockbuf *sb, struct mbuf *m, int flags)
{
struct mbuf *n;
@@ -577,7 +594,7 @@ sbappend_locked(struct sockbuf *sb, struct mbuf *m)
if (m == 0)
return;
- m_clrprotoflags(m);
+ sbm_clrprotoflags(m, flags);
SBLASTRECORDCHK(sb);
n = sb->sb_mb;
if (n) {
@@ -620,11 +637,11 @@ sbappend_locked(struct sockbuf *sb, struct mbuf *m)
* are discarded and mbufs are compacted where possible.
*/
void
-sbappend(struct sockbuf *sb, struct mbuf *m)
+sbappend(struct sockbuf *sb, struct mbuf *m, int flags)
{
SOCKBUF_LOCK(sb);
- sbappend_locked(sb, m);
+ sbappend_locked(sb, m, flags);
SOCKBUF_UNLOCK(sb);
}
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index efed37b8affb..e455b1096d9a 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -981,7 +981,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
control))
control = NULL;
} else
- sbappend_locked(&so2->so_rcv, m);
+ sbappend_locked(&so2->so_rcv, m, flags);
break;
case SOCK_SEQPACKET: {
diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
index f0cd01e0ab4a..68c5975c0de2 100644
--- a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
+++ b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
@@ -972,7 +972,7 @@ ng_btsocket_rfcomm_send(struct socket *so, int flags, struct mbuf *m,
}
/* Put the packet on the socket's send queue and wakeup RFCOMM task */
- sbappend(&pcb->so->so_snd, m);
+ sbappend(&pcb->so->so_snd, m, flags);
m = NULL;
if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_SENDING)) {
@@ -2396,7 +2396,7 @@ ng_btsocket_rfcomm_receive_uih(ng_btsocket_rfcomm_session_p s, int dlci,
error = ENOBUFS;
} else {
/* Append packet to the socket receive queue */
- sbappend(&pcb->so->so_rcv, m0);
+ sbappend(&pcb->so->so_rcv, m0, 0);
m0 = NULL;
sorwakeup(pcb->so);
diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c
index 0b7821266b64..7c6f6cbd1d87 100644
--- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c
+++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c
@@ -242,7 +242,7 @@ sdp_sock_queue_rcv_mb(struct socket *sk, struct mbuf *mb)
SOCKBUF_LOCK(&sk->so_rcv);
if (unlikely(h->flags & SDP_OOB_PRES))
sdp_urg(ssk, mb);
- sbappend_locked(&sk->so_rcv, mb);
+ sbappend_locked(&sk->so_rcv, mb, 0);
sorwakeup_locked(sk);
return mb;
}
diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h
index 0e3e172d63f7..c6904f65952d 100644
--- a/sys/sys/sockbuf.h
+++ b/sys/sys/sockbuf.h
@@ -129,8 +129,8 @@ struct sockbuf {
#define M_BLOCKED M_PROTO2 /* M_NOTREADY in front of m */
#define M_NOTAVAIL (M_NOTREADY | M_BLOCKED)
-void sbappend(struct sockbuf *sb, struct mbuf *m);
-void sbappend_locked(struct sockbuf *sb, struct mbuf *m);
+void sbappend(struct sockbuf *sb, struct mbuf *m, int flags);
+void sbappend_locked(struct sockbuf *sb, struct mbuf *m, int flags);
void sbappendstream(struct sockbuf *sb, struct mbuf *m, int flags);
void sbappendstream_locked(struct sockbuf *sb, struct mbuf *m, int flags);
int sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,