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),
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to