summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2008-11-25 12:07:56 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2008-11-25 12:07:56 +0000
commit6e975ccd45f058f67d5fc4be2f54b49f1e378170 (patch)
treee1e4682b752a1c5f12f860549c09e39b31f3eefd /sys
parenta1fbe835d47bac06ae8b09ed42b732fd0bd7ebb3 (diff)
m_cluncount() needs to walk the mbuf chain to correctly uncount all clusters
but don't do that in m_free() as that will cause a double loop behaviour when called via m_freem(). OK dlg@, deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/uipc_mbuf.c4
-rw-r--r--sys/net/if.c19
-rw-r--r--sys/net/if_ethersubr.c4
-rw-r--r--sys/sys/mbuf.h4
4 files changed, 17 insertions, 14 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 42ea4f9674a..66617e66b9c 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_mbuf.c,v 1.98 2008/11/24 19:17:16 dlg Exp $ */
+/* $OpenBSD: uipc_mbuf.c,v 1.99 2008/11/25 12:07:55 claudio Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */
/*
@@ -323,7 +323,7 @@ m_free(struct mbuf *m)
m->m_ext.ext_prevref->m_ext.ext_nextref =
m->m_ext.ext_nextref;
} else if (m->m_flags & M_CLUSTER) {
- m_cluncount(m);
+ m_cluncount(m, 0);
pool_put(&mclpools[m->m_ext.ext_backend],
m->m_ext.ext_buf);
} else if (m->m_ext.ext_free)
diff --git a/sys/net/if.c b/sys/net/if.c
index db68e28ce8a..c70d9ed71a5 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.177 2008/11/24 12:57:37 dlg Exp $ */
+/* $OpenBSD: if.c,v 1.178 2008/11/25 12:07:55 claudio Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -2050,14 +2050,17 @@ m_clcount(struct ifnet *ifp, int pi)
}
void
-m_cluncount(struct mbuf *m)
+m_cluncount(struct mbuf *m, int all)
{
- struct mbuf_ext *me = &m->m_ext;
+ struct mbuf_ext *me;
- if (((m->m_flags & (M_EXT|M_CLUSTER)) != (M_EXT|M_CLUSTER)) ||
- (me->ext_ifp == NULL))
- return;
+ do {
+ me = &m->m_ext;
+ if (((m->m_flags & (M_EXT|M_CLUSTER)) != (M_EXT|M_CLUSTER)) ||
+ (me->ext_ifp == NULL))
+ continue;
- me->ext_ifp->if_mclstat.mclpool[me->ext_backend].mcl_alive--;
- me->ext_ifp = NULL;
+ me->ext_ifp->if_mclstat.mclpool[me->ext_backend].mcl_alive--;
+ me->ext_ifp = NULL;
+ } while (all && (m = m->m_next));
}
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index e68e442eff8..4e95bdc2796 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ethersubr.c,v 1.129 2008/11/24 12:57:37 dlg Exp $ */
+/* $OpenBSD: if_ethersubr.c,v 1.130 2008/11/25 12:07:55 claudio Exp $ */
/* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
/*
@@ -519,7 +519,7 @@ ether_input(ifp0, eh, m)
struct ether_header *eh_tmp;
#endif
- m_cluncount(m);
+ m_cluncount(m, 1);
if (eh == NULL) {
eh = mtod(m, struct ether_header *);
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 777689fedbb..a8a165fa2c4 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mbuf.h,v 1.113 2008/11/24 15:14:33 claudio Exp $ */
+/* $OpenBSD: mbuf.h,v 1.114 2008/11/25 12:07:55 claudio Exp $ */
/* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */
/*
@@ -426,7 +426,7 @@ int m_trailingspace(struct mbuf *);
void m_clget(struct mbuf *, int, struct ifnet *, u_int);
int m_cldrop(struct ifnet *, int);
void m_clcount(struct ifnet *, int);
-void m_cluncount(struct mbuf *);
+void m_cluncount(struct mbuf *, int);
void m_adj(struct mbuf *, int);
void m_copyback(struct mbuf *, int, int, const void *);
void m_freem(struct mbuf *);