Index: sys/kern/uipc_mbuf.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_mbuf.c,v retrieving revision 1.66 diff -u -r1.66 uipc_mbuf.c --- sys/kern/uipc_mbuf.c 2001/02/11 05:02:00 1.66 +++ sys/kern/uipc_mbuf.c 2001/02/14 05:09:00 @@ -463,7 +463,7 @@ /* * Space allocation routines. - * These are also available as macros + * Some of these are also available as macros * for critical paths. */ struct mbuf * @@ -503,6 +503,72 @@ MFREE(m, n); 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 Index: sys/netncp/ncp_rq.c =================================================================== RCS file: /home/ncvs/src/sys/netncp/ncp_rq.c,v retrieving revision 1.2 diff -u -r1.2 ncp_rq.c --- sys/netncp/ncp_rq.c 2000/12/21 21:44:18 1.2 +++ sys/netncp/ncp_rq.c 2001/02/14 05:09:00 @@ -46,8 +46,6 @@ #include #include -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 @@ 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 @@ 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 @@ 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)); Index: sys/sys/mbuf.h =================================================================== RCS file: /home/ncvs/src/sys/sys/mbuf.h,v retrieving revision 1.69 diff -u -r1.69 mbuf.h --- sys/sys/mbuf.h 2001/02/11 05:02:06 1.69 +++ sys/sys/mbuf.h 2001/02/14 05:09:00 @@ -665,6 +665,7 @@ 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);