Cleanup of net_device list use in seq_file output routines in core networking
files.  Implementation of /proc/net/dev was copied from dev_mcast, since the
latter did the same in a more compact and cleaner way.

The cleanup consists of
 - converting the to list_head, to make the list double-linked (thus making
   remove operation O(1)), and list walks more readable;
 - introducing of for_each_netdev wrapper over list_for_each.

Signed-off-by: Andrey Savochkin <[EMAIL PROTECTED]>
---
Note: functions covered by this patch are good candidates for further
restructuring by introduction of "library" routines for seq_file's showing some
information for each device.

 core/dev.c       |   23 +++++++++++------------
 core/dev_mcast.c |    4 ++--
 ipv4/igmp.c      |   25 +++++++++++++++----------
 ipv6/anycast.c   |   12 +++++++-----
 ipv6/mcast.c     |   25 +++++++++++++++----------
 5 files changed, 50 insertions(+), 39 deletions(-)

--- ./net/core/dev.c.vedevbase-proc     Mon Jul  3 16:09:54 2006
+++ ./net/core/dev.c    Mon Jul  3 16:09:54 2006
@@ -2072,26 +2072,25 @@ static int dev_ifconf(char __user *arg)
  *     This is invoked by the /proc filesystem handler to display a device
  *     in detail.
  */
-static __inline__ struct net_device *dev_get_idx(loff_t pos)
-{
-       struct net_device *dev;
-       loff_t i;
-
-       for (i = 0, dev = dev_base; dev && i < pos; ++i, dev = dev->next);
-
-       return i == pos ? dev : NULL;
-}
-
 void *dev_seq_start(struct seq_file *seq, loff_t *pos)
 {
+       struct net_device *dev;
+       loff_t off = 1;
        read_lock(&dev_base_lock);
-       return *pos ? dev_get_idx(*pos - 1) : SEQ_START_TOKEN;
+       if (!*pos)
+               return SEQ_START_TOKEN;
+       for_each_netdev(dev) {
+               if (off++ == *pos)
+                       return dev;
+       }
+       return NULL;
 }
 
 void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
+       struct net_device *dev = v;
        ++*pos;
-       return v == SEQ_START_TOKEN ? dev_base : ((struct net_device *)v)->next;
+       return v == SEQ_START_TOKEN ? first_netdev() : next_netdev(dev);
 }
 
 void dev_seq_stop(struct seq_file *seq, void *v)
