aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBosko Milekic <bmilekic@FreeBSD.org>2001-02-14 05:13:04 +0000
committerBosko Milekic <bmilekic@FreeBSD.org>2001-02-14 05:13:04 +0000
commitfffd12bd7296415345ca37078c6252d9bf70bded (patch)
tree00d9d70ada4a98db87c0a1e037f8af3a93cc95b8
parentff9dc074b5797f9a15675ff2b3e7e1a4e8751c99 (diff)
Notes
-rw-r--r--sys/kern/uipc_mbuf.c68
-rw-r--r--sys/netncp/ncp_rq.c29
-rw-r--r--sys/sys/mbuf.h1
3 files changed, 70 insertions, 28 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index ff174e35a283..c8cf25c40fad 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -463,7 +463,7 @@ m_reclaim(void)
/*
* Space allocation routines.
- * These are also available as macros
+ * Some of these are also available as macros
* for critical paths.
*/
struct mbuf *
@@ -505,6 +505,72 @@ m_free(struct mbuf *m)
return (n);
}
+/*
+ * struct mbuf *
+ * m_getm(m, len, how, type)
+ *
+ * This will allocate len-worth of mbufs and/or mbuf clusters (whatever fits
+ * best) and return a pointer to the top of the allocated chain. If m is
+ * non-null, then we assume that it is a single mbuf or an mbuf chain to
+ * which we want len bytes worth of mbufs and/or clusters attached, and so
+ * if we succeed in allocating it, we will just return a pointer to m.
+ *
+ * If we happen to fail at any point during the allocation, we will free
+ * up everything we have already allocated and return NULL.
+ *
+ */
+struct mbuf *
+m_getm(struct mbuf *m, int len, int how, int type)
+{
+ struct mbuf *top, *tail, *mp, *mtail = NULL;
+
+ KASSERT(len >= 0, ("len is < 0 in m_getm"));
+
+ MGET(mp, type, how);
+ if (mp == NULL)
+ return (NULL);
+ else if (len > MINCLSIZE) {
+ MCLGET(mp, how);
+ if ((mp->m_flags & M_EXT) == 0) {
+ m_free(mp);
+ return (NULL);
+ }
+ }
+ mp->m_len = 0;
+ len -= M_TRAILINGSPACE(mp);
+
+ if (m != NULL)
+ for (mtail = m; mtail->m_next != NULL; mtail = mtail->m_next);
+ else
+ m = mp;
+
+ top = tail = mp;
+ while (len > 0) {
+ MGET(mp, type, how);
+ if (mp == NULL)
+ goto failed;
+
+ tail->m_next = mp;
+ tail = mp;
+ if (len > MINCLSIZE) {
+ MCLGET(mp, how);
+ if ((mp->m_flags & M_EXT) == 0)
+ goto failed;
+ }
+
+ mp->m_len = 0;
+ len -= M_TRAILINGSPACE(mp);
+ }
+
+ if (mtail != NULL)
+ mtail->m_next = top;
+ return (m);
+
+failed:
+ m_freem(top);
+ return (NULL);
+}
+
void
m_freem(struct mbuf *m)
{
diff --git a/sys/netncp/ncp_rq.c b/sys/netncp/ncp_rq.c
index e661f5edda82..dacdee0cc615 100644
--- a/sys/netncp/ncp_rq.c
+++ b/sys/netncp/ncp_rq.c
@@ -46,8 +46,6 @@
#include <netncp/ncp_ncp.h>
#include <netncp/ncp_nls.h>
-static struct mbuf* m_getm(struct mbuf *top, int len);
-
int
ncp_rq_head(struct ncp_rq *rqp, u_int32_t ptype, u_int8_t fn,struct proc *p,
struct ucred *cred)
@@ -98,29 +96,6 @@ ncp_rq_done(struct ncp_rq *rqp) {
return (0);
}
-static struct mbuf*
-m_getm(struct mbuf *top, int len) {
- int rest = len, mlen;
- struct mbuf *m=0,*mp;
-
- mp = top;
- while (rest > 0) {
-/* NCPSDEBUG("%d\n",rest);*/
- m = m_get(M_TRYWAIT, MT_DATA);
- if (rest > MINCLSIZE) {
- MCLGET(m,M_TRYWAIT);
- mlen = ( (m->m_flags & M_EXT) == 0) ? MLEN : MCLBYTES;
- } else {
- mlen = MLEN;
- }
- m->m_len = 0/*min(mlen,rest)*/;
- mp->m_next = m;
- mp = m;
- rest -= mlen;
- }
- return top;
-}
-
/*
* Routines to fill the request
*/
@@ -182,7 +157,7 @@ ncp_rq_pathstring(struct ncp_rq *rqp, int size, char *name, struct ncp_nlstables
m->m_len += cplen;
}
if (size) {
- m_getm(m, size);
+ m = m_getm(m, size, MT_DATA, M_TRYWAIT);
while (size > 0){
m = m->m_next;
cplen = min(size, M_TRAILINGSPACE(m));
@@ -215,7 +190,7 @@ ncp_rq_putanymem(struct ncp_rq *rqp, caddr_t source, int size, int type) {
m->m_len += cplen;
}
if (size) {
- m_getm(m, size);
+ m = m_getm(m, size, MT_DATA, M_TRYWAIT);
while (size > 0){
m = m->m_next;
cplen = min(size, M_TRAILINGSPACE(m));
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 316c018eae7d..2ea81b030eb8 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -665,6 +665,7 @@ struct mbuf *m_dup(struct mbuf *, int);
struct mbuf *m_free(struct mbuf *);
void m_freem(struct mbuf *);
struct mbuf *m_get(int, int);
+struct mbuf *m_getm(struct mbuf *, int, int, int);
struct mbuf *m_getclr(int, int);
struct mbuf *m_gethdr(int, int);
int m_mballoc(int, int);