diff options
Diffstat (limited to 'fs/nfs/nfs4client.c')
| -rw-r--r-- | fs/nfs/nfs4client.c | 282 | 
1 files changed, 79 insertions, 203 deletions
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 8346ccbf2d52..66776f022111 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -359,11 +359,9 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,  	struct nfs_client *old;  	int error; -	if (clp->cl_cons_state == NFS_CS_READY) { +	if (clp->cl_cons_state == NFS_CS_READY)  		/* the client is initialised already */ -		dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp);  		return clp; -	}  	/* Check NFS protocol revision and initialize RPC op vector */  	clp->rpc_ops = &nfs_v4_clientops; @@ -421,7 +419,6 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,  error:  	nfs_mark_client_ready(clp, error);  	nfs_put_client(clp); -	dprintk("<-- nfs4_init_client() = xerror %d\n", error);  	return ERR_PTR(error);  } @@ -469,6 +466,50 @@ static bool nfs4_same_verifier(nfs4_verifier *v1, nfs4_verifier *v2)  	return memcmp(v1->data, v2->data, sizeof(v1->data)) == 0;  } +static int nfs4_match_client(struct nfs_client  *pos,  struct nfs_client *new, +			     struct nfs_client **prev, struct nfs_net *nn) +{ +	int status; + +	if (pos->rpc_ops != new->rpc_ops) +		return 1; + +	if (pos->cl_minorversion != new->cl_minorversion) +		return 1; + +	/* If "pos" isn't marked ready, we can't trust the +	 * remaining fields in "pos", especially the client +	 * ID and serverowner fields.  Wait for CREATE_SESSION +	 * to finish. */ +	if (pos->cl_cons_state > NFS_CS_READY) { +		atomic_inc(&pos->cl_count); +		spin_unlock(&nn->nfs_client_lock); + +		nfs_put_client(*prev); +		*prev = pos; + +		status = nfs_wait_client_init_complete(pos); +		spin_lock(&nn->nfs_client_lock); + +		if (status < 0) +			return status; +	} + +	if (pos->cl_cons_state != NFS_CS_READY) +		return 1; + +	if (pos->cl_clientid != new->cl_clientid) +		return 1; + +	/* NFSv4.1 always uses the uniform string, however someone +	 * might switch the uniquifier string on us. +	 */ +	if (!nfs4_match_client_owner_id(pos, new)) +		return 1; + +	return 0; +} +  /**   * nfs40_walk_client_list - Find server that recognizes a client ID   * @@ -497,34 +538,10 @@ 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->rpc_ops != new->rpc_ops) -			continue; - -		if (pos->cl_minorversion != new->cl_minorversion) -			continue; - -		/* If "pos" isn't marked ready, we can't trust the -		 * remaining fields in "pos" */ -		if (pos->cl_cons_state > NFS_CS_READY) { -			atomic_inc(&pos->cl_count); -			spin_unlock(&nn->nfs_client_lock); - -			nfs_put_client(prev); -			prev = pos; - -			status = nfs_wait_client_init_complete(pos); -			if (status < 0) -				goto out; -			status = -NFS4ERR_STALE_CLIENTID; -			spin_lock(&nn->nfs_client_lock); -		} -		if (pos->cl_cons_state != NFS_CS_READY) -			continue; - -		if (pos->cl_clientid != new->cl_clientid) -			continue; - -		if (!nfs4_match_client_owner_id(pos, new)) +		status = nfs4_match_client(pos, new, &prev, nn); +		if (status < 0) +			goto out_unlock; +		if (status != 0)  			continue;  		/*  		 * We just sent a new SETCLIENTID, which should have @@ -557,8 +574,6 @@ int nfs40_walk_client_list(struct nfs_client *new,  			prev = NULL;  			*result = pos; -			dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", -				__func__, pos, atomic_read(&pos->cl_count));  			goto out;  		case -ERESTARTSYS:  		case -ETIMEDOUT: @@ -572,32 +587,17 @@ int nfs40_walk_client_list(struct nfs_client *new,  		spin_lock(&nn->nfs_client_lock);  	} +out_unlock:  	spin_unlock(&nn->nfs_client_lock);  	/* No match found. The server lost our clientid */  out:  	nfs_put_client(prev); -	dprintk("NFS: <-- %s status = %d\n", __func__, status);  	return status;  }  #ifdef CONFIG_NFS_V4_1  /* - * Returns true if the client IDs match - */ -static bool nfs4_match_clientids(u64 a, u64 b) -{ -	if (a != b) { -		dprintk("NFS: --> %s client ID %llx does not match %llx\n", -			__func__, a, b); -		return false; -	} -	dprintk("NFS: --> %s client ID %llx matches %llx\n", -		__func__, a, b); -	return true; -} - -/*   * Returns true if the server major ids match   */  static bool @@ -605,36 +605,8 @@ nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1,  				struct nfs41_server_owner *o2)  {  	if (o1->major_id_sz != o2->major_id_sz) -		goto out_major_mismatch; -	if (memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0) -		goto out_major_mismatch; - -	dprintk("NFS: --> %s server owner major IDs match\n", __func__); -	return true; - -out_major_mismatch: -	dprintk("NFS: --> %s server owner major IDs do not match\n", -		__func__); -	return false; -} - -/* - * Returns true if server minor ids match - */ -static bool -nfs4_check_serverowner_minor_id(struct nfs41_server_owner *o1, -				struct nfs41_server_owner *o2) -{ -	/* Check eir_server_owner so_minor_id */ -	if (o1->minor_id != o2->minor_id) -		goto out_minor_mismatch; - -	dprintk("NFS: --> %s server owner minor IDs match\n", __func__); -	return true; - -out_minor_mismatch: -	dprintk("NFS: --> %s server owner minor IDs do not match\n", __func__); -	return false; +		return false; +	return memcmp(o1->major_id, o2->major_id, o1->major_id_sz) == 0;  }  /* @@ -645,18 +617,9 @@ nfs4_check_server_scope(struct nfs41_server_scope *s1,  			struct nfs41_server_scope *s2)  {  	if (s1->server_scope_sz != s2->server_scope_sz) -		goto out_scope_mismatch; -	if (memcmp(s1->server_scope, s2->server_scope, -		   s1->server_scope_sz) != 0) -		goto out_scope_mismatch; - -	dprintk("NFS: --> %s server scopes match\n", __func__); -	return true; - -out_scope_mismatch: -	dprintk("NFS: --> %s server scopes do not match\n", -		__func__); -	return false; +		return false; +	return memcmp(s1->server_scope, s2->server_scope, +					s1->server_scope_sz) == 0;  }  /** @@ -680,7 +643,7 @@ int nfs4_detect_session_trunking(struct nfs_client *clp,  				 struct rpc_xprt *xprt)  {  	/* Check eir_clientid */ -	if (!nfs4_match_clientids(clp->cl_clientid, res->clientid)) +	if (clp->cl_clientid != res->clientid)  		goto out_err;  	/* Check eir_server_owner so_major_id */ @@ -689,8 +652,7 @@ int nfs4_detect_session_trunking(struct nfs_client *clp,  		goto out_err;  	/* Check eir_server_owner so_minor_id */ -	if (!nfs4_check_serverowner_minor_id(clp->cl_serverowner, -					     res->server_owner)) +	if (clp->cl_serverowner->minor_id != res->server_owner->minor_id)  		goto out_err;  	/* Check eir_server_scope */ @@ -739,33 +701,10 @@ int nfs41_walk_client_list(struct nfs_client *new,  		if (pos == new)  			goto found; -		if (pos->rpc_ops != new->rpc_ops) -			continue; - -		if (pos->cl_minorversion != new->cl_minorversion) -			continue; - -		/* If "pos" isn't marked ready, we can't trust the -		 * remaining fields in "pos", especially the client -		 * ID and serverowner fields.  Wait for CREATE_SESSION -		 * to finish. */ -		if (pos->cl_cons_state > NFS_CS_READY) { -			atomic_inc(&pos->cl_count); -			spin_unlock(&nn->nfs_client_lock); - -			nfs_put_client(prev); -			prev = pos; - -			status = nfs_wait_client_init_complete(pos); -			spin_lock(&nn->nfs_client_lock); -			if (status < 0) -				break; -			status = -NFS4ERR_STALE_CLIENTID; -		} -		if (pos->cl_cons_state != NFS_CS_READY) -			continue; - -		if (!nfs4_match_clientids(pos->cl_clientid, new->cl_clientid)) +		status = nfs4_match_client(pos, new, &prev, nn); +		if (status < 0) +			goto out; +		if (status != 0)  			continue;  		/* @@ -777,23 +716,15 @@ int nfs41_walk_client_list(struct nfs_client *new,  						     new->cl_serverowner))  			continue; -		/* Unlike NFSv4.0, we know that NFSv4.1 always uses the -		 * uniform string, however someone might switch the -		 * uniquifier string on us. -		 */ -		if (!nfs4_match_client_owner_id(pos, new)) -			continue;  found:  		atomic_inc(&pos->cl_count);  		*result = pos;  		status = 0; -		dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", -			__func__, pos, atomic_read(&pos->cl_count));  		break;  	} +out:  	spin_unlock(&nn->nfs_client_lock); -	dprintk("NFS: <-- %s status = %d\n", __func__, status);  	nfs_put_client(prev);  	return status;  } @@ -916,9 +847,6 @@ static int nfs4_set_client(struct nfs_server *server,  		.timeparms = timeparms,  	};  	struct nfs_client *clp; -	int error; - -	dprintk("--> nfs4_set_client()\n");  	if (server->flags & NFS_MOUNT_NORESVPORT)  		set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); @@ -927,15 +855,11 @@ static int nfs4_set_client(struct nfs_server *server,  	/* Allocate or find a client reference we can use */  	clp = nfs_get_client(&cl_init); -	if (IS_ERR(clp)) { -		error = PTR_ERR(clp); -		goto error; -	} +	if (IS_ERR(clp)) +		return PTR_ERR(clp); -	if (server->nfs_client == clp) { -		error = -ELOOP; -		goto error; -	} +	if (server->nfs_client == clp) +		return -ELOOP;  	/*  	 * Query for the lease time on clientid setup or renewal @@ -947,11 +871,7 @@ static int nfs4_set_client(struct nfs_server *server,  	set_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state);  	server->nfs_client = clp; -	dprintk("<-- nfs4_set_client() = 0 [new %p]\n", clp);  	return 0; -error: -	dprintk("<-- nfs4_set_client() = xerror %d\n", error); -	return error;  }  /* @@ -982,7 +902,6 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,  		.net = mds_clp->cl_net,  		.timeparms = &ds_timeout,  	}; -	struct nfs_client *clp;  	char buf[INET6_ADDRSTRLEN + 1];  	if (rpc_ntop(ds_addr, buf, sizeof(buf)) <= 0) @@ -998,10 +917,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,  	 * (section 13.1 RFC 5661).  	 */  	nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans); -	clp = nfs_get_client(&cl_init); - -	dprintk("<-- %s %p\n", __func__, clp); -	return clp; +	return nfs_get_client(&cl_init);  }  EXPORT_SYMBOL_GPL(nfs4_set_ds_client); @@ -1098,8 +1014,6 @@ static int nfs4_init_server(struct nfs_server *server,  	struct rpc_timeout timeparms;  	int error; -	dprintk("--> nfs4_init_server()\n"); -  	nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,  			data->timeo, data->retrans); @@ -1127,7 +1041,7 @@ static int nfs4_init_server(struct nfs_server *server,  			data->minorversion,  			data->net);  	if (error < 0) -		goto error; +		return error;  	if (data->rsize)  		server->rsize = nfs_block_size(data->rsize, NULL); @@ -1138,16 +1052,10 @@ static int nfs4_init_server(struct nfs_server *server,  	server->acregmax = data->acregmax * HZ;  	server->acdirmin = data->acdirmin * HZ;  	server->acdirmax = data->acdirmax * HZ; +	server->port     = data->nfs_server.port; -	server->port = data->nfs_server.port; - -	error = nfs_init_server_rpcclient(server, &timeparms, -					  data->selected_flavor); - -error: -	/* Done */ -	dprintk("<-- nfs4_init_server() = %d\n", error); -	return error; +	return nfs_init_server_rpcclient(server, &timeparms, +					 data->selected_flavor);  }  /* @@ -1163,8 +1071,6 @@ struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,  	bool auth_probe;  	int error; -	dprintk("--> nfs4_create_server()\n"); -  	server = nfs_alloc_server();  	if (!server)  		return ERR_PTR(-ENOMEM); @@ -1180,12 +1086,10 @@ struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,  	if (error < 0)  		goto error; -	dprintk("<-- nfs4_create_server() = %p\n", server);  	return server;  error:  	nfs_free_server(server); -	dprintk("<-- nfs4_create_server() = error %d\n", error);  	return ERR_PTR(error);  } @@ -1200,8 +1104,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,  	bool auth_probe;  	int error; -	dprintk("--> nfs4_create_referral_server()\n"); -  	server = nfs_alloc_server();  	if (!server)  		return ERR_PTR(-ENOMEM); @@ -1235,12 +1137,10 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,  	if (error < 0)  		goto error; -	dprintk("<-- nfs_create_referral_server() = %p\n", server);  	return server;  error:  	nfs_free_server(server); -	dprintk("<-- nfs4_create_referral_server() = error %d\n", error);  	return ERR_PTR(error);  } @@ -1300,31 +1200,16 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname,  	struct sockaddr *localaddr = (struct sockaddr *)&address;  	int error; -	dprintk("--> %s: move FSID %llx:%llx to \"%s\")\n", __func__, -			(unsigned long long)server->fsid.major, -			(unsigned long long)server->fsid.minor, -			hostname); -  	error = rpc_switch_client_transport(clnt, &xargs, clnt->cl_timeout); -	if (error != 0) { -		dprintk("<-- %s(): rpc_switch_client_transport returned %d\n", -			__func__, error); -		goto out; -	} +	if (error != 0) +		return error;  	error = rpc_localaddr(clnt, localaddr, sizeof(address)); -	if (error != 0) { -		dprintk("<-- %s(): rpc_localaddr returned %d\n", -			__func__, error); -		goto out; -	} +	if (error != 0) +		return error; -	error = -EAFNOSUPPORT; -	if (rpc_ntop(localaddr, buf, sizeof(buf)) == 0) { -		dprintk("<-- %s(): rpc_ntop returned %d\n", -			__func__, error); -		goto out; -	} +	if (rpc_ntop(localaddr, buf, sizeof(buf)) == 0) +		return -EAFNOSUPPORT;  	nfs_server_remove_lists(server);  	error = nfs4_set_client(server, hostname, sap, salen, buf, @@ -1333,21 +1218,12 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname,  	nfs_put_client(clp);  	if (error != 0) {  		nfs_server_insert_lists(server); -		dprintk("<-- %s(): nfs4_set_client returned %d\n", -			__func__, error); -		goto out; +		return error;  	}  	if (server->nfs_client->cl_hostname == NULL)  		server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL);  	nfs_server_insert_lists(server); -	error = nfs_probe_destination(server); -	if (error < 0) -		goto out; - -	dprintk("<-- %s() succeeded\n", __func__); - -out: -	return error; +	return nfs_probe_destination(server);  }  |