--- ./net/core/dev_mcast.c.vedevbase-proc       Mon Jul  3 15:14:19 2006
+++ ./net/core/dev_mcast.c      Mon Jul  3 16:09:54 2006
@@ -225,7 +225,7 @@ static void *dev_mc_seq_start(struct seq
        loff_t off = 0;
 
        read_lock(&dev_base_lock);
-       for (dev = dev_base; dev; dev = dev->next) {
+       for_each_netdev(dev) {
                if (off++ == *pos) 
                        return dev;
        }
@@ -236,7 +236,7 @@ static void *dev_mc_seq_next(struct seq_
 {
        struct net_device *dev = v;
        ++*pos;
-       return dev->next;
+       return next_netdev(dev);
 }
 
 static void dev_mc_seq_stop(struct seq_file *seq, void *v)
--- ./net/ipv4/igmp.c.vedevbase-proc    Mon Jul  3 15:14:20 2006
+++ ./net/ipv4/igmp.c   Mon Jul  3 16:09:54 2006
@@ -2254,19 +2254,21 @@ struct igmp_mc_iter_state {
 
 static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
 {
+       struct net_device *dev;
        struct ip_mc_list *im = NULL;
        struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
 
-       for (state->dev = dev_base, state->in_dev = NULL;
-            state->dev; 
-            state->dev = state->dev->next) {
+       state->dev = NULL;
+       state->in_dev = NULL;
+       for_each_netdev(dev) {
                struct in_device *in_dev;
-               in_dev = in_dev_get(state->dev);
+               in_dev = in_dev_get(dev);
                if (!in_dev)
                        continue;
                read_lock(&in_dev->mc_list_lock);
                im = in_dev->mc_list;
                if (im) {
+                       state->dev = dev;
                        state->in_dev = in_dev;
                        break;
                }
@@ -2285,7 +2287,7 @@ static struct ip_mc_list *igmp_mc_get_ne
                        read_unlock(&state->in_dev->mc_list_lock);
                        in_dev_put(state->in_dev);
                }
-               state->dev = state->dev->next;
+               state->dev = next_netdev(state->dev);
                if (!state->dev) {
                        state->in_dev = NULL;
                        break;
@@ -2416,15 +2418,17 @@ struct igmp_mcf_iter_state {
 
 static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
 {
+       struct net_device *dev;
        struct ip_sf_list *psf = NULL;
        struct ip_mc_list *im = NULL;
        struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq);
 
-       for (state->dev = dev_base, state->idev = NULL, state->im = NULL;
-            state->dev; 
-            state->dev = state->dev->next) {
+       state->dev = NULL;
+       state->im = NULL;
+       state->idev = NULL;
+       for_each_netdev(dev) {
                struct in_device *idev;
-               idev = in_dev_get(state->dev);
+               idev = in_dev_get(dev);
                if (unlikely(idev == NULL))
                        continue;
                read_lock(&idev->mc_list_lock);
@@ -2433,6 +2437,7 @@ static inline struct ip_sf_list *igmp_mc
                        spin_lock_bh(&im->lock);
                        psf = im->sources;
                        if (likely(psf != NULL)) {
+                               state->dev = dev;
                                state->im = im;
                                state->idev = idev;
                                break;
@@ -2458,7 +2463,7 @@ static struct ip_sf_list *igmp_mcf_get_n
                                read_unlock(&state->idev->mc_list_lock);
                                in_dev_put(state->idev);
                        }
-                       state->dev = state->dev->next;
+                       state->dev = next_netdev(state->dev);
                        if (!state->dev) {
                                state->idev = NULL;
                                goto out;
--- ./net/ipv6/anycast.c.vedevbase-proc Mon Jul  3 16:09:54 2006
+++ ./net/ipv6/anycast.c        Mon Jul  3 16:09:54 2006
@@ -447,19 +447,21 @@ struct ac6_iter_state {
 
 static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq)
 {
+       struct net_device *dev;
        struct ifacaddr6 *im = NULL;
        struct ac6_iter_state *state = ac6_seq_private(seq);
 
-       for (state->dev = dev_base, state->idev = NULL;
-            state->dev;
-            state->dev = state->dev->next) {
+       state->dev = NULL;
+       state->idev = NULL;
+       for_each_netdev(dev) {
                struct inet6_dev *idev;
-               idev = in6_dev_get(state->dev);
+               idev = in6_dev_get(dev);
                if (!idev)
                        continue;
                read_lock_bh(&idev->lock);
                im = idev->ac_list;
                if (im) {
+                       state->dev = dev;
                        state->idev = idev;
                        break;
                }
@@ -478,7 +480,7 @@ static struct ifacaddr6 *ac6_get_next(st
                        read_unlock_bh(&state->idev->lock);
                        in6_dev_put(state->idev);
                }
-               state->dev = state->dev->next;
+               state->dev = next_netdev(state->dev);
                if (!state->dev) {
                        state->idev = NULL;
                        break;
--- ./net/ipv6/mcast.c.vedevbase-proc   Mon Jul  3 15:14:22 2006
+++ ./net/ipv6/mcast.c  Mon Jul  3 16:09:54 2006
@@ -2322,19 +2322,21 @@ struct igmp6_mc_iter_state {
 
 static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
 {
+       struct net_device *dev;
        struct ifmcaddr6 *im = NULL;
        struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
 
-       for (state->dev = dev_base, state->idev = NULL;
-            state->dev; 
-            state->dev = state->dev->next) {
+       state->dev = NULL;
+       state->idev = NULL;
+       for_each_netdev(dev) {
                struct inet6_dev *idev;
-               idev = in6_dev_get(state->dev);
+               idev = in6_dev_get(dev);
                if (!idev)
                        continue;
                read_lock_bh(&idev->lock);
                im = idev->mc_list;
                if (im) {
+                       state->dev = dev;
                        state->idev = idev;
                        break;
                }
@@ -2354,7 +2356,7 @@ static struct ifmcaddr6 *igmp6_mc_get_ne
                        read_unlock_bh(&state->idev->lock);
                        in6_dev_put(state->idev);
                }
-               state->dev = state->dev->next;
+               state->dev = next_netdev(state->dev);
                if (!state->dev) {
                        state->idev = NULL;
                        break;
@@ -2465,15 +2467,17 @@ struct igmp6_mcf_iter_state {
 
 static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq)
 {
+       struct net_device *dev;
        struct ip6_sf_list *psf = NULL;
        struct ifmcaddr6 *im = NULL;
        struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
 
-       for (state->dev = dev_base, state->idev = NULL, state->im = NULL;
-            state->dev; 
-            state->dev = state->dev->next) {
+       state->dev = NULL;
+       state->im = NULL;
+       state->idev = NULL;
+       for_each_netdev(dev) {
                struct inet6_dev *idev;
-               idev = in6_dev_get(state->dev);
+               idev = in6_dev_get(dev);
                if (unlikely(idev == NULL))
                        continue;
                read_lock_bh(&idev->lock);
@@ -2482,6 +2486,7 @@ static inline struct ip6_sf_list *igmp6_
                        spin_lock_bh(&im->mca_lock);
                        psf = im->mca_sources;
                        if (likely(psf != NULL)) {
+                               state->dev = dev;
                                state->im = im;
                                state->idev = idev;
                                break;
@@ -2507,7 +2512,7 @@ static struct ip6_sf_list *igmp6_mcf_get
                                read_unlock_bh(&state->idev->lock);
                                in6_dev_put(state->idev);
                        }
-                       state->dev = state->dev->next;
+                       state->dev = next_netdev(state->dev);
                        if (!state->dev) {
                                state->idev = NULL;
                                goto out;
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to