diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 00:04:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 00:04:44 -0400 |
commit | f8965467f366fd18f01feafb5db10512d7b4422c (patch) | |
tree | 3706a9cd779859271ca61b85c63a1bc3f82d626e /net/core/net_namespace.c | |
parent | a26272e5200765691e67d6780e52b32498fdb659 (diff) | |
parent | 2ec8c6bb5d8f3a62a79f463525054bae1e3d4487 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1674 commits)
qlcnic: adding co maintainer
ixgbe: add support for active DA cables
ixgbe: dcb, do not tag tc_prio_control frames
ixgbe: fix ixgbe_tx_is_paused logic
ixgbe: always enable vlan strip/insert when DCB is enabled
ixgbe: remove some redundant code in setting FCoE FIP filter
ixgbe: fix wrong offset to fc_frame_header in ixgbe_fcoe_ddp
ixgbe: fix header len when unsplit packet overflows to data buffer
ipv6: Never schedule DAD timer on dead address
ipv6: Use POSTDAD state
ipv6: Use state_lock to protect ifa state
ipv6: Replace inet6_ifaddr->dead with state
cxgb4: notify upper drivers if the device is already up when they load
cxgb4: keep interrupts available when the ports are brought down
cxgb4: fix initial addition of MAC address
cnic: Return SPQ credit to bnx2x after ring setup and shutdown.
cnic: Convert cnic_local_flags to atomic ops.
can: Fix SJA1000 command register writes on SMP systems
bridge: fix build for CONFIG_SYSFS disabled
ARCNET: Limit com20020 PCI ID matches for SOHARD cards
...
Fix up various conflicts with pcmcia tree drivers/net/
{pcmcia/3c589_cs.c, wireless/orinoco/orinoco_cs.c and
wireless/orinoco/spectrum_cs.c} and feature removal
(Documentation/feature-removal-schedule.txt).
Also fix a non-content conflict due to pm_qos_requirement getting
renamed in the PM tree (now pm_qos_request) in net/mac80211/scan.c
Diffstat (limited to 'net/core/net_namespace.c')
-rw-r--r-- | net/core/net_namespace.c | 95 |
1 files changed, 47 insertions, 48 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index bd8c4712ea24..c988e685433a 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -27,6 +27,51 @@ EXPORT_SYMBOL(init_net); | |||
27 | 27 | ||
28 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ | 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 | static int ops_init(const struct pernet_operations *ops, struct net *net) | 75 | static int ops_init(const struct pernet_operations *ops, struct net *net) |
31 | { | 76 | { |
32 | int err; | 77 | int err; |
@@ -469,10 +514,10 @@ EXPORT_SYMBOL_GPL(register_pernet_subsys); | |||
469 | * addition run the exit method for all existing network | 514 | * addition run the exit method for all existing network |
470 | * namespaces. | 515 | * namespaces. |
471 | */ | 516 | */ |
472 | void unregister_pernet_subsys(struct pernet_operations *module) | 517 | void unregister_pernet_subsys(struct pernet_operations *ops) |
473 | { | 518 | { |
474 | mutex_lock(&net_mutex); | 519 | mutex_lock(&net_mutex); |
475 | unregister_pernet_operations(module); | 520 | unregister_pernet_operations(ops); |
476 | mutex_unlock(&net_mutex); | 521 | mutex_unlock(&net_mutex); |
477 | } | 522 | } |
478 | EXPORT_SYMBOL_GPL(unregister_pernet_subsys); | 523 | EXPORT_SYMBOL_GPL(unregister_pernet_subsys); |
@@ -526,49 +571,3 @@ void unregister_pernet_device(struct pernet_operations *ops) | |||
526 | mutex_unlock(&net_mutex); | 571 | mutex_unlock(&net_mutex); |
527 | } | 572 | } |
528 | EXPORT_SYMBOL_GPL(unregister_pernet_device); | 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); | ||