diff options
Diffstat (limited to 'net/core/net_namespace.c')
-rw-r--r-- | net/core/net_namespace.c | 54 |
1 files changed, 22 insertions, 32 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index e3bebd36f053..b7292a2719dc 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -115,41 +115,34 @@ static void net_free(struct net *net) | |||
115 | kmem_cache_free(net_cachep, net); | 115 | kmem_cache_free(net_cachep, net); |
116 | } | 116 | } |
117 | 117 | ||
118 | struct net *copy_net_ns(unsigned long flags, struct net *old_net) | 118 | static struct net *net_create(void) |
119 | { | 119 | { |
120 | struct net *new_net = NULL; | 120 | struct net *net; |
121 | int err; | 121 | int rv; |
122 | |||
123 | get_net(old_net); | ||
124 | |||
125 | if (!(flags & CLONE_NEWNET)) | ||
126 | return old_net; | ||
127 | |||
128 | err = -ENOMEM; | ||
129 | new_net = net_alloc(); | ||
130 | if (!new_net) | ||
131 | goto out_err; | ||
132 | 122 | ||
123 | net = net_alloc(); | ||
124 | if (!net) | ||
125 | return ERR_PTR(-ENOMEM); | ||
133 | mutex_lock(&net_mutex); | 126 | mutex_lock(&net_mutex); |
134 | err = setup_net(new_net); | 127 | rv = setup_net(net); |
135 | if (!err) { | 128 | if (rv == 0) { |
136 | rtnl_lock(); | 129 | rtnl_lock(); |
137 | list_add_tail(&new_net->list, &net_namespace_list); | 130 | list_add_tail(&net->list, &net_namespace_list); |
138 | rtnl_unlock(); | 131 | rtnl_unlock(); |
139 | } | 132 | } |
140 | mutex_unlock(&net_mutex); | 133 | mutex_unlock(&net_mutex); |
134 | if (rv < 0) { | ||
135 | net_free(net); | ||
136 | return ERR_PTR(rv); | ||
137 | } | ||
138 | return net; | ||
139 | } | ||
141 | 140 | ||
142 | if (err) | 141 | struct net *copy_net_ns(unsigned long flags, struct net *old_net) |
143 | goto out_free; | 142 | { |
144 | out: | 143 | if (!(flags & CLONE_NEWNET)) |
145 | put_net(old_net); | 144 | return get_net(old_net); |
146 | return new_net; | 145 | return net_create(); |
147 | |||
148 | out_free: | ||
149 | net_free(new_net); | ||
150 | out_err: | ||
151 | new_net = ERR_PTR(err); | ||
152 | goto out; | ||
153 | } | 146 | } |
154 | 147 | ||
155 | static void cleanup_net(struct work_struct *work) | 148 | static void cleanup_net(struct work_struct *work) |
@@ -203,9 +196,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net) | |||
203 | static int __init net_ns_init(void) | 196 | static int __init net_ns_init(void) |
204 | { | 197 | { |
205 | struct net_generic *ng; | 198 | struct net_generic *ng; |
206 | int err; | ||
207 | 199 | ||
208 | printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net)); | ||
209 | #ifdef CONFIG_NET_NS | 200 | #ifdef CONFIG_NET_NS |
210 | net_cachep = kmem_cache_create("net_namespace", sizeof(struct net), | 201 | net_cachep = kmem_cache_create("net_namespace", sizeof(struct net), |
211 | SMP_CACHE_BYTES, | 202 | SMP_CACHE_BYTES, |
@@ -224,15 +215,14 @@ static int __init net_ns_init(void) | |||
224 | rcu_assign_pointer(init_net.gen, ng); | 215 | rcu_assign_pointer(init_net.gen, ng); |
225 | 216 | ||
226 | mutex_lock(&net_mutex); | 217 | mutex_lock(&net_mutex); |
227 | err = setup_net(&init_net); | 218 | if (setup_net(&init_net)) |
219 | panic("Could not setup the initial network namespace"); | ||
228 | 220 | ||
229 | rtnl_lock(); | 221 | rtnl_lock(); |
230 | list_add_tail(&init_net.list, &net_namespace_list); | 222 | list_add_tail(&init_net.list, &net_namespace_list); |
231 | rtnl_unlock(); | 223 | rtnl_unlock(); |
232 | 224 | ||
233 | mutex_unlock(&net_mutex); | 225 | mutex_unlock(&net_mutex); |
234 | if (err) | ||
235 | panic("Could not setup the initial network namespace"); | ||
236 | 226 | ||
237 | return 0; | 227 | return 0; |
238 | } | 228 | } |