svn commit: r274513 - in projects/sendfile/sys: kern sys
Gleb Smirnoff
glebius at FreeBSD.org
Fri Nov 14 15:55:58 UTC 2014
Author: glebius
Date: Fri Nov 14 15:55:56 2014
New Revision: 274513
URL: https://svnweb.freebsd.org/changeset/base/274513
Log:
When sbcut() works on M_NOTREADY mbufs, it shouldn't free them, since
they a referenced by some outside entity. Instead, sbcut() would mark
them with a new flag and forget them.
Later, if sbready() encounters such mbufs, it frees them.
Sponsored by: Nginx, Inc.
Modified:
projects/sendfile/sys/kern/uipc_sockbuf.c
projects/sendfile/sys/sys/sockbuf.h
Modified: projects/sendfile/sys/kern/uipc_sockbuf.c
==============================================================================
--- projects/sendfile/sys/kern/uipc_sockbuf.c Fri Nov 14 15:50:16 2014 (r274512)
+++ projects/sendfile/sys/kern/uipc_sockbuf.c Fri Nov 14 15:55:56 2014 (r274513)
@@ -78,6 +78,20 @@ sbready(struct sockbuf *sb, struct mbuf
SOCKBUF_LOCK_ASSERT(sb);
+ if (m->m_flags & M_SBCUTTED) {
+ /*
+ * Oops, something bad happened to the socket buffer while
+ * we were working on the data. Our mbufs are detached from
+ * the sockbuf, and all what we can do is free them.
+ */
+ for (int i = 0; i < count; i++) {
+ KASSERT(m->m_flags & M_SBCUTTED,
+ ("%s: m %p !M_SBCUTTED", __func__, m));
+ m = m_free(m);
+ }
+ return (EPIPE);
+ }
+
KASSERT(sb->sb_fnrdy != NULL, ("%s: sb %p NULL fnrdy", __func__, sb));
blocker = (sb->sb_fnrdy == m) ? M_BLOCKED : 0;
@@ -1045,8 +1059,12 @@ sbcut_internal(struct sockbuf *sb, int l
len -= m->m_len;
sbfree(sb, m);
n = m->m_next;
- m->m_next = mfree;
- mfree = m;
+ if (m->m_flags & M_NOTREADY)
+ m->m_flags |= M_SBCUTTED;
+ else {
+ m->m_next = mfree;
+ mfree = m;
+ }
m = n;
}
if (m) {
Modified: projects/sendfile/sys/sys/sockbuf.h
==============================================================================
--- projects/sendfile/sys/sys/sockbuf.h Fri Nov 14 15:50:16 2014 (r274512)
+++ projects/sendfile/sys/sys/sockbuf.h Fri Nov 14 15:55:56 2014 (r274513)
@@ -128,6 +128,7 @@ struct sockbuf {
#define M_NOTREADY M_PROTO1 /* m_data not populated yet */
#define M_BLOCKED M_PROTO2 /* M_NOTREADY in front of m */
#define M_NOTAVAIL (M_NOTREADY | M_BLOCKED)
+#define M_SBCUTTED M_PROTO3 /* mbuf was sbcutted out */
void sbappend(struct sockbuf *sb, struct mbuf *m);
void sbappend_locked(struct sockbuf *sb, struct mbuf *m);
More information about the svn-src-projects
mailing list