aboutsummaryrefslogtreecommitdiffstats
path: root/net/decnet/dn_dev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 10:55:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 10:55:01 -0500
commitd7fc02c7bae7b1cf69269992cf880a43a350cdaa (patch)
treea43d56fa72913a1cc98a0bbebe054d08581b3a7c /net/decnet/dn_dev.c
parentee1262dbc65ce0b6234a915d8432171e8d77f518 (diff)
parent28b4d5cc17c20786848cdc07b7ea237a309776bb (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.c53
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
71static DEFINE_RWLOCK(dndev_lock); 71static DEFINE_SPINLOCK(dndev_lock);
72static struct net_device *decnet_default_device; 72static struct net_device *decnet_default_device;
73static BLOCKING_NOTIFIER_HEAD(dnaddr_chain); 73static BLOCKING_NOTIFIER_HEAD(dnaddr_chain);
74 74
@@ -499,7 +499,8 @@ rarok:
499struct net_device *dn_dev_get_default(void) 499struct 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
532static void dn_dev_check_default(struct net_device *dev) 536static 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 */
545static struct dn_dev *dn_dev_by_index(int ifindex) 553static 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();
778out: 789out:
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();
797last_chance: 808last_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
1265static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) 1274static 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
1308static void dn_dev_seq_stop(struct seq_file *seq, void *v) 1317static 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
1314static char *dn_type2asc(char type) 1323static char *dn_type2asc(char type)