diff options
| author | Paul Mundt <lethal@linux-sh.org> | 2011-06-24 17:16:40 +0900 |
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2011-06-24 17:16:40 +0900 |
| commit | 20733d59d5763ecd96276f868c1f39e677b3b4e2 (patch) | |
| tree | 89177676a2a45afa97595ce1827630aa131c51e2 /net/core/net_namespace.c | |
| parent | 75e1b6a84f7e2186e843da94751b6d175caf9209 (diff) | |
| parent | 17e8c4e1ebf139743e3830439fa65fd906af4a43 (diff) | |
Merge branch 'fbdev/stable-updates'
Diffstat (limited to 'net/core/net_namespace.c')
| -rw-r--r-- | net/core/net_namespace.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index e41e5110c65..ea489db1bc2 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -128,6 +128,7 @@ static __net_init int setup_net(struct net *net) LIST_HEAD(net_exit_list); atomic_set(&net->count, 1); + atomic_set(&net->passive, 1); #ifdef NETNS_REFCNT_DEBUG atomic_set(&net->use_count, 0); @@ -210,6 +211,13 @@ static void net_free(struct net *net) kmem_cache_free(net_cachep, net); } +void net_drop_ns(void *p) +{ + struct net *ns = p; + if (ns && atomic_dec_and_test(&ns->passive)) + net_free(ns); +} + struct net *copy_net_ns(unsigned long flags, struct net *old_net) { struct net *net; @@ -230,7 +238,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net) } mutex_unlock(&net_mutex); if (rv < 0) { - net_free(net); + net_drop_ns(net); return ERR_PTR(rv); } return net; @@ -286,7 +294,7 @@ static void cleanup_net(struct work_struct *work) /* Finally it is safe to free my network namespace structure */ list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { list_del_init(&net->exit_list); - net_free(net); + net_drop_ns(net); } } static DECLARE_WORK(net_cleanup_work, cleanup_net); |
