svn commit: r331847 - stable/11/sys/kern
Andriy Voskoboinyk
avos at FreeBSD.org
Sat Mar 31 17:28:32 UTC 2018
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);
}
More information about the svn-src-stable-11
mailing list