git: 51ac5ee0d57f - main - unix/stream: refactor sendfile(2) logic to work without M_BLOCKER flag
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 23 May 2025 22:52:53 UTC
The branch main has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=51ac5ee0d57f178882af4b40d36089e2069704e4
commit 51ac5ee0d57f178882af4b40d36089e2069704e4
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-05-23 21:55:56 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-05-23 22:04:39 +0000
unix/stream: refactor sendfile(2) logic to work without M_BLOCKER flag
This flag was initially an INVARIANT thing back in 2014, but we got
stuck with it until today. A bug with sendfile(2) headers/trailers
fixed as a side effect of refactoring.
---
sys/kern/uipc_usrreq.c | 34 +++++++++++++++++++---------------
1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 0f730cf9424b..5b1b8443f8e6 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1008,10 +1008,10 @@ uipc_stream_sbcheck(struct sockbuf *sb)
dacc = dccc = dctl = dmbcnt = 0;
STAILQ_FOREACH(d, &sb->uxst_mbq, m_stailq) {
- if (d == sb->uxst_fnrdy)
+ if (d == sb->uxst_fnrdy) {
+ MPASS(d->m_flags & M_NOTREADY);
notready = true;
- if (notready)
- MPASS(d->m_flags & (M_NOTREADY|M_BLOCKED));
+ }
if (d->m_type == MT_CONTROL)
dctl += d->m_len;
else if (d->m_type == MT_DATA) {
@@ -2471,15 +2471,21 @@ uipc_sendfile(struct socket *so, int flags, struct mbuf *m,
sb->sb_mbcnt += mc.mc_mlen;
if (sb->uxst_fnrdy == NULL) {
if (notready) {
- sb->uxst_fnrdy = STAILQ_FIRST(&mc.mc_q);
wakeup = false;
+ STAILQ_FOREACH(m, &mc.mc_q, m_stailq) {
+ if (m->m_flags & M_NOTREADY) {
+ sb->uxst_fnrdy = m;
+ break;
+ } else {
+ sb->sb_acc += m->m_len;
+ wakeup = true;
+ }
+ }
} else {
- sb->sb_acc += mc.mc_len;
wakeup = true;
+ sb->sb_acc += mc.mc_len;
}
} else {
- STAILQ_FOREACH(m, &mc.mc_q, m_stailq)
- m->m_flags |= M_BLOCKED;
wakeup = false;
}
STAILQ_CONCAT(&sb->uxst_mbq, &mc.mc_q);
@@ -2504,24 +2510,22 @@ out:
static int
uipc_sbready(struct sockbuf *sb, struct mbuf *m, int count)
{
- u_int blocker;
+ bool blocker;
/* assert locked */
- blocker = (sb->uxst_fnrdy == m) ? M_BLOCKED : 0;
+ blocker = (sb->uxst_fnrdy == m);
STAILQ_FOREACH_FROM(m, &sb->uxst_mbq, m_stailq) {
if (count > 0) {
MPASS(m->m_flags & M_NOTREADY);
- m->m_flags &= ~(M_NOTREADY | blocker);
+ m->m_flags &= ~M_NOTREADY;
if (blocker)
sb->sb_acc += m->m_len;
count--;
- } else if (blocker && !(m->m_flags & M_NOTREADY)) {
- MPASS(m->m_flags & M_BLOCKED);
- m->m_flags &= ~M_BLOCKED;
- sb->sb_acc += m->m_len;
- } else
+ } else if (m->m_flags & M_NOTREADY)
break;
+ else if (blocker)
+ sb->sb_acc += m->m_len;
}
if (blocker) {
sb->uxst_fnrdy = m;