Page MenuHomeFreeBSD

D45443.diff
No OneTemporary

D45443.diff

diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -292,6 +292,8 @@
static int unp_connectat(int, struct socket *, struct sockaddr *,
struct thread *, bool);
static void unp_connect2(struct socket *so, struct socket *so2);
+typedef STAILQ_HEAD(udxg_mbq, mbuf) uxdg_mbq_t;
+static void unp_dispose_uxdg_mbq(uxdg_mbq_t *);
static void unp_disconnect(struct unpcb *unp, struct unpcb *unp2);
static void unp_dispose(struct socket *so);
static void unp_shutdown(struct unpcb *);
@@ -2099,20 +2101,24 @@
static void
unp_disconnect(struct unpcb *unp, struct unpcb *unp2)
{
+ uxdg_mbq_t mbq;
struct socket *so, *so2;
struct mbuf *m = NULL;
#ifdef INVARIANTS
struct unpcb *unptmp;
#endif
+ int sotype;
UNP_PCB_LOCK_ASSERT(unp);
UNP_PCB_LOCK_ASSERT(unp2);
KASSERT(unp->unp_conn == unp2,
("%s: unpcb %p is not connected to %p", __func__, unp, unp2));
+ STAILQ_INIT(&mbq);
unp->unp_conn = NULL;
so = unp->unp_socket;
so2 = unp2->unp_socket;
+ sotype = unp->unp_socket->so_type;
switch (unp->unp_socket->so_type) {
case SOCK_DGRAM:
/*
@@ -2136,7 +2142,7 @@
so2->so_rcv.uxdg_mbcnt += so->so_snd.uxdg_mbcnt;
} else {
m = STAILQ_FIRST(&so->so_snd.uxdg_mb);
- STAILQ_INIT(&so->so_snd.uxdg_mb);
+ STAILQ_CONCAT(&mbq, &so->so_snd.uxdg_mb);
so2->so_rcv.sb_acc -= so->so_snd.uxdg_cc;
so2->so_rcv.sb_ccc -= so->so_snd.uxdg_cc;
so2->so_rcv.sb_ctl -= so->so_snd.uxdg_ctl;
@@ -2190,7 +2196,10 @@
if (m != NULL) {
unp_scan(m, unp_freerights);
- m_freem(m);
+ if (sotype == SOCK_DGRAM)
+ unp_dispose_uxdg_mbq(&mbq);
+ else
+ m_freem(m);
}
}
@@ -3202,19 +3211,33 @@
free(unref, M_TEMP);
}
+static void
+unp_dispose_uxdg_mbq(uxdg_mbq_t *mbq)
+{
+ struct mbuf *m;
+
+ while ((m = STAILQ_FIRST(mbq)) != NULL) {
+ STAILQ_REMOVE(mbq, m, mbuf, m_stailqpkt);
+ m_freem(m);
+ }
+}
+
/*
* Synchronize against unp_gc, which can trip over data as we are freeing it.
*/
static void
unp_dispose(struct socket *so)
{
+ uxdg_mbq_t mbq;
struct sockbuf *sb;
struct unpcb *unp;
struct mbuf *m;
int error __diagused;
+ int sotype;
MPASS(!SOLISTENING(so));
+ STAILQ_INIT(&mbq);
unp = sotounpcb(so);
UNP_LINK_WLOCK();
unp->unp_gcflag |= UNPGC_IGNORE_RIGHTS;
@@ -3226,7 +3249,8 @@
error = SOCK_IO_RECV_LOCK(so, SBL_WAIT | SBL_NOINTR);
MPASS(!error);
SOCK_RECVBUF_LOCK(so);
- switch (so->so_type) {
+ sotype = so->so_type;
+ switch (sotype) {
case SOCK_DGRAM:
while ((sb = TAILQ_FIRST(&so->so_rcv.uxdg_conns)) != NULL) {
STAILQ_CONCAT(&so->so_rcv.uxdg_mb, &sb->uxdg_mb);
@@ -3241,7 +3265,7 @@
sb->uxdg_peeked = NULL;
}
m = STAILQ_FIRST(&sb->uxdg_mb);
- STAILQ_INIT(&sb->uxdg_mb);
+ STAILQ_CONCAT(&mbq, &sb->uxdg_mb);
/* XXX: our shortened sbrelease() */
(void)chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, 0,
RLIM_INFINITY);
@@ -3280,7 +3304,10 @@
if (m != NULL) {
unp_scan(m, unp_freerights);
- m_freem(m);
+ if (sotype == SOCK_DGRAM)
+ unp_dispose_uxdg_mbq(&mbq);
+ else
+ m_freem(m);
}
}

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 19, 9:18 PM (21 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31799182
Default Alt Text
D45443.diff (3 KB)

Event Timeline