Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/uipc_mbuf.c
Show First 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | |||||
CTASSERT(sizeof(m_assertbuf.m_stailqpkt) == sizeof(m_assertbuf.m_nextpkt)); | CTASSERT(sizeof(m_assertbuf.m_stailqpkt) == sizeof(m_assertbuf.m_nextpkt)); | ||||
#endif | #endif | ||||
/* | /* | ||||
* Attach the cluster from *m to *n, set up m_ext in *n | * Attach the cluster from *m to *n, set up m_ext in *n | ||||
* and bump the refcount of the cluster. | * and bump the refcount of the cluster. | ||||
*/ | */ | ||||
void | void | ||||
mb_dupcl(struct mbuf *n, const struct mbuf *m) | mb_dupcl(struct mbuf *n, struct mbuf *m) | ||||
{ | { | ||||
volatile u_int *refcnt; | |||||
KASSERT(m->m_flags & M_EXT, ("%s: M_EXT not set on %p", __func__, m)); | KASSERT(m->m_flags & M_EXT, ("%s: M_EXT not set on %p", __func__, m)); | ||||
KASSERT(!(n->m_flags & M_EXT), ("%s: M_EXT set on %p", __func__, n)); | KASSERT(!(n->m_flags & M_EXT), ("%s: M_EXT set on %p", __func__, n)); | ||||
switch (m->m_ext.ext_type) { | n->m_ext = m->m_ext; | ||||
case EXT_SFBUF: | n->m_flags |= M_EXT; | ||||
case EXT_SFBUF_NOCACHE: | n->m_flags |= m->m_flags & M_RDONLY; | ||||
sf_ext_ref(m->m_ext.ext_arg1, m->m_ext.ext_arg2); | |||||
break; | /* See if this is the mbuf that holds the embedded refcount. */ | ||||
default: | if (m->m_ext.ext_flags & EXT_FLAG_EMBREF) { | ||||
refcnt = n->m_ext.ext_cnt = &m->m_ext.ext_count; | |||||
n->m_ext.ext_flags &= ~EXT_FLAG_EMBREF; | |||||
} else { | |||||
KASSERT(m->m_ext.ext_cnt != NULL, | KASSERT(m->m_ext.ext_cnt != NULL, | ||||
("%s: no refcounting pointer on %p", __func__, m)); | ("%s: no refcounting pointer on %p", __func__, m)); | ||||
if (*(m->m_ext.ext_cnt) == 1) | refcnt = m->m_ext.ext_cnt; | ||||
*(m->m_ext.ext_cnt) += 1; | |||||
else | |||||
atomic_add_int(m->m_ext.ext_cnt, 1); | |||||
} | } | ||||
n->m_ext = m->m_ext; | if (*refcnt == 1) | ||||
n->m_flags |= M_EXT; | *refcnt += 1; | ||||
n->m_flags |= m->m_flags & M_RDONLY; | else | ||||
atomic_add_int(refcnt, 1); | |||||
} | } | ||||
void | void | ||||
m_demote_pkthdr(struct mbuf *m) | m_demote_pkthdr(struct mbuf *m) | ||||
{ | { | ||||
M_ASSERTPKTHDR(m); | M_ASSERTPKTHDR(m); | ||||
▲ Show 20 Lines • Show All 217 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Make a copy of an mbuf chain starting "off0" bytes from the beginning, | * Make a copy of an mbuf chain starting "off0" bytes from the beginning, | ||||
* continuing for "len" bytes. If len is M_COPYALL, copy to end of mbuf. | * continuing for "len" bytes. If len is M_COPYALL, copy to end of mbuf. | ||||
* The wait parameter is a choice of M_WAITOK/M_NOWAIT from caller. | * The wait parameter is a choice of M_WAITOK/M_NOWAIT from caller. | ||||
* Note that the copy is read-only, because clusters are not copied, | * Note that the copy is read-only, because clusters are not copied, | ||||
* only their reference counts are incremented. | * only their reference counts are incremented. | ||||
*/ | */ | ||||
struct mbuf * | struct mbuf * | ||||
m_copym(const struct mbuf *m, int off0, int len, int wait) | m_copym(struct mbuf *m, int off0, int len, int wait) | ||||
{ | { | ||||
struct mbuf *n, **np; | struct mbuf *n, **np; | ||||
int off = off0; | int off = off0; | ||||
struct mbuf *top; | struct mbuf *top; | ||||
int copyhdr = 0; | int copyhdr = 0; | ||||
KASSERT(off >= 0, ("m_copym, negative off %d", off)); | KASSERT(off >= 0, ("m_copym, negative off %d", off)); | ||||
KASSERT(len >= 0, ("m_copym, negative len %d", len)); | KASSERT(len >= 0, ("m_copym, negative len %d", len)); | ||||
▲ Show 20 Lines • Show All 1,419 Lines • Show Last 20 Lines |