aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-10-20 02:28:40 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-20 13:26:39 -0400
commit13bbc06af8a5f65df0f888b442e557c617cadba7 (patch)
tree64129c447795744f44754989d85a138dffdf7fdc
parent7d9ac06f26fe8d477c813405f1a8c7c90eecef2d (diff)
[PATCH] NFS: Fix NFSv4 callback regression
The change in semantics for nfs_find_client() introduced by David breaks the NFSv4 callback channel. Also, replace another completely broken BUG_ON() in nfs_find_client(). In initialised clients, clp->cl_cons_state == 0, and callers of that function should in any case never want to see clients that are uninitialised. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/nfs/client.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 8b123f6a7d02..5fea638743e4 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -232,11 +232,15 @@ void nfs_put_client(struct nfs_client *clp)
232 * Find a client by address 232 * Find a client by address
233 * - caller must hold nfs_client_lock 233 * - caller must hold nfs_client_lock
234 */ 234 */
235static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion) 235static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion, int match_port)
236{ 236{
237 struct nfs_client *clp; 237 struct nfs_client *clp;
238 238
239 list_for_each_entry(clp, &nfs_client_list, cl_share_link) { 239 list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
240 /* Don't match clients that failed to initialise properly */
241 if (clp->cl_cons_state < 0)
242 continue;
243
240 /* Different NFS versions cannot share the same nfs_client */ 244 /* Different NFS versions cannot share the same nfs_client */
241 if (clp->cl_nfsversion != nfsversion) 245 if (clp->cl_nfsversion != nfsversion)
242 continue; 246 continue;
@@ -245,7 +249,7 @@ static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int
245 sizeof(clp->cl_addr.sin_addr)) != 0) 249 sizeof(clp->cl_addr.sin_addr)) != 0)
246 continue; 250 continue;
247 251
248 if (clp->cl_addr.sin_port == addr->sin_port) 252 if (!match_port || clp->cl_addr.sin_port == addr->sin_port)
249 goto found; 253 goto found;
250 } 254 }
251 255
@@ -265,11 +269,12 @@ struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversio
265 struct nfs_client *clp; 269 struct nfs_client *clp;
266 270
267 spin_lock(&nfs_client_lock); 271 spin_lock(&nfs_client_lock);
268 clp = __nfs_find_client(addr, nfsversion); 272 clp = __nfs_find_client(addr, nfsversion, 0);
269 spin_unlock(&nfs_client_lock); 273 spin_unlock(&nfs_client_lock);
270 274 if (clp != NULL && clp->cl_cons_state != NFS_CS_READY) {
271 BUG_ON(clp && clp->cl_cons_state == 0); 275 nfs_put_client(clp);
272 276 clp = NULL;
277 }
273 return clp; 278 return clp;
274} 279}
275 280
@@ -292,7 +297,7 @@ static struct nfs_client *nfs_get_client(const char *hostname,
292 do { 297 do {
293 spin_lock(&nfs_client_lock); 298 spin_lock(&nfs_client_lock);
294 299
295 clp = __nfs_find_client(addr, nfsversion); 300 clp = __nfs_find_client(addr, nfsversion, 1);
296 if (clp) 301 if (clp)
297 goto found_client; 302 goto found_client;
298 if (new) 303 if (new)