diff options
author | Christopher Kenna <cjk@cs.unc.edu> | 2012-09-20 13:33:17 -0400 |
---|---|---|
committer | Christopher Kenna <cjk@cs.unc.edu> | 2012-09-20 13:33:17 -0400 |
commit | 5e0a4919ccb230ab449826ef91bdf38a4ed283e5 (patch) | |
tree | 3790db1aa69ed50b08f34c21c1796785df6a0304 /net/core/net_namespace.c | |
parent | c00613f1fad38acec00ef2c009ae4e73110084ac (diff) | |
parent | 5dd038629bdedef22d5ecad2d5e75ad81f4dc694 (diff) |
Merge remote-tracking branch 'oneiric-ubuntu/pandaboard' into pandaboard-litmus
Remote branch is from Ubuntu Oneiric (tag Ubuntu-3.0.0-1215.27) with
minor patch to the TWL-RTC code. Trying to pull this into LITMUS^RT
staging (as of 9/20/2012) to get LITMUS^RT running on the PandaBoard.
Conflicts:
Makefile
fs/exec.c
include/linux/fs.h
kernel/fork.c
Diffstat (limited to 'net/core/net_namespace.c')
-rw-r--r-- | net/core/net_namespace.c | 64 |
1 files changed, 34 insertions, 30 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index ea489db1bc2..2772ed11bec 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -29,6 +29,20 @@ EXPORT_SYMBOL(init_net); | |||
29 | 29 | ||
30 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ | 30 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ |
31 | 31 | ||
32 | static unsigned int max_gen_ptrs = INITIAL_NET_GEN_PTRS; | ||
33 | |||
34 | static struct net_generic *net_alloc_generic(void) | ||
35 | { | ||
36 | struct net_generic *ng; | ||
37 | size_t generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]); | ||
38 | |||
39 | ng = kzalloc(generic_size, GFP_KERNEL); | ||
40 | if (ng) | ||
41 | ng->len = max_gen_ptrs; | ||
42 | |||
43 | return ng; | ||
44 | } | ||
45 | |||
32 | static int net_assign_generic(struct net *net, int id, void *data) | 46 | static int net_assign_generic(struct net *net, int id, void *data) |
33 | { | 47 | { |
34 | struct net_generic *ng, *old_ng; | 48 | struct net_generic *ng, *old_ng; |
@@ -42,8 +56,7 @@ static int net_assign_generic(struct net *net, int id, void *data) | |||
42 | if (old_ng->len >= id) | 56 | if (old_ng->len >= id) |
43 | goto assign; | 57 | goto assign; |
44 | 58 | ||
45 | ng = kzalloc(sizeof(struct net_generic) + | 59 | ng = net_alloc_generic(); |
46 | id * sizeof(void *), GFP_KERNEL); | ||
47 | if (ng == NULL) | 60 | if (ng == NULL) |
48 | return -ENOMEM; | 61 | return -ENOMEM; |
49 | 62 | ||
@@ -58,7 +71,6 @@ static int net_assign_generic(struct net *net, int id, void *data) | |||
58 | * the old copy for kfree after a grace period. | 71 | * the old copy for kfree after a grace period. |
59 | */ | 72 | */ |
60 | 73 | ||
61 | ng->len = id; | ||
62 | memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); | 74 | memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); |
63 | 75 | ||
64 | rcu_assign_pointer(net->gen, ng); | 76 | rcu_assign_pointer(net->gen, ng); |
@@ -70,21 +82,29 @@ assign: | |||
70 | 82 | ||
71 | static int ops_init(const struct pernet_operations *ops, struct net *net) | 83 | static int ops_init(const struct pernet_operations *ops, struct net *net) |
72 | { | 84 | { |
73 | int err; | 85 | int err = -ENOMEM; |
86 | void *data = NULL; | ||
87 | |||
74 | if (ops->id && ops->size) { | 88 | if (ops->id && ops->size) { |
75 | void *data = kzalloc(ops->size, GFP_KERNEL); | 89 | data = kzalloc(ops->size, GFP_KERNEL); |
76 | if (!data) | 90 | if (!data) |
77 | return -ENOMEM; | 91 | goto out; |
78 | 92 | ||
79 | err = net_assign_generic(net, *ops->id, data); | 93 | err = net_assign_generic(net, *ops->id, data); |
80 | if (err) { | 94 | if (err) |
81 | kfree(data); | 95 | goto cleanup; |
82 | return err; | ||
83 | } | ||
84 | } | 96 | } |
97 | err = 0; | ||
85 | if (ops->init) | 98 | if (ops->init) |
86 | return ops->init(net); | 99 | err = ops->init(net); |
87 | return 0; | 100 | if (!err) |
101 | return 0; | ||
102 | |||
103 | cleanup: | ||
104 | kfree(data); | ||
105 | |||
106 | out: | ||
107 | return err; | ||
88 | } | 108 | } |
89 | 109 | ||
90 | static void ops_free(const struct pernet_operations *ops, struct net *net) | 110 | static void ops_free(const struct pernet_operations *ops, struct net *net) |
@@ -159,18 +179,6 @@ out_undo: | |||
159 | goto out; | 179 | goto out; |
160 | } | 180 | } |
161 | 181 | ||
162 | static struct net_generic *net_alloc_generic(void) | ||
163 | { | ||
164 | struct net_generic *ng; | ||
165 | size_t generic_size = sizeof(struct net_generic) + | ||
166 | INITIAL_NET_GEN_PTRS * sizeof(void *); | ||
167 | |||
168 | ng = kzalloc(generic_size, GFP_KERNEL); | ||
169 | if (ng) | ||
170 | ng->len = INITIAL_NET_GEN_PTRS; | ||
171 | |||
172 | return ng; | ||
173 | } | ||
174 | 182 | ||
175 | #ifdef CONFIG_NET_NS | 183 | #ifdef CONFIG_NET_NS |
176 | static struct kmem_cache *net_cachep; | 184 | static struct kmem_cache *net_cachep; |
@@ -446,12 +454,7 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) | |||
446 | static int __register_pernet_operations(struct list_head *list, | 454 | static int __register_pernet_operations(struct list_head *list, |
447 | struct pernet_operations *ops) | 455 | struct pernet_operations *ops) |
448 | { | 456 | { |
449 | int err = 0; | 457 | return ops_init(ops, &init_net); |
450 | err = ops_init(ops, &init_net); | ||
451 | if (err) | ||
452 | ops_free(ops, &init_net); | ||
453 | return err; | ||
454 | |||
455 | } | 458 | } |
456 | 459 | ||
457 | static void __unregister_pernet_operations(struct pernet_operations *ops) | 460 | static void __unregister_pernet_operations(struct pernet_operations *ops) |
@@ -481,6 +484,7 @@ again: | |||
481 | } | 484 | } |
482 | return error; | 485 | return error; |
483 | } | 486 | } |
487 | max_gen_ptrs = max_t(unsigned int, max_gen_ptrs, *ops->id); | ||
484 | } | 488 | } |
485 | error = __register_pernet_operations(list, ops); | 489 | error = __register_pernet_operations(list, ops); |
486 | if (error) { | 490 | if (error) { |