* imported m_collapse()
* added an expected header dependency in rman.h git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28466 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -114,6 +114,7 @@ void m_move_pkthdr(struct mbuf *, struct mbuf *);
|
|||||||
u_int m_length(struct mbuf *m, struct mbuf **last);
|
u_int m_length(struct mbuf *m, struct mbuf **last);
|
||||||
u_int m_fixhdr(struct mbuf *m);
|
u_int m_fixhdr(struct mbuf *m);
|
||||||
void m_cat(struct mbuf *m, struct mbuf *n);
|
void m_cat(struct mbuf *m, struct mbuf *n);
|
||||||
|
struct mbuf *m_collapse(struct mbuf *m, int how, int maxfrags);
|
||||||
void m_copydata(const struct mbuf *m, int off, int len, caddr_t cp);
|
void m_copydata(const struct mbuf *m, int off, int len, caddr_t cp);
|
||||||
|
|
||||||
struct ifnet;
|
struct ifnet;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
|
#include <machine/resource.h>
|
||||||
|
|
||||||
|
|
||||||
#define RF_ACTIVE 0x0002
|
#define RF_ACTIVE 0x0002
|
||||||
|
|||||||
@@ -520,3 +520,89 @@ m_copyback(struct mbuf *m0, int off, int len, caddr_t cp)
|
|||||||
out: if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
|
out: if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
|
||||||
m->m_pkthdr.len = totlen;
|
m->m_pkthdr.len = totlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defragment an mbuf chain, returning at most maxfrags separate
|
||||||
|
* mbufs+clusters. If this is not possible NULL is returned and
|
||||||
|
* the original mbuf chain is left in it's present (potentially
|
||||||
|
* modified) state. We use two techniques: collapsing consecutive
|
||||||
|
* mbufs and replacing consecutive mbufs by a cluster.
|
||||||
|
*
|
||||||
|
* NB: this should really be named m_defrag but that name is taken
|
||||||
|
*/
|
||||||
|
struct mbuf *
|
||||||
|
m_collapse(struct mbuf *m0, int how, int maxfrags)
|
||||||
|
{
|
||||||
|
struct mbuf *m, *n, *n2, **prev;
|
||||||
|
u_int curfrags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the current number of frags.
|
||||||
|
*/
|
||||||
|
curfrags = 0;
|
||||||
|
for (m = m0; m != NULL; m = m->m_next)
|
||||||
|
curfrags++;
|
||||||
|
/*
|
||||||
|
* First, try to collapse mbufs. Note that we always collapse
|
||||||
|
* towards the front so we don't need to deal with moving the
|
||||||
|
* pkthdr. This may be suboptimal if the first mbuf has much
|
||||||
|
* less data than the following.
|
||||||
|
*/
|
||||||
|
m = m0;
|
||||||
|
again:
|
||||||
|
for (;;) {
|
||||||
|
n = m->m_next;
|
||||||
|
if (n == NULL)
|
||||||
|
break;
|
||||||
|
if ((m->m_flags & M_RDONLY) == 0 &&
|
||||||
|
n->m_len < M_TRAILINGSPACE(m)) {
|
||||||
|
bcopy(mtod(n, void *), mtod(m, char *) + m->m_len,
|
||||||
|
n->m_len);
|
||||||
|
m->m_len += n->m_len;
|
||||||
|
m->m_next = n->m_next;
|
||||||
|
m_free(n);
|
||||||
|
if (--curfrags <= maxfrags)
|
||||||
|
return m0;
|
||||||
|
} else
|
||||||
|
m = n;
|
||||||
|
}
|
||||||
|
KASSERT(maxfrags > 1,
|
||||||
|
("maxfrags %u, but normal collapse failed", maxfrags));
|
||||||
|
/*
|
||||||
|
* Collapse consecutive mbufs to a cluster.
|
||||||
|
*/
|
||||||
|
prev = &m0->m_next; /* NB: not the first mbuf */
|
||||||
|
while ((n = *prev) != NULL) {
|
||||||
|
if ((n2 = n->m_next) != NULL &&
|
||||||
|
n->m_len + n2->m_len < MCLBYTES) {
|
||||||
|
m = m_getcl(how, MT_DATA, 0);
|
||||||
|
if (m == NULL)
|
||||||
|
goto bad;
|
||||||
|
bcopy(mtod(n, void *), mtod(m, void *), n->m_len);
|
||||||
|
bcopy(mtod(n2, void *), mtod(m, char *) + n->m_len,
|
||||||
|
n2->m_len);
|
||||||
|
m->m_len = n->m_len + n2->m_len;
|
||||||
|
m->m_next = n2->m_next;
|
||||||
|
*prev = m;
|
||||||
|
m_free(n);
|
||||||
|
m_free(n2);
|
||||||
|
if (--curfrags <= maxfrags) /* +1 cl -2 mbufs */
|
||||||
|
return m0;
|
||||||
|
/*
|
||||||
|
* Still not there, try the normal collapse
|
||||||
|
* again before we allocate another cluster.
|
||||||
|
*/
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
prev = &n->m_next;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* No place where we can collapse to a cluster; punt.
|
||||||
|
* This can occur if, for example, you request 2 frags
|
||||||
|
* but the packet requires that both be clusters (we
|
||||||
|
* never reallocate the first mbuf to avoid moving the
|
||||||
|
* packet header).
|
||||||
|
*/
|
||||||
|
bad:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user