diff options
author | pb <pb@FreeBSD.org> | 1999-09-28 12:59:18 +0000 |
---|---|---|
committer | pb <pb@FreeBSD.org> | 1999-09-28 12:59:18 +0000 |
commit | 3b30ad42290fed0d41cbf8a0bc84c8f9aa949861 (patch) | |
tree | f86342edd69352c57c545caa5751ed25f9954a4c /sys/kern/uipc_sockbuf.c | |
parent | 5e9f92ecf757c8f55ddae7d0dcec108fef05954d (diff) | |
download | FreeBSD-src-3b30ad42290fed0d41cbf8a0bc84c8f9aa949861.zip FreeBSD-src-3b30ad42290fed0d41cbf8a0bc84c8f9aa949861.tar.gz |
In sbflush(), don't exit the while loop too early: this can cause
an empty mbuf to stay in the queue, then causing a needless panic
because sb_cc == 0 and sb_mbcnt != 0.
But we still need to panic rather than endlessly looping if, for
some reason, sb_cc == 0 and there are non-empty mbufs in the queue.
PR: kern/11988
Reviewed by: fenner
Diffstat (limited to 'sys/kern/uipc_sockbuf.c')
-rw-r--r-- | sys/kern/uipc_sockbuf.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index a51f983..9c1cd07 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -730,8 +730,15 @@ sbflush(sb) if (sb->sb_flags & SB_LOCK) panic("sbflush: locked"); - while (sb->sb_mbcnt && sb->sb_cc) + while (sb->sb_mbcnt) { + /* + * Don't call sbdrop(sb, 0) if the leading mbuf is non-empty: + * we would loop forever. Panic instead. + */ + if (!sb->sb_cc && (sb->sb_mb == NULL || sb->sb_mb->m_len)) + break; sbdrop(sb, (int)sb->sb_cc); + } if (sb->sb_cc || sb->sb_mb || sb->sb_mbcnt) panic("sbflush: cc %ld || mb %p || mbcnt %ld", sb->sb_cc, (void *)sb->sb_mb, sb->sb_mbcnt); } |