Commit 05fceb4ad7e8bf809a2a97061d6273d27d1a8449
Committed by
David S. Miller
1 parent
47d54d6582
Exists in
master
and in
39 other branches
net: disallow to use net_assign_generic externally
Now there's no need to use this fuction directly because it's handled by register_pernet_device. So to make this simple and easy to understand, make this static to do not tempt potentional users. Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 2 changed files with 47 additions and 53 deletions Side-by-side Diff
include/net/netns/generic.h
... | ... | @@ -14,11 +14,8 @@ |
14 | 14 | * The rules are simple: |
15 | 15 | * 1. set pernet_operations->id. After register_pernet_device you |
16 | 16 | * will have the id of your private pointer. |
17 | - * 2. Either set pernet_operations->size (to have the code allocate and | |
18 | - * free a private structure pointed to from struct net ) or | |
19 | - * call net_assign_generic() to put the private data on the struct | |
20 | - * net (most preferably this should be done in the ->init callback | |
21 | - * of the ops registered); | |
17 | + * 2. set pernet_operations->size to have the code allocate and free | |
18 | + * a private structure pointed to from struct net. | |
22 | 19 | * 3. do not change this pointer while the net is alive; |
23 | 20 | * 4. do not try to have any private reference on the net_generic object. |
24 | 21 | * |
... | ... | @@ -46,7 +43,5 @@ |
46 | 43 | |
47 | 44 | return ptr; |
48 | 45 | } |
49 | - | |
50 | -extern int net_assign_generic(struct net *net, int id, void *data); | |
51 | 46 | #endif |
net/core/net_namespace.c
... | ... | @@ -27,6 +27,51 @@ |
27 | 27 | |
28 | 28 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ |
29 | 29 | |
30 | +static void net_generic_release(struct rcu_head *rcu) | |
31 | +{ | |
32 | + struct net_generic *ng; | |
33 | + | |
34 | + ng = container_of(rcu, struct net_generic, rcu); | |
35 | + kfree(ng); | |
36 | +} | |
37 | + | |
38 | +static int net_assign_generic(struct net *net, int id, void *data) | |
39 | +{ | |
40 | + struct net_generic *ng, *old_ng; | |
41 | + | |
42 | + BUG_ON(!mutex_is_locked(&net_mutex)); | |
43 | + BUG_ON(id == 0); | |
44 | + | |
45 | + ng = old_ng = net->gen; | |
46 | + if (old_ng->len >= id) | |
47 | + goto assign; | |
48 | + | |
49 | + ng = kzalloc(sizeof(struct net_generic) + | |
50 | + id * sizeof(void *), GFP_KERNEL); | |
51 | + if (ng == NULL) | |
52 | + return -ENOMEM; | |
53 | + | |
54 | + /* | |
55 | + * Some synchronisation notes: | |
56 | + * | |
57 | + * The net_generic explores the net->gen array inside rcu | |
58 | + * read section. Besides once set the net->gen->ptr[x] | |
59 | + * pointer never changes (see rules in netns/generic.h). | |
60 | + * | |
61 | + * That said, we simply duplicate this array and schedule | |
62 | + * the old copy for kfree after a grace period. | |
63 | + */ | |
64 | + | |
65 | + ng->len = id; | |
66 | + memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); | |
67 | + | |
68 | + rcu_assign_pointer(net->gen, ng); | |
69 | + call_rcu(&old_ng->rcu, net_generic_release); | |
70 | +assign: | |
71 | + ng->ptr[id - 1] = data; | |
72 | + return 0; | |
73 | +} | |
74 | + | |
30 | 75 | static int ops_init(const struct pernet_operations *ops, struct net *net) |
31 | 76 | { |
32 | 77 | int err; |
... | ... | @@ -526,50 +571,4 @@ |
526 | 571 | mutex_unlock(&net_mutex); |
527 | 572 | } |
528 | 573 | EXPORT_SYMBOL_GPL(unregister_pernet_device); |
529 | - | |
530 | -static void net_generic_release(struct rcu_head *rcu) | |
531 | -{ | |
532 | - struct net_generic *ng; | |
533 | - | |
534 | - ng = container_of(rcu, struct net_generic, rcu); | |
535 | - kfree(ng); | |
536 | -} | |
537 | - | |
538 | -int net_assign_generic(struct net *net, int id, void *data) | |
539 | -{ | |
540 | - struct net_generic *ng, *old_ng; | |
541 | - | |
542 | - BUG_ON(!mutex_is_locked(&net_mutex)); | |
543 | - BUG_ON(id == 0); | |
544 | - | |
545 | - ng = old_ng = net->gen; | |
546 | - if (old_ng->len >= id) | |
547 | - goto assign; | |
548 | - | |
549 | - ng = kzalloc(sizeof(struct net_generic) + | |
550 | - id * sizeof(void *), GFP_KERNEL); | |
551 | - if (ng == NULL) | |
552 | - return -ENOMEM; | |
553 | - | |
554 | - /* | |
555 | - * Some synchronisation notes: | |
556 | - * | |
557 | - * The net_generic explores the net->gen array inside rcu | |
558 | - * read section. Besides once set the net->gen->ptr[x] | |
559 | - * pointer never changes (see rules in netns/generic.h). | |
560 | - * | |
561 | - * That said, we simply duplicate this array and schedule | |
562 | - * the old copy for kfree after a grace period. | |
563 | - */ | |
564 | - | |
565 | - ng->len = id; | |
566 | - memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); | |
567 | - | |
568 | - rcu_assign_pointer(net->gen, ng); | |
569 | - call_rcu(&old_ng->rcu, net_generic_release); | |
570 | -assign: | |
571 | - ng->ptr[id - 1] = data; | |
572 | - return 0; | |
573 | -} | |
574 | -EXPORT_SYMBOL_GPL(net_assign_generic); |