diff options
author | Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2005-10-10 21:25:23 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-10-10 21:25:23 -0700 |
commit | eeb2b8560676e454ad37ee30b49bc7d897edc9be (patch) | |
tree | 60b316e93b880aa1ba01a9c5496c8269a48b4de9 | |
parent | 2a9bc9bb4d3a4570a8a48aadf071b91e657adb89 (diff) |
[TWSK]: Grab the module refcount for timewait sockets
This is required to avoid unloading a module that has active timewait
sockets, such as DCCP.
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/inet_timewait_sock.h | 3 | ||||
-rw-r--r-- | net/ipv4/inet_timewait_sock.c | 1 |
2 files changed, 4 insertions, 0 deletions
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index 4ade56ef3a4d..28f7b2103505 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -19,6 +19,7 @@ #include <linux/ip.h> #include <linux/list.h> +#include <linux/module.h> #include <linux/timer.h> #include <linux/types.h> #include <linux/workqueue.h> @@ -193,11 +194,13 @@ static inline u32 inet_rcv_saddr(const struct sock *sk) static inline void inet_twsk_put(struct inet_timewait_sock *tw) { if (atomic_dec_and_test(&tw->tw_refcnt)) { + struct module *owner = tw->tw_prot->owner; #ifdef SOCK_REFCNT_DEBUG printk(KERN_DEBUG "%s timewait_sock %p released\n", tw->tw_prot->name, tw); #endif kmem_cache_free(tw->tw_prot->twsk_slab, tw); + module_put(owner); } } diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index f9076ef3a1a8..a010e9a68811 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c @@ -111,6 +111,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat tw->tw_prot = sk->sk_prot_creator; atomic_set(&tw->tw_refcnt, 1); inet_twsk_dead_node_init(tw); + __module_get(tw->tw_prot->owner); } return tw; |