The branch stable/14 has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6e9b6e5dbb84c0c44930448b7da169a6a351d670

commit 6e9b6e5dbb84c0c44930448b7da169a6a351d670
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2024-12-28 08:30:01 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2025-01-20 02:40:09 +0000

    mb_unmapped_to_ext(): return error code on error
    
    (cherry picked from commit cf322978d73a3ed4958cb64cc4f1b47ceb53a03e)
---
 sys/kern/kern_mbuf.c | 41 +++++++++++++++++++++++++++--------------
 sys/sys/mbuf.h       |  2 +-
 2 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c
index 002e508e91cc..0a9cb72222c2 100644
--- a/sys/kern/kern_mbuf.c
+++ b/sys/kern/kern_mbuf.c
@@ -936,8 +936,8 @@ mb_unmapped_free_mext(struct mbuf *m)
        mb_free_extpg(old_m);
 }
 
-static struct mbuf *
-_mb_unmapped_to_ext(struct mbuf *m)
+static int
+_mb_unmapped_to_ext(struct mbuf *m, struct mbuf **mres)
 {
        struct mbuf *m_new, *top, *prev, *mref;
        struct sf_buf *sf;
@@ -947,9 +947,15 @@ _mb_unmapped_to_ext(struct mbuf *m)
        u_int ref_inc = 0;
 
        M_ASSERTEXTPG(m);
+
+       if (m->m_epg_tls != NULL) {
+               /* can't convert TLS mbuf */
+               m_freem(m);
+               *mres = NULL;
+               return (EINVAL);
+       }
+
        len = m->m_len;
-       KASSERT(m->m_epg_tls == NULL, ("%s: can't convert TLS mbuf %p",
-           __func__, m));
 
        /* See if this is the mbuf that holds the embedded refcount. */
        if (m->m_ext.ext_flags & EXT_FLAG_EMBREF) {
@@ -1047,7 +1053,8 @@ _mb_unmapped_to_ext(struct mbuf *m)
                        atomic_add_int(refcnt, ref_inc);
        }
        m_free(m);
-       return (top);
+       *mres = top;
+       return (0);
 
 fail:
        if (ref_inc != 0) {
@@ -1064,13 +1071,15 @@ fail:
        }
        m_free(m);
        m_freem(top);
-       return (NULL);
+       *mres = NULL;
+       return (ENOMEM);
 }
 
-struct mbuf *
-mb_unmapped_to_ext(struct mbuf *top)
+int
+mb_unmapped_to_ext(struct mbuf *top, struct mbuf **mres)
 {
-       struct mbuf *m, *next, *prev = NULL;
+       struct mbuf *m, *m1, *next, *prev = NULL;
+       int error;
 
        prev = NULL;
        for (m = top; m != NULL; m = next) {
@@ -1086,12 +1095,15 @@ mb_unmapped_to_ext(struct mbuf *top)
                                 */
                                prev->m_next = NULL;
                        }
-                       m = _mb_unmapped_to_ext(m);
-                       if (m == NULL) {
-                               m_freem(top);
+                       error = _mb_unmapped_to_ext(m, &m1);
+                       if (error != 0) {
+                               if (top != m)
+                                       m_free(top);
                                m_freem(next);
-                               return (NULL);
+                               *mres = NULL;
+                               return (error);
                        }
+                       m = m1;
                        if (prev == NULL) {
                                top = m;
                        } else {
@@ -1110,7 +1122,8 @@ mb_unmapped_to_ext(struct mbuf *top)
                        prev = m;
                }
        }
-       return (top);
+       *mres = top;
+       return (0);
 }
 
 /*
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index f7925da795cd..941c907e903b 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -814,7 +814,7 @@ struct mbuf *mb_alloc_ext_plus_pages(int, int);
 struct mbuf    *mb_mapped_to_unmapped(struct mbuf *, int, int, int,
                    struct mbuf **);
 int             mb_unmapped_compress(struct mbuf *m);
-struct mbuf    *mb_unmapped_to_ext(struct mbuf *m);
+int             mb_unmapped_to_ext(struct mbuf *m, struct mbuf **mres);
 void            mb_free_notready(struct mbuf *m, int count);
 void            m_adj(struct mbuf *, int);
 void            m_adj_decap(struct mbuf *, int);

Reply via email to