aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-05-23 01:35:25 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-05-23 13:35:31 -0400
commitf2d395865faa2a7cd4620b07178e58cbb160ba08 (patch)
tree01d3b090a4ce73eb346a2c55d99fe12d07d52906
parente46e490368f87032a6e54969194413339b35a385 (diff)
[PATCH] knfsd: Fix two problems that can cause rmmod nfsd to die
Both cause the 'entries' count in the export cache to be non-zero at module removal time, so unregistering that cache fails and results in an oops. 1/ exp_pseudoroot (used for NFSv4 only) leaks a reference to an export entry. 2/ sunrpc_cache_update doesn't increment the entries count when it adds an entry. Thanks to "david m. richter" <richterd@citi.umich.edu> for triggering the problem and finding one of the bugs. Cc: "david m. richter" <richterd@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/nfsd/export.c4
-rw-r--r--net/sunrpc/cache.c1
2 files changed, 4 insertions, 1 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 4e0578121d9a..3eec30000f3f 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -1066,9 +1066,11 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
1066 rv = nfserr_perm; 1066 rv = nfserr_perm;
1067 else if (IS_ERR(exp)) 1067 else if (IS_ERR(exp))
1068 rv = nfserrno(PTR_ERR(exp)); 1068 rv = nfserrno(PTR_ERR(exp));
1069 else 1069 else {
1070 rv = fh_compose(fhp, exp, 1070 rv = fh_compose(fhp, exp,
1071 fsid_key->ek_dentry, NULL); 1071 fsid_key->ek_dentry, NULL);
1072 exp_put(exp);
1073 }
1072 cache_put(&fsid_key->h, &svc_expkey_cache); 1074 cache_put(&fsid_key->h, &svc_expkey_cache);
1073 return rv; 1075 return rv;
1074} 1076}
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 3ac4193a78ed..7026b0866b7b 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -159,6 +159,7 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
159 detail->update(tmp, new); 159 detail->update(tmp, new);
160 tmp->next = *head; 160 tmp->next = *head;
161 *head = tmp; 161 *head = tmp;
162 detail->entries++;
162 cache_get(tmp); 163 cache_get(tmp);
163 is_new = cache_fresh_locked(tmp, new->expiry_time); 164 is_new = cache_fresh_locked(tmp, new->expiry_time);
164 cache_fresh_locked(old, 0); 165 cache_fresh_locked(old, 0);