
From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>

Fix an oops which happens during `less /proc/net/igmp'


 25-akpm/net/ipv4/igmp.c  |   10 +++++++++-
 25-akpm/net/ipv6/mcast.c |   10 +++++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff -puN net/ipv4/igmp.c~proc-net-igmp-oops-fix net/ipv4/igmp.c
--- 25/net/ipv4/igmp.c~proc-net-igmp-oops-fix	Tue Aug 26 13:49:54 2003
+++ 25-akpm/net/ipv4/igmp.c	Tue Aug 26 13:49:54 2003
@@ -2122,6 +2122,7 @@ static inline struct ip_mc_list *igmp_mc
 			break;
 		}
 		read_unlock(&in_dev->lock);
+		in_dev_put(in_dev);
 	}
 	return im;
 }
@@ -2181,7 +2182,9 @@ static void igmp_mc_seq_stop(struct seq_
 	if (likely(state->in_dev != NULL)) {
 		read_unlock(&state->in_dev->lock);
 		in_dev_put(state->in_dev);
+		state->in_dev = NULL;
 	}
+	state->dev = NULL;
 	read_unlock(&dev_base_lock);
 }
 
@@ -2284,6 +2287,7 @@ static inline struct ip_sf_list *igmp_mc
 			spin_unlock_bh(&im->lock);
 		}
 		read_unlock_bh(&idev->lock);
+		in_dev_put(idev);
 	}
 	return psf;
 }
@@ -2350,12 +2354,16 @@ static void *igmp_mcf_seq_next(struct se
 static void igmp_mcf_seq_stop(struct seq_file *seq, void *v)
 {
 	struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq);
-	if (likely(state->im != NULL))
+	if (likely(state->im != NULL)) {
 		spin_unlock_bh(&state->im->lock);
+		state->im = NULL;
+	}
 	if (likely(state->idev != NULL)) {
 		read_unlock_bh(&state->idev->lock);
 		in_dev_put(state->idev);
+		state->idev = NULL;
 	}
+	state->dev = NULL;
 	read_unlock(&dev_base_lock);
 }
 
diff -puN net/ipv6/mcast.c~proc-net-igmp-oops-fix net/ipv6/mcast.c
--- 25/net/ipv6/mcast.c~proc-net-igmp-oops-fix	Tue Aug 26 13:49:54 2003
+++ 25-akpm/net/ipv6/mcast.c	Tue Aug 26 13:49:54 2003
@@ -2078,6 +2078,7 @@ static inline struct ifmcaddr6 *igmp6_mc
 			break;
 		}
 		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
 	}
 	return im;
 }
@@ -2135,7 +2136,9 @@ static void igmp6_mc_seq_stop(struct seq
 	if (likely(state->idev != NULL)) {
 		read_unlock_bh(&state->idev->lock);
 		in6_dev_put(state->idev);
+		state->idev = NULL;
 	}
+	state->dev = NULL;
 	read_unlock(&dev_base_lock);
 }
 
@@ -2225,6 +2228,7 @@ static inline struct ip6_sf_list *igmp6_
 			spin_unlock_bh(&im->mca_lock);
 		}
 		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
 	}
 	return psf;
 }
@@ -2291,12 +2295,16 @@ static void *igmp6_mcf_seq_next(struct s
 static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v)
 {
 	struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
-	if (likely(state->im != NULL))
+	if (likely(state->im != NULL)) {
 		spin_unlock_bh(&state->im->mca_lock);
+		state->im = NULL;
+	}
 	if (likely(state->idev != NULL)) {
 		read_unlock_bh(&state->idev->lock);
 		in6_dev_put(state->idev);
+		state->idev = NULL;
 	}
+	state->dev = NULL;
 	read_unlock(&dev_base_lock);
 }
 

_
