Date: Sat, 31 Mar 2018 17:28:31 +0000 (UTC) From: Andriy Voskoboinyk <avos@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r331847 - stable/11/sys/kern Message-ID: <201803311728.w2VHSV1b099379@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avos Date: Sat Mar 31 17:28:30 2018 New Revision: 331847 URL: https://svnweb.freebsd.org/changeset/base/331847 Log: MFC r324673: mbuf(9): unbreak m_fragment() - Fix it by replacing m_cat() with m_prev->m_next = m_new (m_cat() will try to append data - as a result, there will be no fragmentation). - Move some checks out of the loop. Some variables were renamed (m_final -> m_first, m_new -> m_last) Was previously tested with D4077. Differential Revision: D4090 Modified: stable/11/sys/kern/uipc_mbuf.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/kern/uipc_mbuf.c ============================================================================== --- stable/11/sys/kern/uipc_mbuf.c Sat Mar 31 16:58:02 2018 (r331846) +++ stable/11/sys/kern/uipc_mbuf.c Sat Mar 31 17:28:30 2018 (r331847) @@ -1439,62 +1439,59 @@ bad: struct mbuf * m_fragment(struct mbuf *m0, int how, int length) { - struct mbuf *m_new = NULL, *m_final = NULL; - int progress = 0; + struct mbuf *m_first, *m_last; + int divisor = 255, progress = 0, fraglen; if (!(m0->m_flags & M_PKTHDR)) return (m0); - if ((length == 0) || (length < -2)) + if (length == 0 || length < -2) return (m0); + if (length > MCLBYTES) + length = MCLBYTES; + if (length < 0 && divisor > MCLBYTES) + divisor = MCLBYTES; + if (length == -1) + length = 1 + (arc4random() % divisor); + if (length > 0) + fraglen = length; m_fixhdr(m0); /* Needed sanity check */ - m_final = m_getcl(how, MT_DATA, M_PKTHDR); - - if (m_final == NULL) + m_first = m_getcl(how, MT_DATA, M_PKTHDR); + if (m_first == NULL) goto nospace; - if (m_dup_pkthdr(m_final, m0, how) == 0) + if (m_dup_pkthdr(m_first, m0, how) == 0) goto nospace; - m_new = m_final; + m_last = m_first; - if (length == -1) - length = 1 + (arc4random() & 255); - while (progress < m0->m_pkthdr.len) { - int fraglen; - - if (length > 0) - fraglen = length; - else - fraglen = 1 + (arc4random() & 255); + if (length == -2) + fraglen = 1 + (arc4random() % divisor); if (fraglen > m0->m_pkthdr.len - progress) fraglen = m0->m_pkthdr.len - progress; - if (fraglen > MCLBYTES) - fraglen = MCLBYTES; - - if (m_new == NULL) { - m_new = m_getcl(how, MT_DATA, 0); + if (progress != 0) { + struct mbuf *m_new = m_getcl(how, MT_DATA, 0); if (m_new == NULL) goto nospace; + + m_last->m_next = m_new; + m_last = m_new; } - m_copydata(m0, progress, fraglen, mtod(m_new, caddr_t)); + m_copydata(m0, progress, fraglen, mtod(m_last, caddr_t)); progress += fraglen; - m_new->m_len = fraglen; - if (m_new != m_final) - m_cat(m_final, m_new); - m_new = NULL; + m_last->m_len = fraglen; } m_freem(m0); - m0 = m_final; + m0 = m_first; return (m0); nospace: - if (m_final) - m_freem(m_final); + if (m_first) + m_freem(m_first); /* Return the original chain on failure */ return (m0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803311728.w2VHSV1b099379>