diff options
author | hrs <hrs@FreeBSD.org> | 2014-09-08 09:04:22 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2014-09-08 09:04:22 +0000 |
commit | a8a6b19feef476ab4d42bee092d3e1e694ca2bfe (patch) | |
tree | 72e29dad7ac17e220991244deb22862ca670c357 /sys/kern | |
parent | af6fb4b67f48fb57b3488289f90fe4defb6742e1 (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/uipc_socket.c | 51 |
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; |