diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2008-11-25 12:07:56 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2008-11-25 12:07:56 +0000 |
commit | 6e975ccd45f058f67d5fc4be2f54b49f1e378170 (patch) | |
tree | e1e4682b752a1c5f12f860549c09e39b31f3eefd /sys | |
parent | a1fbe835d47bac06ae8b09ed42b732fd0bd7ebb3 (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.c | 4 | ||||
-rw-r--r-- | sys/net/if.c | 19 | ||||
-rw-r--r-- | sys/net/if_ethersubr.c | 4 | ||||
-rw-r--r-- | sys/sys/mbuf.h | 4 |
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 *); |