diff options
Diffstat (limited to 'fs/nfs/nfs4client.c')
| -rw-r--r-- | fs/nfs/nfs4client.c | 17 | 
1 files changed, 13 insertions, 4 deletions
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 12bbab0becb4..65a7e5da508c 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -404,15 +404,19 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,  	if (error < 0)  		goto error; -	if (!nfs4_has_session(clp)) -		nfs_mark_client_ready(clp, NFS_CS_READY); -  	error = nfs4_discover_server_trunking(clp, &old);  	if (error < 0)  		goto error; -	if (clp != old) +	if (clp != old) {  		clp->cl_preserve_clid = true; +		/* +		 * Mark the client as having failed initialization so other +		 * processes walking the nfs_client_list in nfs_match_client() +		 * won't try to use it. +		 */ +		nfs_mark_client_ready(clp, -EPERM); +	}  	nfs_put_client(clp);  	clear_bit(NFS_CS_TSM_POSSIBLE, &clp->cl_flags);  	return old; @@ -539,6 +543,9 @@ int nfs40_walk_client_list(struct nfs_client *new,  	spin_lock(&nn->nfs_client_lock);  	list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { +		if (pos == new) +			goto found; +  		status = nfs4_match_client(pos, new, &prev, nn);  		if (status < 0)  			goto out_unlock; @@ -559,6 +566,7 @@ int nfs40_walk_client_list(struct nfs_client *new,  		 * way that a SETCLIENTID_CONFIRM to pos can succeed is  		 * if new and pos point to the same server:  		 */ +found:  		refcount_inc(&pos->cl_count);  		spin_unlock(&nn->nfs_client_lock); @@ -572,6 +580,7 @@ int nfs40_walk_client_list(struct nfs_client *new,  		case 0:  			nfs4_swap_callback_idents(pos, new);  			pos->cl_confirm = new->cl_confirm; +			nfs_mark_client_ready(pos, NFS_CS_READY);  			prev = NULL;  			*result = pos;  | 
