Page MenuHomeFreeBSD

D45443.id139311.diff
No OneTemporary

D45443.id139311.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,12 +292,15 @@
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 *);
static void unp_drop(struct unpcb *);
static void unp_gc(__unused void *, int);
-static void unp_scan(struct mbuf *, void (*)(struct filedescent **, int));
+static void unp_scan(bool is_dgram, struct mbuf *,
+ void (*)(struct filedescent **, int));
static void unp_discard(struct file *);
static void unp_freerights(struct filedescent **, int);
static int unp_internalize(struct mbuf **, struct thread *,
@@ -1054,7 +1057,7 @@
UNP_PCB_UNLOCK(unp);
}
if (control != NULL && error != 0)
- unp_scan(control, unp_freerights);
+ unp_scan(false, control, unp_freerights);
release:
if (control != NULL)
@@ -1333,7 +1336,7 @@
SOCK_IO_SEND_UNLOCK(so);
out2:
if (c)
- unp_scan(c, unp_freerights);
+ unp_scan(true, c, unp_freerights);
out:
if (f)
m_freem(f);
@@ -1534,7 +1537,7 @@
error = unp_externalize(cm, controlp, flags);
if (error != 0) {
SOCK_IO_RECV_UNLOCK(so);
- unp_scan(m, unp_freerights);
+ unp_scan(true, m, unp_freerights);
m_freem(m);
return (error);
}
@@ -2099,20 +2102,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 +2143,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;
@@ -2189,8 +2196,11 @@
}
if (m != NULL) {
- unp_scan(m, unp_freerights);
- m_freem(m);
+ unp_scan(sotype == SOCK_DGRAM, m, unp_freerights);
+ if (sotype == SOCK_DGRAM)
+ unp_dispose_uxdg_mbq(&mbq);
+ else
+ m_freem(m);
}
}
@@ -3025,14 +3035,14 @@
SOCK_RECVBUF_LOCK(so);
switch (so->so_type) {
case SOCK_DGRAM:
- unp_scan(STAILQ_FIRST(&so->so_rcv.uxdg_mb), op);
- unp_scan(so->so_rcv.uxdg_peeked, op);
+ unp_scan(true, STAILQ_FIRST(&so->so_rcv.uxdg_mb), op);
+ unp_scan(true, so->so_rcv.uxdg_peeked, op);
TAILQ_FOREACH(sb, &so->so_rcv.uxdg_conns, uxdg_clist)
- unp_scan(STAILQ_FIRST(&sb->uxdg_mb), op);
+ unp_scan(true, STAILQ_FIRST(&sb->uxdg_mb), op);
break;
case SOCK_STREAM:
case SOCK_SEQPACKET:
- unp_scan(so->so_rcv.sb_mb, op);
+ unp_scan(false, so->so_rcv.sb_mb, op);
break;
}
SOCK_RECVBUF_UNLOCK(so);
@@ -3202,19 +3212,33 @@
free(unref, M_TEMP);
}
+static void
+unp_dispose_uxdg_mbq(uxdg_mbq_t *mbq)
+{
+ struct mbuf *m, *m2;
+
+ STAILQ_FOREACH_SAFE(m, mbq, m_stailqpkt, m2) {
+ 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 +3250,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 +3266,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);
@@ -3279,13 +3304,16 @@
SOCK_IO_RECV_UNLOCK(so);
if (m != NULL) {
- unp_scan(m, unp_freerights);
- m_freem(m);
+ unp_scan(sotype == SOCK_DGRAM, m, unp_freerights);
+ if (sotype == SOCK_DGRAM)
+ unp_dispose_uxdg_mbq(&mbq);
+ else
+ m_freem(m);
}
}
static void
-unp_scan(struct mbuf *m0, void (*op)(struct filedescent **, int))
+unp_scan(bool is_dgram, struct mbuf *m0, void (*op)(struct filedescent **, int))
{
struct mbuf *m;
struct cmsghdr *cm;
@@ -3324,7 +3352,7 @@
}
}
}
- m0 = m0->m_nextpkt;
+ m0 = is_dgram ? STAILQ_NEXT(m0, m_stailqpkt) : m0->m_nextpkt;
}
}

File Metadata

Mime Type
text/plain
Expires
Sat, Jun 13, 11:42 AM (9 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33924312
Default Alt Text
D45443.id139311.diff (5 KB)

Event Timeline