-.\" $OpenBSD: mbuf.9,v 1.73 2014/07/13 05:23:24 dlg Exp $
+.\" $OpenBSD: mbuf.9,v 1.74 2014/07/13 09:52:48 dlg Exp $
.\"
.\" Copyright (c) 2001 Jean-Jacques Bernard-Gundol <jjbg@openbsd.org>
.\" All rights reserved.
.Fn MCLGET "struct mbuf *m" "int how"
.Ft struct mbuf *
.Fn MCLGETI "struct mbuf *m" "int how" "struct ifnet *ifp" "int len"
-.Fn MEXTADD "struct mbuf *m" "caddr_t buf" "u_int size" "int type" \
+.Fn MEXTADD "struct mbuf *m" "caddr_t buf" "u_int size" "int flags" \
"void (*free)(caddr_t, u_int, void *)" "void *arg"
.Fn M_ALIGN "struct mbuf *m" "int len"
.Fn MH_ALIGN "struct mbuf *m" "int len"
.Fn m_get
for a description of
.Fa how .
-.It Fn MEXTADD "struct mbuf *m" "caddr_t buf" "u_int size" "int type" \
+.It Fn MEXTADD "struct mbuf *m" "caddr_t buf" "u_int size" "int flags" \
"void (*free)(caddr_t, u_int, void *)" "void *arg"
Add pre-allocated storage to the mbuf pointed to by
.Fa m .
-On success, the flag M_EXT is set in the mbuf.
+On success, the flag M_EXT is set in the mbuf, and M_EXTWR if specified in
+.Fa flags ..
.It Fn M_ALIGN "struct mbuf *m" "int len"
Set the
.Fa m_data
-/* $OpenBSD: uipc_mbuf.c,v 1.190 2014/07/09 13:05:45 dlg Exp $ */
+/* $OpenBSD: uipc_mbuf.c,v 1.191 2014/07/13 09:52:48 dlg Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */
/*
static char mclnames[MCLPOOLS][8];
struct pool mclpools[MCLPOOLS];
-int m_clpool(u_int);
+struct pool *m_clpool(u_int);
int max_linkhdr; /* largest link-level header */
int max_protohdr; /* largest protocol header */
return (m);
}
-int
+struct pool *
m_clpool(u_int pktlen)
{
+ struct pool *pp;
int pi;
- for (pi = 0; pi < MCLPOOLS; pi++) {
- if (pktlen <= mclsizes[pi])
- return (pi);
+ for (pi = 0; pi < nitems(mclpools); pi++) {
+ pp = &mclpools[pi];
+ if (pktlen <= pp->pr_size)
+ return (pp);
}
- return (-1);
+ return (NULL);
}
struct mbuf *
m_clget(struct mbuf *m, int how, struct ifnet *ifp, u_int pktlen)
{
struct mbuf *m0 = NULL;
- int pi;
+ struct pool *pp;
+ caddr_t buf;
int s;
- pi = m_clpool(pktlen);
+ pp = m_clpool(pktlen);
#ifdef DIAGNOSTIC
- if (pi == -1)
+ if (pp == NULL)
panic("m_clget: request for %u byte cluster", pktlen);
#endif
}
m = m0;
}
- m->m_ext.ext_buf = pool_get(&mclpools[pi],
- how == M_WAIT ? PR_WAITOK : PR_NOWAIT);
- if (!m->m_ext.ext_buf) {
+ buf = pool_get(pp, how == M_WAIT ? PR_WAITOK : PR_NOWAIT);
+ if (buf == NULL) {
if (m0)
m_freem(m0);
splx(s);
}
splx(s);
- m->m_data = m->m_ext.ext_buf;
- m->m_flags |= M_EXT|M_CLUSTER;
- m->m_ext.ext_size = mclpools[pi].pr_size;
- m->m_ext.ext_free = NULL;
- m->m_ext.ext_arg = &mclpools[pi];
- MCLINITREFERENCE(m);
+ MEXTADD(m, buf, pp->pr_size, M_EXTWR, m_extfree_pool, pp);
return (m);
}
+void
+m_extfree_pool(caddr_t buf, u_int size, void *pp)
+{
+ splassert(IPL_NET);
+ pool_put(pp, buf);
+}
+
struct mbuf *
m_free_unlocked(struct mbuf *m)
{
m->m_ext.ext_prevref;
m->m_ext.ext_prevref->m_ext.ext_nextref =
m->m_ext.ext_nextref;
- } else if (m->m_flags & M_CLUSTER) {
- pool_put(m->m_ext.ext_arg, m->m_ext.ext_buf);
} else if (m->m_ext.ext_free)
(*(m->m_ext.ext_free))(m->m_ext.ext_buf,
m->m_ext.ext_size, m->m_ext.ext_arg);
else
panic("unknown type of extension buffer");
m->m_ext.ext_size = 0;
- m->m_flags &= ~(M_EXT|M_CLUSTER);
+ m->m_flags &= ~(M_EXT|M_EXTWR);
}
void
if (m0->m_flags & M_EXT) {
memcpy(&m->m_ext, &m0->m_ext, sizeof(struct mbuf_ext));
MCLINITREFERENCE(m);
- m->m_flags |= M_EXT|M_CLUSTER;
+ m->m_flags |= m0->m_flags & (M_EXT|M_EXTWR);
m->m_data = m->m_ext.ext_buf;
} else {
m->m_data = m->m_pktdat;
}
m->m_pkthdr.len = m->m_len = m0->m_len;
- m0->m_flags &= ~(M_EXT|M_CLUSTER); /* cluster is gone */
+ m0->m_flags &= ~(M_EXT|M_EXTWR); /* cluster is gone */
m_free(m0);
return (0);
KASSERT(from->m_flags & M_PKTHDR);
- to->m_flags = (to->m_flags & (M_EXT | M_CLUSTER));
+ to->m_flags = (to->m_flags & (M_EXT | M_EXTWR));
to->m_flags |= (from->m_flags & M_COPYFLAGS);
to->m_pkthdr = from->m_pkthdr;
-/* $OpenBSD: mbuf.h,v 1.179 2014/07/09 13:05:45 dlg Exp $ */
+/* $OpenBSD: mbuf.h,v 1.180 2014/07/13 09:52:48 dlg Exp $ */
/* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */
/*
#define M_EXT 0x0001 /* has associated external storage */
#define M_PKTHDR 0x0002 /* start of record */
#define M_EOR 0x0004 /* end of record */
-#define M_CLUSTER 0x0008 /* external storage is a cluster */
+#define M_EXTWR 0x0008 /* external storage is writable */
#define M_PROTO1 0x0010 /* protocol-specific */
/* mbuf pkthdr flags, also in m_flags */
#ifdef _KERNEL
#define M_BITS \
- ("\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_CLUSTER\5M_PROTO1\6M_VLANTAG\7M_LOOP" \
+ ("\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_EXTWR\5M_PROTO1\6M_VLANTAG\7M_LOOP" \
"\10M_FILDROP\11M_BCAST\12M_MCAST\13M_CONF\14M_AUTH\15M_TUNNEL" \
"\16M_ZEROIZE\17M_COMP\20M_LINK0")
#endif
#define MCLADDREFERENCE(o, n) do { \
int ms = splnet(); \
- (n)->m_flags |= ((o)->m_flags & (M_EXT|M_CLUSTER)); \
+ (n)->m_flags |= ((o)->m_flags & (M_EXT|M_EXTWR)); \
(n)->m_ext.ext_nextref = (o)->m_ext.ext_nextref; \
(n)->m_ext.ext_prevref = (o); \
(o)->m_ext.ext_nextref = (n); \
* MCLGET allocates and adds an mbuf cluster to a normal mbuf;
* the flag M_EXT is set upon success.
*/
-#define MEXTADD(m, buf, size, type, free, arg) do { \
+#define MEXTADD(m, buf, size, mflags, free, arg) do { \
(m)->m_data = (m)->m_ext.ext_buf = (caddr_t)(buf); \
- (m)->m_flags |= M_EXT; \
- (m)->m_flags &= ~M_CLUSTER; \
+ (m)->m_flags |= M_EXT | (mflags & M_EXTWR); \
(m)->m_ext.ext_size = (size); \
(m)->m_ext.ext_free = (free); \
(m)->m_ext.ext_arg = (arg); \
* from must have M_PKTHDR set, and to must be empty.
*/
#define M_MOVE_PKTHDR(to, from) do { \
- (to)->m_flags = ((to)->m_flags & (M_EXT | M_CLUSTER)); \
+ (to)->m_flags = ((to)->m_flags & (M_EXT | M_EXTWR)); \
(to)->m_flags |= (from)->m_flags & M_COPYFLAGS; \
M_MOVE_HDR((to), (from)); \
if (((to)->m_flags & M_EXT) == 0) \
*/
#define M_READONLY(m) \
(((m)->m_flags & M_EXT) != 0 && \
- (((m)->m_flags & M_CLUSTER) == 0 || MCLISREFERENCED(m)))
+ (((m)->m_flags & M_EXTWR) == 0 || MCLISREFERENCED(m)))
/*
* Compute the amount of space available
int m_leadingspace(struct mbuf *);
int m_trailingspace(struct mbuf *);
struct mbuf *m_clget(struct mbuf *, int, struct ifnet *, u_int);
+void m_extfree_pool(caddr_t, u_int, void *);
void m_adj(struct mbuf *, int);
int m_copyback(struct mbuf *, int, int, const void *, int);
void m_freem(struct mbuf *);