Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
[safe/jmp/linux-2.6] / net / decnet / dn_dev.c
index 1b1daeb..238af09 100644 (file)
@@ -68,7 +68,7 @@ extern struct neigh_table dn_neigh_table;
  */
 __le16 decnet_address = 0;
 
-static DEFINE_RWLOCK(dndev_lock);
+static DEFINE_SPINLOCK(dndev_lock);
 static struct net_device *decnet_default_device;
 static BLOCKING_NOTIFIER_HEAD(dnaddr_chain);
 
@@ -499,7 +499,8 @@ rarok:
 struct net_device *dn_dev_get_default(void)
 {
        struct net_device *dev;
-       read_lock(&dndev_lock);
+
+       spin_lock(&dndev_lock);
        dev = decnet_default_device;
        if (dev) {
                if (dev->dn_ptr)
@@ -507,7 +508,8 @@ struct net_device *dn_dev_get_default(void)
                else
                        dev = NULL;
        }
-       read_unlock(&dndev_lock);
+       spin_unlock(&dndev_lock);
+
        return dev;
 }
 
@@ -517,13 +519,15 @@ int dn_dev_set_default(struct net_device *dev, int force)
        int rv = -EBUSY;
        if (!dev->dn_ptr)
                return -ENODEV;
-       write_lock(&dndev_lock);
+
+       spin_lock(&dndev_lock);
        if (force || decnet_default_device == NULL) {
                old = decnet_default_device;
                decnet_default_device = dev;
                rv = 0;
        }
-       write_unlock(&dndev_lock);
+       spin_unlock(&dndev_lock);
+
        if (old)
                dev_put(old);
        return rv;
@@ -531,26 +535,29 @@ int dn_dev_set_default(struct net_device *dev, int force)
 
 static void dn_dev_check_default(struct net_device *dev)
 {
-       write_lock(&dndev_lock);
+       spin_lock(&dndev_lock);
        if (dev == decnet_default_device) {
                decnet_default_device = NULL;
        } else {
                dev = NULL;
        }
-       write_unlock(&dndev_lock);
+       spin_unlock(&dndev_lock);
+
        if (dev)
                dev_put(dev);
 }
 
+/*
+ * Called with RTNL
+ */
 static struct dn_dev *dn_dev_by_index(int ifindex)
 {
        struct net_device *dev;
        struct dn_dev *dn_dev = NULL;
-       dev = dev_get_by_index(&init_net, ifindex);
-       if (dev) {
+
+       dev = __dev_get_by_index(&init_net, ifindex);
+       if (dev)
                dn_dev = dev->dn_ptr;
-               dev_put(dev);
-       }
 
        return dn_dev;
 }
@@ -571,7 +578,7 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        struct dn_ifaddr *ifa, **ifap;
        int err = -EINVAL;
 
-       if (net != &init_net)
+       if (!net_eq(net, &init_net))
                goto errout;
 
        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)
        struct dn_ifaddr *ifa;
        int err;
 
-       if (net != &init_net)
+       if (!net_eq(net, &init_net))
                return -EINVAL;
 
        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)
        struct dn_dev *dn_db;
        struct dn_ifaddr *ifa;
 
-       if (net != &init_net)
+       if (!net_eq(net, &init_net))
                return 0;
 
        skip_ndevs = cb->args[0];
@@ -768,13 +775,17 @@ static int dn_dev_get_first(struct net_device *dev, __le16 *addr)
        struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr;
        struct dn_ifaddr *ifa;
        int rv = -ENODEV;
+
        if (dn_db == NULL)
                goto out;
+
+       rtnl_lock();
        ifa = dn_db->ifa_list;
        if (ifa != NULL) {
                *addr = ifa->ifa_local;
                rv = 0;
        }
+       rtnl_unlock();
 out:
        return rv;
 }
@@ -796,9 +807,7 @@ int dn_dev_bind_default(__le16 *addr)
        dev = dn_dev_get_default();
 last_chance:
        if (dev) {
-               read_lock(&dev_base_lock);
                rv = dn_dev_get_first(dev, addr);
-               read_unlock(&dev_base_lock);
                dev_put(dev);
                if (rv == 0 || dev == init_net.loopback_dev)
                        return rv;
@@ -1263,18 +1272,18 @@ static inline int is_dn_dev(struct net_device *dev)
 }
 
 static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos)
-       __acquires(&dev_base_lock)
+       __acquires(rcu)
 {
        int i;
        struct net_device *dev;
 
-       read_lock(&dev_base_lock);
+       rcu_read_lock();
 
        if (*pos == 0)
                return SEQ_START_TOKEN;
 
        i = 1;
-       for_each_netdev(&init_net, dev) {
+       for_each_netdev_rcu(&init_net, dev) {
                if (!is_dn_dev(dev))
                        continue;
 
@@ -1295,7 +1304,7 @@ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
        if (v == SEQ_START_TOKEN)
                dev = net_device_entry(&init_net.dev_base_head);
 
-       for_each_netdev_continue(&init_net, dev) {
+       for_each_netdev_continue_rcu(&init_net, dev) {
                if (!is_dn_dev(dev))
                        continue;
 
@@ -1306,9 +1315,9 @@ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void dn_dev_seq_stop(struct seq_file *seq, void *v)
-       __releases(&dev_base_lock)
+       __releases(rcu)
 {
-       read_unlock(&dev_base_lock);
+       rcu_read_unlock();
 }
 
 static char *dn_type2asc(char type)