summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2014-09-08 09:04:22 +0000
committerhrs <hrs@FreeBSD.org>2014-09-08 09:04:22 +0000
commita8a6b19feef476ab4d42bee092d3e1e694ca2bfe (patch)
tree72e29dad7ac17e220991244deb22862ca670c357
parentaf6fb4b67f48fb57b3488289f90fe4defb6742e1 (diff)
downloadFreeBSD-src-a8a6b19feef476ab4d42bee092d3e1e694ca2bfe.zip
FreeBSD-src-a8a6b19feef476ab4d42bee092d3e1e694ca2bfe.tar.gz
- Make hhook_run_socket() vnet-aware instead of adding CURVNET_SET() around
the function calls. - Fix a memory leak and stats in the case that hhook_run_socket() fails in soalloc(). PR: 193265
-rw-r--r--sys/kern/uipc_socket.c51
1 files changed, 20 insertions, 31 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 8a8f957..7066327 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -391,25 +391,24 @@ soalloc(struct vnet *vnet)
sx_init(&so->so_snd.sb_sx, "so_snd_sx");
sx_init(&so->so_rcv.sb_sx, "so_rcv_sx");
TAILQ_INIT(&so->so_aiojobq);
- mtx_lock(&so_global_mtx);
- so->so_gencnt = ++so_gencnt;
- ++numopensockets;
#ifdef VIMAGE
VNET_ASSERT(vnet != NULL, ("%s:%d vnet is NULL, so=%p",
__func__, __LINE__, so));
- vnet->vnet_sockcnt++;
so->so_vnet = vnet;
#endif
- mtx_unlock(&so_global_mtx);
-
- CURVNET_SET(vnet);
/* We shouldn't need the so_global_mtx */
- if (V_socket_hhh[HHOOK_SOCKET_CREATE]->hhh_nhooks > 0) {
- if (hhook_run_socket(so, NULL, HHOOK_SOCKET_CREATE))
- /* Do we need more comprehensive error returns? */
- so = NULL;
+ if (hhook_run_socket(so, NULL, HHOOK_SOCKET_CREATE)) {
+ /* Do we need more comprehensive error returns? */
+ uma_zfree(socket_zone, so);
+ return (NULL);
}
- CURVNET_RESTORE();
+ mtx_lock(&so_global_mtx);
+ so->so_gencnt = ++so_gencnt;
+ ++numopensockets;
+#ifdef VIMAGE
+ vnet->vnet_sockcnt++;
+#endif
+ mtx_unlock(&so_global_mtx);
return (so);
}
@@ -447,10 +446,7 @@ sodealloc(struct socket *so)
#ifdef MAC
mac_socket_destroy(so);
#endif
- CURVNET_SET(so->so_vnet);
- if (V_socket_hhh[HHOOK_SOCKET_CLOSE]->hhh_nhooks > 0)
- hhook_run_socket(so, NULL, HHOOK_SOCKET_CLOSE);
- CURVNET_RESTORE();
+ hhook_run_socket(so, NULL, HHOOK_SOCKET_CLOSE);
crfree(so->so_cred);
khelp_destroy_osd(&so->osd);
@@ -2406,10 +2402,13 @@ hhook_run_socket(struct socket *so, void *hctx, int32_t h_id)
struct socket_hhook_data hhook_data = {
.so = so,
.hctx = hctx,
- .m = NULL
+ .m = NULL,
+ .status = 0
};
- hhook_run_hooks(V_socket_hhh[h_id], &hhook_data, &so->osd);
+ CURVNET_SET(so->so_vnet);
+ HHOOKS_RUN_IF(V_socket_hhh[h_id], &hhook_data, &so->osd);
+ CURVNET_RESTORE();
/* Ugly but needed, since hhooks return void for now */
return (hhook_data.status);
@@ -3245,7 +3244,6 @@ static int
filt_soread(struct knote *kn, long hint)
{
struct socket *so;
- int ret;
so = kn->kn_fp->f_data;
SOCKBUF_LOCK_ASSERT(&so->so_rcv);
@@ -3266,14 +3264,8 @@ filt_soread(struct knote *kn, long hint)
return 1;
}
- CURVNET_SET(so->so_vnet);
- if (V_socket_hhh[HHOOK_FILT_SOREAD]->hhh_nhooks > 0)
- ret = hhook_run_socket(so, NULL, HHOOK_FILT_SOREAD);
- else
- ret = 0;
- CURVNET_RESTORE();
-
- return (ret);
+ /* This hook returning non-zero indicates an event, not error */
+ return (hhook_run_socket(so, NULL, HHOOK_FILT_SOREAD));
}
static void
@@ -3298,10 +3290,7 @@ filt_sowrite(struct knote *kn, long hint)
SOCKBUF_LOCK_ASSERT(&so->so_snd);
kn->kn_data = sbspace(&so->so_snd);
- CURVNET_SET(so->so_vnet);
- if (V_socket_hhh[HHOOK_FILT_SOWRITE]->hhh_nhooks > 0)
- hhook_run_socket(so, kn, HHOOK_FILT_SOWRITE);
- CURVNET_RESTORE();
+ hhook_run_socket(so, kn, HHOOK_FILT_SOWRITE);
if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
kn->kn_flags |= EV_EOF;
OpenPOWER on IntegriCloud