+#include "param.h"
+#include "dir.h"
+#include "user.h"
+#include "proc.h"
+#include "cmap.h"
+#include "map.h"
+#include "mbuf.h"
+#include "vm.h"
+#include "kernel.h"
+
+mbinit()
+{
+ int s;
+
+ s = splimp();
+ if (m_clalloc(4096/CLBYTES, MPG_MBUFS, M_DONTWAIT) == 0)
+ goto bad;
+ if (m_clalloc(8*4096/CLBYTES, MPG_CLUSTERS, M_DONTWAIT) == 0)
+ goto bad;
+ splx(s);
+ return;
+bad:
+ panic("mbinit");
+}
+
+/*
+ * Must be called at splimp.
+ */
+caddr_t
+m_clalloc(ncl, how, canwait)
+ register int ncl;
+ int how;
+{
+ int npg, mbx;
+ register struct mbuf *m;
+ register int i;
+
+ npg = ncl * CLSIZE;
+ mbx = rmalloc(mbmap, (long)npg);
+ if (mbx == 0) {
+ if (canwait == M_WAIT)
+ panic("out of mbufs: map full");
+ return (0);
+ }
+ m = cltom(mbx / CLSIZE);
+ if (memall(&Mbmap[mbx], npg, proc, CSYS) == 0) {
+ rmfree(mbmap, (long)npg, (long)mbx);
+ return (0);
+ }
+ vmaccess(&Mbmap[mbx], (caddr_t)m, npg);
+ switch (how) {
+
+ case MPG_CLUSTERS:
+ for (i = 0; i < ncl; i++) {
+ m->m_off = 0;
+ m->m_next = mclfree;
+ mclfree = m;
+ m += CLBYTES / sizeof (*m);
+ mbstat.m_clfree++;
+ }
+ mbstat.m_clusters += ncl;
+ break;
+
+ case MPG_MBUFS:
+ for (i = ncl * CLBYTES / sizeof (*m); i > 0; i--) {
+ m->m_off = 0;
+ m->m_type = MT_DATA;
+ mbstat.m_mtypes[MT_DATA]++;
+ mbstat.m_mbufs++;
+ (void) m_free(m);
+ m++;
+ }
+ break;
+ }
+ return ((caddr_t)m);
+}
+
+m_pgfree(addr, n)
+ caddr_t addr;
+ int n;
+{
+
+#ifdef lint
+ addr = addr; n = n;
+#endif
+}
+
+/*
+ * Must be called at splimp.
+ */
+m_expand(canwait)