aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/net_namespace.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-08-08 08:30:29 -0400
committerTakashi Iwai <tiwai@suse.de>2011-08-08 08:30:29 -0400
commit0a2d31b62dba9b5b92a38c67c9cc42630513662a (patch)
treef755d74ec85248de645e10c45ed1a2ed467530f6 /net/core/net_namespace.c
parent8039290a91c5dc4414093c086987a5d7738fe2fd (diff)
parentdf944f66784e6d4f2f50739263a4947885d8b6ae (diff)
Merge branch 'fix/kconfig' into for-linus
Diffstat (limited to 'net/core/net_namespace.c')
-rw-r--r--net/core/net_namespace.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 6c6b86d0da15..5bbdbf0d3664 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -128,6 +128,8 @@ static __net_init int setup_net(struct net *net)
128 LIST_HEAD(net_exit_list); 128 LIST_HEAD(net_exit_list);
129 129
130 atomic_set(&net->count, 1); 130 atomic_set(&net->count, 1);
131 atomic_set(&net->passive, 1);
132 net->dev_base_seq = 1;
131 133
132#ifdef NETNS_REFCNT_DEBUG 134#ifdef NETNS_REFCNT_DEBUG
133 atomic_set(&net->use_count, 0); 135 atomic_set(&net->use_count, 0);
@@ -210,6 +212,13 @@ static void net_free(struct net *net)
210 kmem_cache_free(net_cachep, net); 212 kmem_cache_free(net_cachep, net);
211} 213}
212 214
215void net_drop_ns(void *p)
216{
217 struct net *ns = p;
218 if (ns && atomic_dec_and_test(&ns->passive))
219 net_free(ns);
220}
221
213struct net *copy_net_ns(unsigned long flags, struct net *old_net) 222struct net *copy_net_ns(unsigned long flags, struct net *old_net)
214{ 223{
215 struct net *net; 224 struct net *net;
@@ -230,7 +239,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net)
230 } 239 }
231 mutex_unlock(&net_mutex); 240 mutex_unlock(&net_mutex);
232 if (rv < 0) { 241 if (rv < 0) {
233 net_free(net); 242 net_drop_ns(net);
234 return ERR_PTR(rv); 243 return ERR_PTR(rv);
235 } 244 }
236 return net; 245 return net;
@@ -286,7 +295,7 @@ static void cleanup_net(struct work_struct *work)
286 /* Finally it is safe to free my network namespace structure */ 295 /* Finally it is safe to free my network namespace structure */
287 list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { 296 list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
288 list_del_init(&net->exit_list); 297 list_del_init(&net->exit_list);
289 net_free(net); 298 net_drop_ns(net);
290 } 299 }
291} 300}
292static DECLARE_WORK(net_cleanup_work, cleanup_net); 301static DECLARE_WORK(net_cleanup_work, cleanup_net);
@@ -310,19 +319,17 @@ struct net *get_net_ns_by_fd(int fd)
310 struct file *file; 319 struct file *file;
311 struct net *net; 320 struct net *net;
312 321
313 net = ERR_PTR(-EINVAL);
314 file = proc_ns_fget(fd); 322 file = proc_ns_fget(fd);
315 if (!file) 323 if (IS_ERR(file))
316 goto out; 324 return ERR_CAST(file);
317 325
318 ei = PROC_I(file->f_dentry->d_inode); 326 ei = PROC_I(file->f_dentry->d_inode);
319 if (ei->ns_ops != &netns_operations) 327 if (ei->ns_ops == &netns_operations)
320 goto out; 328 net = get_net(ei->ns);
329 else
330 net = ERR_PTR(-EINVAL);
321 331
322 net = get_net(ei->ns); 332 fput(file);
323out:
324 if (file)
325 fput(file);
326 return net; 333 return net;
327} 334}
328 335