svn commit: r275968 - head/sys/kern
Gleb Smirnoff
glebius at FreeBSD.org
Sat Dec 20 22:12:05 UTC 2014
Author: glebius
Date: Sat Dec 20 22:12:04 2014
New Revision: 275968
URL: https://svnweb.freebsd.org/changeset/base/275968
Log:
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.
Modified:
head/sys/kern/uipc_sockbuf.c
head/sys/kern/uipc_socket.c
Modified: head/sys/kern/uipc_sockbuf.c
==============================================================================
--- head/sys/kern/uipc_sockbuf.c Sat Dec 20 21:17:28 2014 (r275967)
+++ head/sys/kern/uipc_sockbuf.c Sat Dec 20 22:12:04 2014 (r275968)
@@ -640,9 +640,6 @@ sbappendstream_locked(struct sockbuf *sb
{
SOCKBUF_LOCK_ASSERT(sb);
- if (m == NULL)
- return;
-
KASSERT(m->m_nextpkt == NULL,("sbappendstream 0"));
KASSERT(sb->sb_mb == sb->sb_lastrecord,("sbappendstream 1"));
@@ -1065,6 +1062,21 @@ sbcut_internal(struct sockbuf *sb, int l
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) {
sb->sb_mb = m;
m->m_nextpkt = next;
Modified: head/sys/kern/uipc_socket.c
==============================================================================
--- head/sys/kern/uipc_socket.c Sat Dec 20 21:17:28 2014 (r275967)
+++ head/sys/kern/uipc_socket.c Sat Dec 20 22:12:04 2014 (r275968)
@@ -1310,11 +1310,14 @@ restart:
resid = 0;
if (flags & MSG_EOR)
top->m_flags |= M_EOR;
- } else if (resid > 0) {
+ } else {
/*
* Copy the data from userland into a mbuf
- * chain. If no data is to be copied in,
- * a single empty mbuf is returned.
+ * chain. If resid is 0, which can happen
+ * 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,
(atomic ? max_hdr : 0),
More information about the svn-src-all
mailing list