Revert r274494, r274712, r275955 and provide extra comments explaining

why there could appear a zero-sized mbufs in socket buffers.

A proper fix would be to divorce record socket buffers and stream
socket buffers, and divorce pru_send that accepts normal data from
pru_send that accepts control data.
This commit is contained in:
glebius 2014-12-20 22:12:04 +00:00
parent 17a1543435
commit 50e87fd952
2 changed files with 21 additions and 6 deletions

View File

@ -640,9 +640,6 @@ sbappendstream_locked(struct sockbuf *sb, struct mbuf *m, int flags)
{ {
SOCKBUF_LOCK_ASSERT(sb); SOCKBUF_LOCK_ASSERT(sb);
if (m == NULL)
return;
KASSERT(m->m_nextpkt == NULL,("sbappendstream 0")); KASSERT(m->m_nextpkt == NULL,("sbappendstream 0"));
KASSERT(sb->sb_mb == sb->sb_lastrecord,("sbappendstream 1")); KASSERT(sb->sb_mb == sb->sb_lastrecord,("sbappendstream 1"));
@ -1065,6 +1062,21 @@ sbcut_internal(struct sockbuf *sb, int len)
m = n; m = n;
} }
} }
/*
* Free any zero-length mbufs from the buffer.
* For SOCK_DGRAM sockets such mbufs represent empty records.
* XXX: For SOCK_STREAM sockets such mbufs can appear in the buffer,
* when sosend_generic() needs to send only control data.
*/
while (m && m->m_len == 0) {
struct mbuf *n;
sbfree(sb, m);
n = m->m_next;
m->m_next = mfree;
mfree = m;
m = n;
}
if (m) { if (m) {
sb->sb_mb = m; sb->sb_mb = m;
m->m_nextpkt = next; m->m_nextpkt = next;

View File

@ -1310,11 +1310,14 @@ restart:
resid = 0; resid = 0;
if (flags & MSG_EOR) if (flags & MSG_EOR)
top->m_flags |= M_EOR; top->m_flags |= M_EOR;
} else if (resid > 0) { } else {
/* /*
* Copy the data from userland into a mbuf * Copy the data from userland into a mbuf
* chain. If no data is to be copied in, * chain. If resid is 0, which can happen
* a single empty mbuf is returned. * only if we have control to send, then
* a single empty mbuf is returned. This
* is a workaround to prevent protocol send
* methods to panic.
*/ */
top = m_uiotombuf(uio, M_WAITOK, space, top = m_uiotombuf(uio, M_WAITOK, space,
(atomic ? max_hdr : 0), (atomic ? max_hdr : 0),