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().
This commit is contained in:
Gleb Smirnoff 2016-01-08 19:03:20 +00:00
parent 638b3cc8ce
commit 829fae9063
5 changed files with 27 additions and 10 deletions

View File

@ -68,6 +68,23 @@ static u_long sb_efficiency = 8; /* parameter for sbreserve() */
static struct mbuf *sbcut_internal(struct sockbuf *sb, int len); static struct mbuf *sbcut_internal(struct sockbuf *sb, int len);
static void sbflush_internal(struct sockbuf *sb); 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". * Mark ready "count" mbufs starting with "m".
*/ */
@ -569,7 +586,7 @@ sblastmbufchk(struct sockbuf *sb, const char *file, int line)
* are discarded and mbufs are compacted where possible. * are discarded and mbufs are compacted where possible.
*/ */
void void
sbappend_locked(struct sockbuf *sb, struct mbuf *m) sbappend_locked(struct sockbuf *sb, struct mbuf *m, int flags)
{ {
struct mbuf *n; struct mbuf *n;
@ -577,7 +594,7 @@ sbappend_locked(struct sockbuf *sb, struct mbuf *m)
if (m == 0) if (m == 0)
return; return;
m_clrprotoflags(m); sbm_clrprotoflags(m, flags);
SBLASTRECORDCHK(sb); SBLASTRECORDCHK(sb);
n = sb->sb_mb; n = sb->sb_mb;
if (n) { if (n) {
@ -620,11 +637,11 @@ sbappend_locked(struct sockbuf *sb, struct mbuf *m)
* are discarded and mbufs are compacted where possible. * are discarded and mbufs are compacted where possible.
*/ */
void void
sbappend(struct sockbuf *sb, struct mbuf *m) sbappend(struct sockbuf *sb, struct mbuf *m, int flags)
{ {
SOCKBUF_LOCK(sb); SOCKBUF_LOCK(sb);
sbappend_locked(sb, m); sbappend_locked(sb, m, flags);
SOCKBUF_UNLOCK(sb); SOCKBUF_UNLOCK(sb);
} }

View File

@ -981,7 +981,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
control)) control))
control = NULL; control = NULL;
} else } else
sbappend_locked(&so2->so_rcv, m); sbappend_locked(&so2->so_rcv, m, flags);
break; break;
case SOCK_SEQPACKET: { case SOCK_SEQPACKET: {

View File

@ -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 */ /* 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; m = NULL;
if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_SENDING)) { 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; error = ENOBUFS;
} else { } else {
/* Append packet to the socket receive queue */ /* Append packet to the socket receive queue */
sbappend(&pcb->so->so_rcv, m0); sbappend(&pcb->so->so_rcv, m0, 0);
m0 = NULL; m0 = NULL;
sorwakeup(pcb->so); sorwakeup(pcb->so);

View File

@ -242,7 +242,7 @@ sdp_sock_queue_rcv_mb(struct socket *sk, struct mbuf *mb)
SOCKBUF_LOCK(&sk->so_rcv); SOCKBUF_LOCK(&sk->so_rcv);
if (unlikely(h->flags & SDP_OOB_PRES)) if (unlikely(h->flags & SDP_OOB_PRES))
sdp_urg(ssk, mb); sdp_urg(ssk, mb);
sbappend_locked(&sk->so_rcv, mb); sbappend_locked(&sk->so_rcv, mb, 0);
sorwakeup_locked(sk); sorwakeup_locked(sk);
return mb; return mb;
} }

View File

@ -129,8 +129,8 @@ struct sockbuf {
#define M_BLOCKED M_PROTO2 /* M_NOTREADY in front of m */ #define M_BLOCKED M_PROTO2 /* M_NOTREADY in front of m */
#define M_NOTAVAIL (M_NOTREADY | M_BLOCKED) #define M_NOTAVAIL (M_NOTREADY | M_BLOCKED)
void sbappend(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); void sbappend_locked(struct sockbuf *sb, struct mbuf *m, int flags);
void sbappendstream(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); void sbappendstream_locked(struct sockbuf *sb, struct mbuf *m, int flags);
int sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa, int sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,