summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4client.c
diff options
context:
space:
mode:
authorTrond Myklebust2013-01-19 04:56:23 +0100
committerTrond Myklebust2013-01-27 21:51:28 +0100
commit202c312dba7d95b96493b412c606163a0cd83984 (patch)
tree09bdba985da1addd3ae48e16b8953027645f2c62 /fs/nfs/nfs4client.c
parentNFSv4: Fix NFSv4 reference counting for trunked sessions (diff)
downloadkernel-qcow2-linux-202c312dba7d95b96493b412c606163a0cd83984.tar.gz
kernel-qcow2-linux-202c312dba7d95b96493b412c606163a0cd83984.tar.xz
kernel-qcow2-linux-202c312dba7d95b96493b412c606163a0cd83984.zip
NFSv4: Fix NFSv4 trunking discovery
If walking the list in nfs4[01]_walk_client_list fails, then the most likely explanation is that the server dropped the clientid before we actually managed to confirm it. As long as our nfs_client is the very last one in the list to be tested, the caller can be assured that this is the case when the final return value is NFS4ERR_STALE_CLIENTID. Reported-by: Ben Greear <greearb@candelatech.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: Chuck Lever <chuck.lever@oracle.com> Cc: stable@vger.kernel.org [>=3.7] Tested-by: Ben Greear <greearb@candelatech.com>
Diffstat (limited to 'fs/nfs/nfs4client.c')
-rw-r--r--fs/nfs/nfs4client.c26
1 files changed, 7 insertions, 19 deletions
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 65a290a73065..2f21f17fb16c 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -352,14 +352,8 @@ int nfs40_walk_client_list(struct nfs_client *new,
}
spin_unlock(&nn->nfs_client_lock);
+ /* No match found. The server lost our clientid */
out:
- /*
- * No matching nfs_client found. This should be impossible,
- * because the new nfs_client has already been added to
- * nfs_client_list by nfs_get_client().
- *
- * Don't BUG(), since the caller is holding a mutex.
- */
if (prev)
nfs_put_client(prev);
dprintk("NFS: <-- %s status = %d\n", __func__, status);
@@ -430,7 +424,7 @@ int nfs41_walk_client_list(struct nfs_client *new,
{
struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
struct nfs_client *pos, *n, *prev = NULL;
- int error;
+ int status = -NFS4ERR_STALE_CLIENTID;
spin_lock(&nn->nfs_client_lock);
list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) {
@@ -446,8 +440,8 @@ int nfs41_walk_client_list(struct nfs_client *new,
nfs_put_client(prev);
prev = pos;
- error = nfs_wait_client_init_complete(pos);
- if (error < 0) {
+ status = nfs_wait_client_init_complete(pos);
+ if (status < 0) {
nfs_put_client(pos);
spin_lock(&nn->nfs_client_lock);
continue;
@@ -480,16 +474,10 @@ int nfs41_walk_client_list(struct nfs_client *new,
return 0;
}
- /*
- * No matching nfs_client found. This should be impossible,
- * because the new nfs_client has already been added to
- * nfs_client_list by nfs_get_client().
- *
- * Don't BUG(), since the caller is holding a mutex.
- */
+ /* No matching nfs_client found. */
spin_unlock(&nn->nfs_client_lock);
- pr_err("NFS: %s Error: no matching nfs_client found\n", __func__);
- return -NFS4ERR_STALE_CLIENTID;
+ dprintk("NFS: <-- %s status = %d\n", __func__, status);
+ return status;
}
#endif /* CONFIG_NFS_V4_1 */