diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 10:55:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 10:55:01 -0500 |
commit | d7fc02c7bae7b1cf69269992cf880a43a350cdaa (patch) | |
tree | a43d56fa72913a1cc98a0bbebe054d08581b3a7c /net/decnet/dn_dev.c | |
parent | ee1262dbc65ce0b6234a915d8432171e8d77f518 (diff) | |
parent | 28b4d5cc17c20786848cdc07b7ea237a309776bb (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: (1815 commits)
mac80211: fix reorder buffer release
iwmc3200wifi: Enable wimax core through module parameter
iwmc3200wifi: Add wifi-wimax coexistence mode as a module parameter
iwmc3200wifi: Coex table command does not expect a response
iwmc3200wifi: Update wiwi priority table
iwlwifi: driver version track kernel version
iwlwifi: indicate uCode type when fail dump error/event log
iwl3945: remove duplicated event logging code
b43: fix two warnings
ipw2100: fix rebooting hang with driver loaded
cfg80211: indent regulatory messages with spaces
iwmc3200wifi: fix NULL pointer dereference in pmkid update
mac80211: Fix TX status reporting for injected data frames
ath9k: enable 2GHz band only if the device supports it
airo: Fix integer overflow warning
rt2x00: Fix padding bug on L2PAD devices.
WE: Fix set events not propagated
b43legacy: avoid PPC fault during resume
b43: avoid PPC fault during resume
tcp: fix a timewait refcnt race
...
Fix up conflicts due to sysctl cleanups (dead sysctl_check code and
CTL_UNNUMBERED removed) in
kernel/sysctl_check.c
net/ipv4/sysctl_net_ipv4.c
net/ipv6/addrconf.c
net/sctp/sysctl.c
Diffstat (limited to 'net/decnet/dn_dev.c')
-rw-r--r-- | net/decnet/dn_dev.c | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 1b1daeb151f2..238af093495b 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -68,7 +68,7 @@ extern struct neigh_table dn_neigh_table; | |||
68 | */ | 68 | */ |
69 | __le16 decnet_address = 0; | 69 | __le16 decnet_address = 0; |
70 | 70 | ||
71 | static DEFINE_RWLOCK(dndev_lock); | 71 | static DEFINE_SPINLOCK(dndev_lock); |
72 | static struct net_device *decnet_default_device; | 72 | static struct net_device *decnet_default_device; |
73 | static BLOCKING_NOTIFIER_HEAD(dnaddr_chain); | 73 | static BLOCKING_NOTIFIER_HEAD(dnaddr_chain); |
74 | 74 | ||
@@ -499,7 +499,8 @@ rarok: | |||
499 | struct net_device *dn_dev_get_default(void) | 499 | struct net_device *dn_dev_get_default(void) |
500 | { | 500 | { |
501 | struct net_device *dev; | 501 | struct net_device *dev; |
502 | read_lock(&dndev_lock); | 502 | |
503 | spin_lock(&dndev_lock); | ||
503 | dev = decnet_default_device; | 504 | dev = decnet_default_device; |
504 | if (dev) { | 505 | if (dev) { |
505 | if (dev->dn_ptr) | 506 | if (dev->dn_ptr) |
@@ -507,7 +508,8 @@ struct net_device *dn_dev_get_default(void) | |||
507 | else | 508 | else |
508 | dev = NULL; | 509 | dev = NULL; |
509 | } | 510 | } |
510 | read_unlock(&dndev_lock); | 511 | spin_unlock(&dndev_lock); |
512 | |||
511 | return dev; | 513 | return dev; |
512 | } | 514 | } |
513 | 515 | ||
@@ -517,13 +519,15 @@ int dn_dev_set_default(struct net_device *dev, int force) | |||
517 | int rv = -EBUSY; | 519 | int rv = -EBUSY; |
518 | if (!dev->dn_ptr) | 520 | if (!dev->dn_ptr) |
519 | return -ENODEV; | 521 | return -ENODEV; |
520 | write_lock(&dndev_lock); | 522 | |
523 | spin_lock(&dndev_lock); | ||
521 | if (force || decnet_default_device == NULL) { | 524 | if (force || decnet_default_device == NULL) { |
522 | old = decnet_default_device; | 525 | old = decnet_default_device; |
523 | decnet_default_device = dev; | 526 | decnet_default_device = dev; |
524 | rv = 0; | 527 | rv = 0; |
525 | } | 528 | } |
526 | write_unlock(&dndev_lock); | 529 | spin_unlock(&dndev_lock); |
530 | |||
527 | if (old) | 531 | if (old) |
528 | dev_put(old); | 532 | dev_put(old); |
529 | return rv; | 533 | return rv; |
@@ -531,26 +535,29 @@ int dn_dev_set_default(struct net_device *dev, int force) | |||
531 | 535 | ||
532 | static void dn_dev_check_default(struct net_device *dev) | 536 | static void dn_dev_check_default(struct net_device *dev) |
533 | { | 537 | { |
534 | write_lock(&dndev_lock); | 538 | spin_lock(&dndev_lock); |
535 | if (dev == decnet_default_device) { | 539 | if (dev == decnet_default_device) { |
536 | decnet_default_device = NULL; | 540 | decnet_default_device = NULL; |
537 | } else { | 541 | } else { |
538 | dev = NULL; | 542 | dev = NULL; |
539 | } | 543 | } |
540 | write_unlock(&dndev_lock); | 544 | spin_unlock(&dndev_lock); |
545 | |||
541 | if (dev) | 546 | if (dev) |
542 | dev_put(dev); | 547 | dev_put(dev); |
543 | } | 548 | } |
544 | 549 | ||
550 | /* | ||
551 | * Called with RTNL | ||
552 | */ | ||
545 | static struct dn_dev *dn_dev_by_index(int ifindex) | 553 | static struct dn_dev *dn_dev_by_index(int ifindex) |
546 | { | 554 | { |
547 | struct net_device *dev; | 555 | struct net_device *dev; |
548 | struct dn_dev *dn_dev = NULL; | 556 | struct dn_dev *dn_dev = NULL; |
549 | dev = dev_get_by_index(&init_net, ifindex); | 557 | |
550 | if (dev) { | 558 | dev = __dev_get_by_index(&init_net, ifindex); |
559 | if (dev) | ||
551 | dn_dev = dev->dn_ptr; | 560 | dn_dev = dev->dn_ptr; |
552 | dev_put(dev); | ||
553 | } | ||
554 | 561 | ||
555 | return dn_dev; | 562 | return dn_dev; |
556 | } | 563 | } |
@@ -571,7 +578,7 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
571 | struct dn_ifaddr *ifa, **ifap; | 578 | struct dn_ifaddr *ifa, **ifap; |
572 | int err = -EINVAL; | 579 | int err = -EINVAL; |
573 | 580 | ||
574 | if (net != &init_net) | 581 | if (!net_eq(net, &init_net)) |
575 | goto errout; | 582 | goto errout; |
576 | 583 | ||
577 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); | 584 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); |
@@ -610,7 +617,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
610 | struct dn_ifaddr *ifa; | 617 | struct dn_ifaddr *ifa; |
611 | int err; | 618 | int err; |
612 | 619 | ||
613 | if (net != &init_net) | 620 | if (!net_eq(net, &init_net)) |
614 | return -EINVAL; | 621 | return -EINVAL; |
615 | 622 | ||
616 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); | 623 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); |
@@ -724,7 +731,7 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) | |||
724 | struct dn_dev *dn_db; | 731 | struct dn_dev *dn_db; |
725 | struct dn_ifaddr *ifa; | 732 | struct dn_ifaddr *ifa; |
726 | 733 | ||
727 | if (net != &init_net) | 734 | if (!net_eq(net, &init_net)) |
728 | return 0; | 735 | return 0; |
729 | 736 | ||
730 | skip_ndevs = cb->args[0]; | 737 | skip_ndevs = cb->args[0]; |
@@ -768,13 +775,17 @@ static int dn_dev_get_first(struct net_device *dev, __le16 *addr) | |||
768 | struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; | 775 | struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; |
769 | struct dn_ifaddr *ifa; | 776 | struct dn_ifaddr *ifa; |
770 | int rv = -ENODEV; | 777 | int rv = -ENODEV; |
778 | |||
771 | if (dn_db == NULL) | 779 | if (dn_db == NULL) |
772 | goto out; | 780 | goto out; |
781 | |||
782 | rtnl_lock(); | ||
773 | ifa = dn_db->ifa_list; | 783 | ifa = dn_db->ifa_list; |
774 | if (ifa != NULL) { | 784 | if (ifa != NULL) { |
775 | *addr = ifa->ifa_local; | 785 | *addr = ifa->ifa_local; |
776 | rv = 0; | 786 | rv = 0; |
777 | } | 787 | } |
788 | rtnl_unlock(); | ||
778 | out: | 789 | out: |
779 | return rv; | 790 | return rv; |
780 | } | 791 | } |
@@ -796,9 +807,7 @@ int dn_dev_bind_default(__le16 *addr) | |||
796 | dev = dn_dev_get_default(); | 807 | dev = dn_dev_get_default(); |
797 | last_chance: | 808 | last_chance: |
798 | if (dev) { | 809 | if (dev) { |
799 | read_lock(&dev_base_lock); | ||
800 | rv = dn_dev_get_first(dev, addr); | 810 | rv = dn_dev_get_first(dev, addr); |
801 | read_unlock(&dev_base_lock); | ||
802 | dev_put(dev); | 811 | dev_put(dev); |
803 | if (rv == 0 || dev == init_net.loopback_dev) | 812 | if (rv == 0 || dev == init_net.loopback_dev) |
804 | return rv; | 813 | return rv; |
@@ -1263,18 +1272,18 @@ static inline int is_dn_dev(struct net_device *dev) | |||
1263 | } | 1272 | } |
1264 | 1273 | ||
1265 | static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) | 1274 | static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) |
1266 | __acquires(&dev_base_lock) | 1275 | __acquires(rcu) |
1267 | { | 1276 | { |
1268 | int i; | 1277 | int i; |
1269 | struct net_device *dev; | 1278 | struct net_device *dev; |
1270 | 1279 | ||
1271 | read_lock(&dev_base_lock); | 1280 | rcu_read_lock(); |
1272 | 1281 | ||
1273 | if (*pos == 0) | 1282 | if (*pos == 0) |
1274 | return SEQ_START_TOKEN; | 1283 | return SEQ_START_TOKEN; |
1275 | 1284 | ||
1276 | i = 1; | 1285 | i = 1; |
1277 | for_each_netdev(&init_net, dev) { | 1286 | for_each_netdev_rcu(&init_net, dev) { |
1278 | if (!is_dn_dev(dev)) | 1287 | if (!is_dn_dev(dev)) |
1279 | continue; | 1288 | continue; |
1280 | 1289 | ||
@@ -1295,7 +1304,7 @@ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1295 | if (v == SEQ_START_TOKEN) | 1304 | if (v == SEQ_START_TOKEN) |
1296 | dev = net_device_entry(&init_net.dev_base_head); | 1305 | dev = net_device_entry(&init_net.dev_base_head); |
1297 | 1306 | ||
1298 | for_each_netdev_continue(&init_net, dev) { | 1307 | for_each_netdev_continue_rcu(&init_net, dev) { |
1299 | if (!is_dn_dev(dev)) | 1308 | if (!is_dn_dev(dev)) |
1300 | continue; | 1309 | continue; |
1301 | 1310 | ||
@@ -1306,9 +1315,9 @@ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1306 | } | 1315 | } |
1307 | 1316 | ||
1308 | static void dn_dev_seq_stop(struct seq_file *seq, void *v) | 1317 | static void dn_dev_seq_stop(struct seq_file *seq, void *v) |
1309 | __releases(&dev_base_lock) | 1318 | __releases(rcu) |
1310 | { | 1319 | { |
1311 | read_unlock(&dev_base_lock); | 1320 | rcu_read_unlock(); |
1312 | } | 1321 | } |
1313 | 1322 | ||
1314 | static char *dn_type2asc(char type) | 1323 | static char *dn_type2asc(char type) |