Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[safe/jmp/linux-2.6] / net / ipv4 / igmp.c
index 01b4284..76c0840 100644 (file)
@@ -1298,6 +1298,28 @@ void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
        }
 }
 
+/* Device changing type */
+
+void ip_mc_unmap(struct in_device *in_dev)
+{
+       struct ip_mc_list *i;
+
+       ASSERT_RTNL();
+
+       for (i = in_dev->mc_list; i; i = i->next)
+               igmp_group_dropped(i);
+}
+
+void ip_mc_remap(struct in_device *in_dev)
+{
+       struct ip_mc_list *i;
+
+       ASSERT_RTNL();
+
+       for (i = in_dev->mc_list; i; i = i->next)
+               igmp_group_added(i);
+}
+
 /* Device going down */
 
 void ip_mc_down(struct in_device *in_dev)
@@ -1877,8 +1899,9 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
        err = -EADDRNOTAVAIL;
 
        for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
-               if (pmc->multi.imr_multiaddr.s_addr == imr.imr_multiaddr.s_addr
-                   && pmc->multi.imr_ifindex == imr.imr_ifindex)
+               if ((pmc->multi.imr_multiaddr.s_addr ==
+                    imr.imr_multiaddr.s_addr) &&
+                   (pmc->multi.imr_ifindex == imr.imr_ifindex))
                        break;
        }
        if (!pmc) {             /* must have a prior join */
@@ -2289,9 +2312,10 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
        struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
 
        state->in_dev = NULL;
-       for_each_netdev(net, state->dev) {
+       for_each_netdev_rcu(net, state->dev) {
                struct in_device *in_dev;
-               in_dev = in_dev_get(state->dev);
+
+               in_dev = __in_dev_get_rcu(state->dev);
                if (!in_dev)
                        continue;
                read_lock(&in_dev->mc_list_lock);
@@ -2301,7 +2325,6 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
                        break;
                }
                read_unlock(&in_dev->mc_list_lock);
-               in_dev_put(in_dev);
        }
        return im;
 }
@@ -2311,16 +2334,15 @@ static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_li
        struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
        im = im->next;
        while (!im) {
-               if (likely(state->in_dev != NULL)) {
+               if (likely(state->in_dev != NULL))
                        read_unlock(&state->in_dev->mc_list_lock);
-                       in_dev_put(state->in_dev);
-               }
-               state->dev = next_net_device(state->dev);
+
+               state->dev = next_net_device_rcu(state->dev);
                if (!state->dev) {
                        state->in_dev = NULL;
                        break;
                }
-               state->in_dev = in_dev_get(state->dev);
+               state->in_dev = __in_dev_get_rcu(state->dev);
                if (!state->in_dev)
                        continue;
                read_lock(&state->in_dev->mc_list_lock);
@@ -2339,9 +2361,9 @@ static struct ip_mc_list *igmp_mc_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos)
-       __acquires(dev_base_lock)
+       __acquires(rcu)
 {
-       read_lock(&dev_base_lock);
+       rcu_read_lock();
        return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
 }
 
@@ -2357,16 +2379,15 @@ static void *igmp_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void igmp_mc_seq_stop(struct seq_file *seq, void *v)
-       __releases(dev_base_lock)
+       __releases(rcu)
 {
        struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
        if (likely(state->in_dev != NULL)) {
                read_unlock(&state->in_dev->mc_list_lock);
-               in_dev_put(state->in_dev);
                state->in_dev = NULL;
        }
        state->dev = NULL;
-       read_unlock(&dev_base_lock);
+       rcu_read_unlock();
 }
 
 static int igmp_mc_seq_show(struct seq_file *seq, void *v)
@@ -2440,9 +2461,9 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
 
        state->idev = NULL;
        state->im = NULL;
-       for_each_netdev(net, state->dev) {
+       for_each_netdev_rcu(net, state->dev) {
                struct in_device *idev;
-               idev = in_dev_get(state->dev);
+               idev = __in_dev_get_rcu(state->dev);
                if (unlikely(idev == NULL))
                        continue;
                read_lock(&idev->mc_list_lock);
@@ -2458,7 +2479,6 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
                        spin_unlock_bh(&im->lock);
                }
                read_unlock(&idev->mc_list_lock);
-               in_dev_put(idev);
        }
        return psf;
 }
@@ -2472,16 +2492,15 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l
                spin_unlock_bh(&state->im->lock);
                state->im = state->im->next;
                while (!state->im) {
-                       if (likely(state->idev != NULL)) {
+                       if (likely(state->idev != NULL))
                                read_unlock(&state->idev->mc_list_lock);
-                               in_dev_put(state->idev);
-                       }
-                       state->dev = next_net_device(state->dev);
+
+                       state->dev = next_net_device_rcu(state->dev);
                        if (!state->dev) {
                                state->idev = NULL;
                                goto out;
                        }
-                       state->idev = in_dev_get(state->dev);
+                       state->idev = __in_dev_get_rcu(state->dev);
                        if (!state->idev)
                                continue;
                        read_lock(&state->idev->mc_list_lock);
@@ -2506,8 +2525,9 @@ static struct ip_sf_list *igmp_mcf_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *igmp_mcf_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(rcu)
 {
-       read_lock(&dev_base_lock);
+       rcu_read_lock();
        return *pos ? igmp_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
 }
 
@@ -2523,6 +2543,7 @@ static void *igmp_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void igmp_mcf_seq_stop(struct seq_file *seq, void *v)
+       __releases(rcu)
 {
        struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq);
        if (likely(state->im != NULL)) {
@@ -2531,11 +2552,10 @@ static void igmp_mcf_seq_stop(struct seq_file *seq, void *v)
        }
        if (likely(state->idev != NULL)) {
                read_unlock(&state->idev->mc_list_lock);
-               in_dev_put(state->idev);
                state->idev = NULL;
        }
        state->dev = NULL;
-       read_unlock(&dev_base_lock);
+       rcu_read_unlock();
 }
 
 static int igmp_mcf_seq_show(struct seq_file *seq, void *v)