Commit e11259f9 authored by Trond Myklebust's avatar Trond Myklebust

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: default avatarJorge Mora <Jorge.Mora@netapp.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 48d66b97
...@@ -6897,9 +6897,13 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred, ...@@ -6897,9 +6897,13 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
if (status == 0) { if (status == 0) {
clp->cl_clientid = res.clientid; clp->cl_clientid = res.clientid;
clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R); clp->cl_exchange_flags = res.flags;
if (!(res.flags & EXCHGID4_FLAG_CONFIRMED_R)) /* Client ID is not confirmed */
if (!(res.flags & EXCHGID4_FLAG_CONFIRMED_R)) {
clear_bit(NFS4_SESSION_ESTABLISHED,
&clp->cl_session->session_state);
clp->cl_seqid = res.seqid; clp->cl_seqid = res.seqid;
}
kfree(clp->cl_serverowner); kfree(clp->cl_serverowner);
clp->cl_serverowner = res.server_owner; clp->cl_serverowner = res.server_owner;
...@@ -7231,6 +7235,9 @@ static void nfs4_update_session(struct nfs4_session *session, ...@@ -7231,6 +7235,9 @@ static void nfs4_update_session(struct nfs4_session *session,
struct nfs41_create_session_res *res) struct nfs41_create_session_res *res)
{ {
nfs4_copy_sessionid(&session->sess_id, &res->sessionid); nfs4_copy_sessionid(&session->sess_id, &res->sessionid);
/* Mark client id and session as being confirmed */
session->clp->cl_exchange_flags |= EXCHGID4_FLAG_CONFIRMED_R;
set_bit(NFS4_SESSION_ESTABLISHED, &session->session_state);
session->flags = res->flags; session->flags = res->flags;
memcpy(&session->fc_attrs, &res->fc_attrs, sizeof(session->fc_attrs)); memcpy(&session->fc_attrs, &res->fc_attrs, sizeof(session->fc_attrs));
if (res->flags & SESSION4_BACK_CHAN) if (res->flags & SESSION4_BACK_CHAN)
...@@ -7326,8 +7333,8 @@ int nfs4_proc_destroy_session(struct nfs4_session *session, ...@@ -7326,8 +7333,8 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,
dprintk("--> nfs4_proc_destroy_session\n"); dprintk("--> nfs4_proc_destroy_session\n");
/* session is still being setup */ /* session is still being setup */
if (session->clp->cl_cons_state != NFS_CS_READY) if (!test_and_clear_bit(NFS4_SESSION_ESTABLISHED, &session->session_state))
return status; return 0;
status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
trace_nfs4_destroy_session(session->clp, status); trace_nfs4_destroy_session(session->clp, status);
......
...@@ -70,6 +70,7 @@ struct nfs4_session { ...@@ -70,6 +70,7 @@ struct nfs4_session {
enum nfs4_session_state { enum nfs4_session_state {
NFS4_SESSION_INITING, NFS4_SESSION_INITING,
NFS4_SESSION_ESTABLISHED,
}; };
extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl,
......
...@@ -353,6 +353,10 @@ int nfs41_discover_server_trunking(struct nfs_client *clp, ...@@ -353,6 +353,10 @@ int nfs41_discover_server_trunking(struct nfs_client *clp,
if (clp != *result) if (clp != *result)
return 0; return 0;
/* Purge state if the client id was established in a prior instance */
if (clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R)
set_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state);
else
set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
nfs4_schedule_state_manager(clp); nfs4_schedule_state_manager(clp);
status = nfs_wait_client_init_complete(clp); status = nfs_wait_client_init_complete(clp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment