aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/net_namespace.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2011-06-21 15:02:57 -0400
committerKeith Packard <keithp@keithp.com>2011-06-21 15:02:57 -0400
commit2cd1176bd9e92924242e779dcc5c8fc922f96659 (patch)
treee9daa254647af2e7d9f99694e19976df0ea2a14d /net/core/net_namespace.c
parenta18711120764dd96ed2ee6a4d436c448542bad77 (diff)
parente92d03bff9a0d0bcbb812c9b1290ca96c9338d45 (diff)
Merge branch 'drm-intel-fixes' into drm-intel-next
Diffstat (limited to 'net/core/net_namespace.c')
-rw-r--r--net/core/net_namespace.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 6c6b86d0da15..ea489db1bc23 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)
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);
131 132
132#ifdef NETNS_REFCNT_DEBUG 133#ifdef NETNS_REFCNT_DEBUG
133 atomic_set(&net->use_count, 0); 134 atomic_set(&net->use_count, 0);
@@ -210,6 +211,13 @@ static void net_free(struct net *net)
210 kmem_cache_free(net_cachep, net); 211 kmem_cache_free(net_cachep, net);
211} 212}
212 213
214void net_drop_ns(void *p)
215{
216 struct net *ns = p;
217 if (ns && atomic_dec_and_test(&ns->passive))
218 net_free(ns);
219}
220
213struct net *copy_net_ns(unsigned long flags, struct net *old_net) 221struct net *copy_net_ns(unsigned long flags, struct net *old_net)
214{ 222{
215 struct net *net; 223 struct net *net;
@@ -230,7 +238,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net)
230 } 238 }
231 mutex_unlock(&net_mutex); 239 mutex_unlock(&net_mutex);
232 if (rv < 0) { 240 if (rv < 0) {
233 net_free(net); 241 net_drop_ns(net);
234 return ERR_PTR(rv); 242 return ERR_PTR(rv);
235 } 243 }
236 return net; 244 return net;
@@ -286,7 +294,7 @@ static void cleanup_net(struct work_struct *work)
286 /* Finally it is safe to free my network namespace structure */ 294 /* Finally it is safe to free my network namespace structure */
287 list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { 295 list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
288 list_del_init(&net->exit_list); 296 list_del_init(&net->exit_list);
289 net_free(net); 297 net_drop_ns(net);
290 } 298 }
291} 299}
292static DECLARE_WORK(net_cleanup_work, cleanup_net); 300static DECLARE_WORK(net_cleanup_work, cleanup_net);
@@ -310,19 +318,17 @@ struct net *get_net_ns_by_fd(int fd)
310 struct file *file; 318 struct file *file;
311 struct net *net; 319 struct net *net;
312 320
313 net = ERR_PTR(-EINVAL);
314 file = proc_ns_fget(fd); 321 file = proc_ns_fget(fd);
315 if (!file) 322 if (IS_ERR(file))
316 goto out; 323 return ERR_CAST(file);
317 324
318 ei = PROC_I(file->f_dentry->d_inode); 325 ei = PROC_I(file->f_dentry->d_inode);
319 if (ei->ns_ops != &netns_operations) 326 if (ei->ns_ops == &netns_operations)
320 goto out; 327 net = get_net(ei->ns);
328 else
329 net = ERR_PTR(-EINVAL);
321 330
322 net = get_net(ei->ns); 331 fput(file);
323out:
324 if (file)
325 fput(file);
326 return net; 332 return net;
327} 333}
328 334