diff options
Diffstat (limited to 'fs/nfs/nfs4client.c')
| -rw-r--r-- | fs/nfs/nfs4client.c | 62 | 
1 files changed, 26 insertions, 36 deletions
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index acc34726812..2e9779b58b7 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -236,11 +236,10 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,  	error = nfs4_discover_server_trunking(clp, &old);  	if (error < 0)  		goto error; +	nfs_put_client(clp);  	if (clp != old) {  		clp->cl_preserve_clid = true; -		nfs_put_client(clp);  		clp = old; -		atomic_inc(&clp->cl_count);  	}  	return clp; @@ -306,7 +305,7 @@ int nfs40_walk_client_list(struct nfs_client *new,  		.clientid	= new->cl_clientid,  		.confirm	= new->cl_confirm,  	}; -	int status; +	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) { @@ -332,40 +331,33 @@ int nfs40_walk_client_list(struct nfs_client *new,  		if (prev)  			nfs_put_client(prev); +		prev = pos;  		status = nfs4_proc_setclientid_confirm(pos, &clid, cred); -		if (status == 0) { +		switch (status) { +		case -NFS4ERR_STALE_CLIENTID: +			break; +		case 0:  			nfs4_swap_callback_idents(pos, new); -			nfs_put_client(pos); +			prev = NULL;  			*result = pos;  			dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",  				__func__, pos, atomic_read(&pos->cl_count)); -			return 0; -		} -		if (status != -NFS4ERR_STALE_CLIENTID) { -			nfs_put_client(pos); -			dprintk("NFS: <-- %s status = %d, no result\n", -				__func__, status); -			return status; +		default: +			goto out;  		}  		spin_lock(&nn->nfs_client_lock); -		prev = pos;  	} +	spin_unlock(&nn->nfs_client_lock); -	/* -	 * 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 match found. The server lost our clientid */ +out:  	if (prev)  		nfs_put_client(prev); -	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;  }  #ifdef CONFIG_NFS_V4_1 @@ -432,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) { @@ -448,14 +440,17 @@ 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) { +			nfs4_schedule_lease_recovery(pos); +			status = nfs_wait_client_init_complete(pos); +			if (status < 0) {  				nfs_put_client(pos);  				spin_lock(&nn->nfs_client_lock);  				continue;  			} - +			status = pos->cl_cons_state;  			spin_lock(&nn->nfs_client_lock); +			if (status < 0) +				continue;  		}  		if (pos->rpc_ops != new->rpc_ops) @@ -473,6 +468,7 @@ int nfs41_walk_client_list(struct nfs_client *new,  		if (!nfs4_match_serverowners(pos, new))  			continue; +		atomic_inc(&pos->cl_count);  		spin_unlock(&nn->nfs_client_lock);  		dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",  			__func__, pos, atomic_read(&pos->cl_count)); @@ -481,16 +477,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 */  |