diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-10-19 23:28:40 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-20 10:26:39 -0700 |
commit | 13bbc06af8a5f65df0f888b442e557c617cadba7 (patch) | |
tree | 64129c447795744f44754989d85a138dffdf7fdc /fs/nfs/client.c | |
parent | 7d9ac06f26fe8d477c813405f1a8c7c90eecef2d (diff) | |
download | kernel_samsung_aries-13bbc06af8a5f65df0f888b442e557c617cadba7.zip kernel_samsung_aries-13bbc06af8a5f65df0f888b442e557c617cadba7.tar.gz kernel_samsung_aries-13bbc06af8a5f65df0f888b442e557c617cadba7.tar.bz2 |
[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>
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r-- | fs/nfs/client.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 8b123f6..5fea638 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -232,11 +232,15 @@ void nfs_put_client(struct nfs_client *clp) * Find a client by address * - caller must hold nfs_client_lock */ -static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion) +static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion, int match_port) { struct nfs_client *clp; list_for_each_entry(clp, &nfs_client_list, cl_share_link) { + /* Don't match clients that failed to initialise properly */ + if (clp->cl_cons_state < 0) + continue; + /* Different NFS versions cannot share the same nfs_client */ if (clp->cl_nfsversion != nfsversion) continue; @@ -245,7 +249,7 @@ static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int sizeof(clp->cl_addr.sin_addr)) != 0) continue; - if (clp->cl_addr.sin_port == addr->sin_port) + if (!match_port || clp->cl_addr.sin_port == addr->sin_port) goto found; } @@ -265,11 +269,12 @@ struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversio struct nfs_client *clp; spin_lock(&nfs_client_lock); - clp = __nfs_find_client(addr, nfsversion); + clp = __nfs_find_client(addr, nfsversion, 0); spin_unlock(&nfs_client_lock); - - BUG_ON(clp && clp->cl_cons_state == 0); - + if (clp != NULL && clp->cl_cons_state != NFS_CS_READY) { + nfs_put_client(clp); + clp = NULL; + } return clp; } @@ -292,7 +297,7 @@ static struct nfs_client *nfs_get_client(const char *hostname, do { spin_lock(&nfs_client_lock); - clp = __nfs_find_client(addr, nfsversion); + clp = __nfs_find_client(addr, nfsversion, 1); if (clp) goto found_client; if (new) |