git: 67c1c4dfd1cc - main - sockbuf: provide sbunreserve_locked() which is a complement to sbreserve()

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Mon, 24 Mar 2025 06:41:19 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=67c1c4dfd1ccf7d46271bfbabc403dc0534c1631

commit 67c1c4dfd1ccf7d46271bfbabc403dc0534c1631
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-03-24 06:40:50 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-03-24 06:40:50 +0000

    sockbuf: provide sbunreserve_locked() which is a complement to sbreserve()
    
    The sbreserve() works only on protocol-independent parts of the sockbuf,
    but sbrelease() also clears the generic sockbuf mbuf chain.  Calling the
    latter to undo changes done by the former is not correct.  The new
    function is the right thing.
    
    Reviewed by:            markj
    Differential Revision:  https://reviews.freebsd.org/D49364
---
 sys/kern/uipc_sockbuf.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 48984046ea8a..ec00878cd9a5 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -75,6 +75,7 @@ static void	sbcompress_ktls_rx(struct sockbuf *sb, struct mbuf *m,
     struct mbuf *n);
 #endif
 static struct mbuf	*sbcut_internal(struct sockbuf *sb, int len);
+static void		sbunreserve_locked(struct socket *so, sb_which which);
 
 /*
  * Our own version of m_clrprotoflags(), that can preserve M_NOTREADY.
@@ -618,7 +619,7 @@ soreserve(struct socket *so, u_long sndcc, u_long rcvcc)
 	SOCK_SENDBUF_UNLOCK(so);
 	return (0);
 bad2:
-	sbrelease_locked(so, SO_SND);
+	sbunreserve_locked(so, SO_SND);
 bad:
 	SOCK_RECVBUF_UNLOCK(so);
 	SOCK_SENDBUF_UNLOCK(so);
@@ -683,6 +684,18 @@ sbreserve_locked(struct socket *so, sb_which which, u_long cc,
 	return (sbreserve_locked_limit(so, which, cc, sb_max, td));
 }
 
+static void
+sbunreserve_locked(struct socket *so, sb_which which)
+{
+	struct sockbuf *sb = sobuf(so, which);
+
+	SOCK_BUF_LOCK_ASSERT(so, which);
+
+	(void)chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, 0,
+	    RLIM_INFINITY);
+	sb->sb_mbmax = 0;
+}
+
 int
 sbsetopt(struct socket *so, struct sockopt *sopt)
 {
@@ -786,9 +799,7 @@ sbrelease_locked(struct socket *so, sb_which which)
 	SOCK_BUF_LOCK_ASSERT(so, which);
 
 	sbflush_locked(sb);
-	(void)chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, 0,
-	    RLIM_INFINITY);
-	sb->sb_mbmax = 0;
+	sbunreserve_locked(so, which);
 }
 
 void