aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-03-03 20:35:31 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-03-03 21:52:30 -0500
commite11259f920d8cb3550e0f311c064bdabe1bc3aaf (patch)
tree2b07c087911fe9c2db2f38943af888c693efe163 /fs
parent48d66b9749e39e0d4cc37d635df3f18906af38a6 (diff)
NFSv4.1: Clear the old state by our client id before establishing a new lease
If the call to exchange-id returns with the EXCHGID4_FLAG_CONFIRMED_R flag set, then that means our lease was established by a previous mount instance. Ensure that we detect this situation, and that we clear the state held by that mount. Reported-by: Jorge Mora <Jorge.Mora@netapp.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/nfs4proc.c15
-rw-r--r--fs/nfs/nfs4session.h1
-rw-r--r--fs/nfs/nfs4state.c6
3 files changed, 17 insertions, 5 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 732526e04cd5..627f37c44456 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6897,9 +6897,13 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
6897 6897
6898 if (status == 0) { 6898 if (status == 0) {
6899 clp->cl_clientid = res.clientid; 6899 clp->cl_clientid = res.clientid;
6900 clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R); 6900 clp->cl_exchange_flags = res.flags;
6901 if (!(res.flags & EXCHGID4_FLAG_CONFIRMED_R)) 6901 /* Client ID is not confirmed */
6902 if (!(res.flags & EXCHGID4_FLAG_CONFIRMED_R)) {
6903 clear_bit(NFS4_SESSION_ESTABLISHED,
6904 &clp->cl_session->session_state);
6902 clp->cl_seqid = res.seqid; 6905 clp->cl_seqid = res.seqid;
6906 }
6903 6907
6904 kfree(clp->cl_serverowner); 6908 kfree(clp->cl_serverowner);
6905 clp->cl_serverowner = res.server_owner; 6909 clp->cl_serverowner = res.server_owner;
@@ -7231,6 +7235,9 @@ static void nfs4_update_session(struct nfs4_session *session,
7231 struct nfs41_create_session_res *res) 7235 struct nfs41_create_session_res *res)
7232{ 7236{
7233 nfs4_copy_sessionid(&session->sess_id, &res->sessionid); 7237 nfs4_copy_sessionid(&session->sess_id, &res->sessionid);
7238 /* Mark client id and session as being confirmed */
7239 session->clp->cl_exchange_flags |= EXCHGID4_FLAG_CONFIRMED_R;
7240 set_bit(NFS4_SESSION_ESTABLISHED, &session->session_state);
7234 session->flags = res->flags; 7241 session->flags = res->flags;
7235 memcpy(&session->fc_attrs, &res->fc_attrs, sizeof(session->fc_attrs)); 7242 memcpy(&session->fc_attrs, &res->fc_attrs, sizeof(session->fc_attrs));
7236 if (res->flags & SESSION4_BACK_CHAN) 7243 if (res->flags & SESSION4_BACK_CHAN)
@@ -7326,8 +7333,8 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,
7326 dprintk("--> nfs4_proc_destroy_session\n"); 7333 dprintk("--> nfs4_proc_destroy_session\n");
7327 7334
7328 /* session is still being setup */ 7335 /* session is still being setup */
7329 if (session->clp->cl_cons_state != NFS_CS_READY) 7336 if (!test_and_clear_bit(NFS4_SESSION_ESTABLISHED, &session->session_state))
7330 return status; 7337 return 0;
7331 7338
7332 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 7339 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
7333 trace_nfs4_destroy_session(session->clp, status); 7340 trace_nfs4_destroy_session(session->clp, status);
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h
index fc46c7455898..e3ea2c5324d6 100644
--- a/fs/nfs/nfs4session.h
+++ b/fs/nfs/nfs4session.h
@@ -70,6 +70,7 @@ struct nfs4_session {
70 70
71enum nfs4_session_state { 71enum nfs4_session_state {
72 NFS4_SESSION_INITING, 72 NFS4_SESSION_INITING,
73 NFS4_SESSION_ESTABLISHED,
73}; 74};
74 75
75extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, 76extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl,
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index d8b43f0e08fc..f95e3b58bbc3 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -353,7 +353,11 @@ int nfs41_discover_server_trunking(struct nfs_client *clp,
353 if (clp != *result) 353 if (clp != *result)
354 return 0; 354 return 0;
355 355
356 set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 356 /* Purge state if the client id was established in a prior instance */
357 if (clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R)
358 set_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state);
359 else
360 set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
357 nfs4_schedule_state_manager(clp); 361 nfs4_schedule_state_manager(clp);
358 status = nfs_wait_client_init_complete(clp); 362 status = nfs_wait_client_init_complete(clp);
359 if (status < 0) 363 if (status < 0)