diff options
Diffstat (limited to 'net/tipc/net.c')
-rw-r--r-- | net/tipc/net.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/net/tipc/net.c b/net/tipc/net.c index 62199cf5a56c..f076edb74338 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c | |||
@@ -104,6 +104,14 @@ | |||
104 | * - A local spin_lock protecting the queue of subscriber events. | 104 | * - A local spin_lock protecting the queue of subscriber events. |
105 | */ | 105 | */ |
106 | 106 | ||
107 | struct tipc_net_work { | ||
108 | struct work_struct work; | ||
109 | struct net *net; | ||
110 | u32 addr; | ||
111 | }; | ||
112 | |||
113 | static void tipc_net_finalize(struct net *net, u32 addr); | ||
114 | |||
107 | int tipc_net_init(struct net *net, u8 *node_id, u32 addr) | 115 | int tipc_net_init(struct net *net, u8 *node_id, u32 addr) |
108 | { | 116 | { |
109 | if (tipc_own_id(net)) { | 117 | if (tipc_own_id(net)) { |
@@ -119,17 +127,38 @@ int tipc_net_init(struct net *net, u8 *node_id, u32 addr) | |||
119 | return 0; | 127 | return 0; |
120 | } | 128 | } |
121 | 129 | ||
122 | void tipc_net_finalize(struct net *net, u32 addr) | 130 | static void tipc_net_finalize(struct net *net, u32 addr) |
123 | { | 131 | { |
124 | struct tipc_net *tn = tipc_net(net); | 132 | struct tipc_net *tn = tipc_net(net); |
125 | 133 | ||
126 | if (!cmpxchg(&tn->node_addr, 0, addr)) { | 134 | if (cmpxchg(&tn->node_addr, 0, addr)) |
127 | tipc_set_node_addr(net, addr); | 135 | return; |
128 | tipc_named_reinit(net); | 136 | tipc_set_node_addr(net, addr); |
129 | tipc_sk_reinit(net); | 137 | tipc_named_reinit(net); |
130 | tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr, | 138 | tipc_sk_reinit(net); |
131 | TIPC_CLUSTER_SCOPE, 0, addr); | 139 | tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr, |
132 | } | 140 | TIPC_CLUSTER_SCOPE, 0, addr); |
141 | } | ||
142 | |||
143 | static void tipc_net_finalize_work(struct work_struct *work) | ||
144 | { | ||
145 | struct tipc_net_work *fwork; | ||
146 | |||
147 | fwork = container_of(work, struct tipc_net_work, work); | ||
148 | tipc_net_finalize(fwork->net, fwork->addr); | ||
149 | kfree(fwork); | ||
150 | } | ||
151 | |||
152 | void tipc_sched_net_finalize(struct net *net, u32 addr) | ||
153 | { | ||
154 | struct tipc_net_work *fwork = kzalloc(sizeof(*fwork), GFP_ATOMIC); | ||
155 | |||
156 | if (!fwork) | ||
157 | return; | ||
158 | INIT_WORK(&fwork->work, tipc_net_finalize_work); | ||
159 | fwork->net = net; | ||
160 | fwork->addr = addr; | ||
161 | schedule_work(&fwork->work); | ||
133 | } | 162 | } |
134 | 163 | ||
135 | void tipc_net_stop(struct net *net) | 164 | void tipc_net_stop(struct net *net) |