diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2009-12-03 15:22:55 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-03 15:22:55 -0500 |
commit | e9c5158ac26affd5d8ce006521bdfb7148090e18 (patch) | |
tree | a8d43fb446a1908175923f4109c977dcb84e4f91 /net/decnet | |
parent | 3a765edadb28cc736d185f67d1ba6bedcc85f4b9 (diff) |
net: Allow fib_rule_unregister to batch
Refactor the code so fib_rules_register always takes a template instead
of the actual fib_rules_ops structure that will be used. This is
required for network namespace support so 2 out of the 3 callers already
do this, it allows the error handling to be made common, and it allows
fib_rules_unregister to free the template for hte caller.
Modify fib_rules_unregister to use call_rcu instead of syncrhonize_rcu
to allw multiple namespaces to be cleaned up in the same rcu grace
period.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/decnet')
-rw-r--r-- | net/decnet/dn_rules.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 72495f25269f..7466c546f286 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <net/dn_dev.h> | 33 | #include <net/dn_dev.h> |
34 | #include <net/dn_route.h> | 34 | #include <net/dn_route.h> |
35 | 35 | ||
36 | static struct fib_rules_ops dn_fib_rules_ops; | 36 | static struct fib_rules_ops *dn_fib_rules_ops; |
37 | 37 | ||
38 | struct dn_fib_rule | 38 | struct dn_fib_rule |
39 | { | 39 | { |
@@ -56,7 +56,7 @@ int dn_fib_lookup(struct flowi *flp, struct dn_fib_res *res) | |||
56 | }; | 56 | }; |
57 | int err; | 57 | int err; |
58 | 58 | ||
59 | err = fib_rules_lookup(&dn_fib_rules_ops, flp, 0, &arg); | 59 | err = fib_rules_lookup(dn_fib_rules_ops, flp, 0, &arg); |
60 | res->r = arg.rule; | 60 | res->r = arg.rule; |
61 | 61 | ||
62 | return err; | 62 | return err; |
@@ -217,9 +217,9 @@ static u32 dn_fib_rule_default_pref(struct fib_rules_ops *ops) | |||
217 | struct list_head *pos; | 217 | struct list_head *pos; |
218 | struct fib_rule *rule; | 218 | struct fib_rule *rule; |
219 | 219 | ||
220 | if (!list_empty(&dn_fib_rules_ops.rules_list)) { | 220 | if (!list_empty(&dn_fib_rules_ops->rules_list)) { |
221 | pos = dn_fib_rules_ops.rules_list.next; | 221 | pos = dn_fib_rules_ops->rules_list.next; |
222 | if (pos->next != &dn_fib_rules_ops.rules_list) { | 222 | if (pos->next != &dn_fib_rules_ops->rules_list) { |
223 | rule = list_entry(pos->next, struct fib_rule, list); | 223 | rule = list_entry(pos->next, struct fib_rule, list); |
224 | if (rule->pref) | 224 | if (rule->pref) |
225 | return rule->pref - 1; | 225 | return rule->pref - 1; |
@@ -234,7 +234,7 @@ static void dn_fib_rule_flush_cache(struct fib_rules_ops *ops) | |||
234 | dn_rt_cache_flush(-1); | 234 | dn_rt_cache_flush(-1); |
235 | } | 235 | } |
236 | 236 | ||
237 | static struct fib_rules_ops dn_fib_rules_ops = { | 237 | static struct fib_rules_ops dn_fib_rules_ops_template = { |
238 | .family = AF_DECnet, | 238 | .family = AF_DECnet, |
239 | .rule_size = sizeof(struct dn_fib_rule), | 239 | .rule_size = sizeof(struct dn_fib_rule), |
240 | .addr_size = sizeof(u16), | 240 | .addr_size = sizeof(u16), |
@@ -247,21 +247,23 @@ static struct fib_rules_ops dn_fib_rules_ops = { | |||
247 | .flush_cache = dn_fib_rule_flush_cache, | 247 | .flush_cache = dn_fib_rule_flush_cache, |
248 | .nlgroup = RTNLGRP_DECnet_RULE, | 248 | .nlgroup = RTNLGRP_DECnet_RULE, |
249 | .policy = dn_fib_rule_policy, | 249 | .policy = dn_fib_rule_policy, |
250 | .rules_list = LIST_HEAD_INIT(dn_fib_rules_ops.rules_list), | ||
251 | .owner = THIS_MODULE, | 250 | .owner = THIS_MODULE, |
252 | .fro_net = &init_net, | 251 | .fro_net = &init_net, |
253 | }; | 252 | }; |
254 | 253 | ||
255 | void __init dn_fib_rules_init(void) | 254 | void __init dn_fib_rules_init(void) |
256 | { | 255 | { |
257 | BUG_ON(fib_default_rule_add(&dn_fib_rules_ops, 0x7fff, | 256 | dn_fib_rules_ops = |
257 | fib_rules_register(&dn_fib_rules_ops_template, &init_net); | ||
258 | BUG_ON(IS_ERR(dn_fib_rules_ops)); | ||
259 | BUG_ON(fib_default_rule_add(dn_fib_rules_ops, 0x7fff, | ||
258 | RT_TABLE_MAIN, 0)); | 260 | RT_TABLE_MAIN, 0)); |
259 | fib_rules_register(&dn_fib_rules_ops); | ||
260 | } | 261 | } |
261 | 262 | ||
262 | void __exit dn_fib_rules_cleanup(void) | 263 | void __exit dn_fib_rules_cleanup(void) |
263 | { | 264 | { |
264 | fib_rules_unregister(&dn_fib_rules_ops); | 265 | fib_rules_unregister(dn_fib_rules_ops); |
266 | rcu_barrier(); | ||
265 | } | 267 | } |
266 | 268 | ||
267 | 269 | ||