diff options
| -rw-r--r-- | net/core/net_namespace.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index aefcd7acbff..0e950fda9a0 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
| @@ -30,6 +30,20 @@ EXPORT_SYMBOL(init_net); | |||
| 30 | 30 | ||
| 31 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ | 31 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ |
| 32 | 32 | ||
| 33 | static unsigned int max_gen_ptrs = INITIAL_NET_GEN_PTRS; | ||
| 34 | |||
| 35 | static struct net_generic *net_alloc_generic(void) | ||
| 36 | { | ||
| 37 | struct net_generic *ng; | ||
| 38 | size_t generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]); | ||
| 39 | |||
| 40 | ng = kzalloc(generic_size, GFP_KERNEL); | ||
| 41 | if (ng) | ||
| 42 | ng->len = max_gen_ptrs; | ||
| 43 | |||
| 44 | return ng; | ||
| 45 | } | ||
| 46 | |||
| 33 | static int net_assign_generic(struct net *net, int id, void *data) | 47 | static int net_assign_generic(struct net *net, int id, void *data) |
| 34 | { | 48 | { |
| 35 | struct net_generic *ng, *old_ng; | 49 | struct net_generic *ng, *old_ng; |
| @@ -43,8 +57,7 @@ static int net_assign_generic(struct net *net, int id, void *data) | |||
| 43 | if (old_ng->len >= id) | 57 | if (old_ng->len >= id) |
| 44 | goto assign; | 58 | goto assign; |
| 45 | 59 | ||
| 46 | ng = kzalloc(sizeof(struct net_generic) + | 60 | ng = net_alloc_generic(); |
| 47 | id * sizeof(void *), GFP_KERNEL); | ||
| 48 | if (ng == NULL) | 61 | if (ng == NULL) |
| 49 | return -ENOMEM; | 62 | return -ENOMEM; |
| 50 | 63 | ||
| @@ -59,7 +72,6 @@ static int net_assign_generic(struct net *net, int id, void *data) | |||
| 59 | * the old copy for kfree after a grace period. | 72 | * the old copy for kfree after a grace period. |
| 60 | */ | 73 | */ |
| 61 | 74 | ||
| 62 | ng->len = id; | ||
| 63 | memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); | 75 | memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); |
| 64 | 76 | ||
| 65 | rcu_assign_pointer(net->gen, ng); | 77 | rcu_assign_pointer(net->gen, ng); |
| @@ -161,18 +173,6 @@ out_undo: | |||
| 161 | goto out; | 173 | goto out; |
| 162 | } | 174 | } |
| 163 | 175 | ||
| 164 | static struct net_generic *net_alloc_generic(void) | ||
| 165 | { | ||
| 166 | struct net_generic *ng; | ||
| 167 | size_t generic_size = sizeof(struct net_generic) + | ||
| 168 | INITIAL_NET_GEN_PTRS * sizeof(void *); | ||
| 169 | |||
| 170 | ng = kzalloc(generic_size, GFP_KERNEL); | ||
| 171 | if (ng) | ||
| 172 | ng->len = INITIAL_NET_GEN_PTRS; | ||
| 173 | |||
| 174 | return ng; | ||
| 175 | } | ||
| 176 | 176 | ||
| 177 | #ifdef CONFIG_NET_NS | 177 | #ifdef CONFIG_NET_NS |
| 178 | static struct kmem_cache *net_cachep; | 178 | static struct kmem_cache *net_cachep; |
| @@ -483,6 +483,7 @@ again: | |||
| 483 | } | 483 | } |
| 484 | return error; | 484 | return error; |
| 485 | } | 485 | } |
| 486 | max_gen_ptrs = max_t(unsigned int, max_gen_ptrs, *ops->id); | ||
| 486 | } | 487 | } |
| 487 | error = __register_pernet_operations(list, ops); | 488 | error = __register_pernet_operations(list, ops); |
| 488 | if (error) { | 489 | if (error) { |
