On Sat, May 27, 2017 at 09:38:28AM +0200, Claudio Jeker wrote:
> The MLEN check is for n which never has m_type MT_HEADER. n is allocated
> with MGET() and we want to put remain bytes into it. If that is bigger
> than MLEN it will not fit and we allocate a cluster.

You are right.  I was confused by MT_HEADER and M_PKTHDR.

I wonder whether we should add a KASSERT(m0->m_flags & M_PKTHDR)
as we access m0->m_pkthdr.len unconditionally.

> Updated version attached

OK bluhm@

> -- 
> :wq Claudio
> 
> Index: kern/uipc_mbuf.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_mbuf.c,v
> retrieving revision 1.246
> diff -u -p -r1.246 uipc_mbuf.c
> --- kern/uipc_mbuf.c  8 May 2017 15:47:49 -0000       1.246
> +++ kern/uipc_mbuf.c  27 May 2017 07:36:12 -0000
> @@ -1078,7 +1110,12 @@ m_makespace(struct mbuf *m0, int skip, i
>       struct mbuf *m;
>       unsigned remain;
>  
> -     KASSERT(m0 != NULL);
> +     /*
> +      * Limit the size of the new header to MHLEN. In case
> +      * skip = 0 and the first buffer is not a cluster this
> +      * is the maximum space available in that mbuf.
> +      * In other words this code never prepends a mbuf.
> +      */
>       KASSERT(hlen < MHLEN);
>  
>       for (m = m0; m && skip > m->m_len; m = m->m_next)
> @@ -1089,7 +1126,7 @@ m_makespace(struct mbuf *m0, int skip, i
>        * At this point skip is the offset into the mbuf m
>        * where the new header should be placed.  Figure out
>        * if there's space to insert the new header.  If so,
> -      * and copying the remainder makese sense then do so.
> +      * and copying the remainder makes sense then do so.
>        * Otherwise insert a new mbuf in the chain, splitting
>        * the contents of m as needed.
>        */
> @@ -1099,69 +1136,45 @@ m_makespace(struct mbuf *m0, int skip, i
>                       memmove(m->m_data-hlen, m->m_data, skip);
>               m->m_data -= hlen;
>               m->m_len += hlen;
> -             (*off) = skip;
> +             *off = skip;
>       } else if (hlen > M_TRAILINGSPACE(m)) {
> -             struct mbuf *n0, *n, **np;
> -             int todo, len, done, alloc;
> +             struct mbuf *n;
>  
> -             n0 = NULL;
> -             np = &n0;
> -             alloc = 0;
> -             done = 0;
> -             todo = remain;
> -             while (todo > 0) {
> +             if (remain > 0) {
>                       MGET(n, M_DONTWAIT, m->m_type);
> -                     len = MHLEN;
> -                     if (n && todo > MHLEN) {
> -                             MCLGET(n, M_DONTWAIT);
> -                             len = MCLBYTES;
> +                     if (n && remain > MLEN) {
> +                             MCLGETI(n, M_DONTWAIT, NULL, remain);
>                               if ((n->m_flags & M_EXT) == 0) {
>                                       m_free(n);
>                                       n = NULL;
>                               }
>                       }
> -                     if (n == NULL) {
> -                             m_freem(n0);
> -                             return NULL;
> -                     }
> -                     *np = n;
> -                     np = &n->m_next;
> -                     alloc++;
> -                     len = min(todo, len);
> -                     memcpy(n->m_data, mtod(m, char *) + skip + done, len);
> -                     n->m_len = len;
> -                     done += len;
> -                     todo -= len;
> +                     if (n == NULL)
> +                             return (NULL);
> +
> +                     memcpy(n->m_data, mtod(m, char *) + skip, remain);
> +                     n->m_len = remain;
> +                     m->m_len -= remain;
> +
> +                     n->m_next = m->m_next;
> +                     m->m_next = n;
>               }
>  
> -             if (hlen <= M_TRAILINGSPACE(m) + remain) {
> -                     m->m_len = skip + hlen;
> +             if (hlen <= M_TRAILINGSPACE(m)) {
> +                     m->m_len += hlen;
>                       *off = skip;
> -                     if (n0 != NULL) {
> -                             *np = m->m_next;
> -                             m->m_next = n0;
> -                     }
> -             }
> -             else {
> +             } else {
>                       n = m_get(M_DONTWAIT, m->m_type);
> -                     if (n == NULL) {
> -                             m_freem(n0);
> +                     if (n == NULL)
>                               return NULL;
> -                     }
> -                     alloc++;
> -
> -                     if ((n->m_next = n0) == NULL)
> -                             np = &n->m_next;
> -                     n0 = n;
> -
> -                     *np = m->m_next;
> -                     m->m_next = n0;
>  
>                       n->m_len = hlen;
> -                     m->m_len = skip;
>  
> -                     m = n;                  /* header is at front ... */
> -                     *off = 0;               /* ... of new mbuf */
> +                     n->m_next = m->m_next;
> +                     m->m_next = n;
> +
> +                     *off = 0;       /* header is at front ... */
> +                     m = n;          /* ... of new mbuf */
>               }
>       } else {
>               /*

Reply via email to