aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-26 13:41:04 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-26 14:17:31 -0400
commit32b0131069c5bebf52368a9fe170f8d58b78fa8d (patch)
tree540451b739e9938b2f15682a0bab117852bc8e4e /fs/nfs/nfs4proc.c
parent662455391040a783b89d0232e743c27c23617dbd (diff)
NFSv4.1: Don't clobber the seqid if exchange_id returns a confirmed clientid
If the EXCHGID4_FLAG_CONFIRMED_R flag is set, the client is in theory supposed to already know the correct value of the seqid, in which case RFC5661 states that it should ignore the value returned. Also ensure that if the sanity check in nfs4_check_cl_exchange_flags fails, then we must not change the nfs_client fields. Finally, clean up the code: we don't need to retest the value of 'status' unless it can change. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 485a6c0cdc40..9f0a96fe6212 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5171,7 +5171,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
5171 .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER, 5171 .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER,
5172 }; 5172 };
5173 struct nfs41_exchange_id_res res = { 5173 struct nfs41_exchange_id_res res = {
5174 .client = clp, 5174 0
5175 }; 5175 };
5176 int status; 5176 int status;
5177 struct rpc_message msg = { 5177 struct rpc_message msg = {
@@ -5214,22 +5214,22 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
5214 5214
5215 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 5215 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
5216 if (status == 0) 5216 if (status == 0)
5217 status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); 5217 status = nfs4_check_cl_exchange_flags(res.flags);
5218 5218
5219 if (status == 0) { 5219 if (status == 0) {
5220 clp->cl_clientid = res.clientid;
5221 clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R);
5222 if (!(res.flags & EXCHGID4_FLAG_CONFIRMED_R))
5223 clp->cl_seqid = res.seqid;
5224
5220 kfree(clp->cl_serverowner); 5225 kfree(clp->cl_serverowner);
5221 clp->cl_serverowner = res.server_owner; 5226 clp->cl_serverowner = res.server_owner;
5222 res.server_owner = NULL; 5227 res.server_owner = NULL;
5223 }
5224 5228
5225 if (status == 0) {
5226 /* use the most recent implementation id */ 5229 /* use the most recent implementation id */
5227 kfree(clp->cl_implid); 5230 kfree(clp->cl_implid);
5228 clp->cl_implid = res.impl_id; 5231 clp->cl_implid = res.impl_id;
5229 } else
5230 kfree(res.impl_id);
5231 5232
5232 if (status == 0) {
5233 if (clp->cl_serverscope != NULL && 5233 if (clp->cl_serverscope != NULL &&
5234 !nfs41_same_server_scope(clp->cl_serverscope, 5234 !nfs41_same_server_scope(clp->cl_serverscope,
5235 res.server_scope)) { 5235 res.server_scope)) {
@@ -5244,7 +5244,8 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
5244 clp->cl_serverscope = res.server_scope; 5244 clp->cl_serverscope = res.server_scope;
5245 goto out; 5245 goto out;
5246 } 5246 }
5247 } 5247 } else
5248 kfree(res.impl_id);
5248 5249
5249out_server_owner: 5250out_server_owner:
5250 kfree(res.server_owner); 5251 kfree(res.server_owner);