nfs41: add session setup to the state manager
At mount, nfs_alloc_client sets the cl_state NFS4CLNT_LEASE_EXPIRED bit and nfs4_alloc_session sets the NFS4CLNT_SESSION_SETUP bit, so both bits are set when nfs4_lookup_root calls nfs4_recover_expired_lease which schedules the nfs4_state_manager and waits for it to complete. Place the session setup after the clientid establishment in nfs4_state_manager so that the session is setup right after the clientid has been established without rescheduling the state manager. Unlike nfsv4.0, the nfs_client struct is not ready to use until the session has been established. Postpone marking the nfs_client struct to NFS_CS_READY until after a successful CREATE_SESSION call so that other threads cannot use the client until the session is established. If the EXCHANGE_ID call fails and the session has not been setup (the NFS4CLNT_SESSION_SETUP bit is set), mark the client with the error and return. If the session setup CREATE_SESSION call fails with NFS4ERR_STALE_CLIENTID which could occur due to server reboot or network partition inbetween the EXCHANGE_ID and CREATE_SESSION call, reset the NFS4CLNT_LEASE_EXPIRED and NFS4CLNT_SESSION_SETUP bits and try again. If the CREATE_SESSION call fails with other errors, mark the client with the error and return. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: NFS_CS_SESSION_SETUP cl_cons_state for back channel setup] On session setup, the CREATE_SESSION reply races with the server back channel probe which needs to succeed to setup the back channel. Set a new cl_cons_state NFS_CS_SESSION_SETUP just prior to the CREATE_SESSION call and add it as a valid state to nfs_find_client so that the client back channel can find the nfs_client struct and won't drop the server backchannel probe. Use a new cl_cons_state so that NFSv4.0 back channel behaviour which only sets NFS_CS_READY is unchanged. Adjust waiting on the nfs_client_active_wq accordingly. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: rename NFS_CS_SESSION_SETUP to NFS_CS_SESSION_INITING] Signed-off-by: Andy Adamson <andros@netapp.com> [nfs41: set NFS_CL_SESSION_INITING in alloc_session] Signed-off-by: Andy Adamson <andros@netapp.com> [nfs41: move session setup into a function] Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [moved nfs4_proc_create_session declaration here] Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
committed by
Benny Halevy
parent
ac72b7b3b3
commit
76db6d9500
@ -1113,6 +1113,27 @@ static int nfs4_reclaim_lease(struct nfs_client *clp)
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFS_V4_1
|
||||
|
||||
static int nfs4_initialize_session(struct nfs_client *clp)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = nfs4_proc_create_session(clp, 0);
|
||||
if (!status) {
|
||||
nfs_mark_client_ready(clp, NFS_CS_READY);
|
||||
} else if (status == -NFS4ERR_STALE_CLIENTID) {
|
||||
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
|
||||
set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
|
||||
} else {
|
||||
nfs_mark_client_ready(clp, status);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#else /* CONFIG_NFS_V4_1 */
|
||||
static int nfs4_initialize_session(struct nfs_client *clp) { return 0; }
|
||||
#endif /* CONFIG_NFS_V4_1 */
|
||||
|
||||
static void nfs4_state_manager(struct nfs_client *clp)
|
||||
{
|
||||
int status = 0;
|
||||
@ -1126,6 +1147,9 @@ static void nfs4_state_manager(struct nfs_client *clp)
|
||||
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
|
||||
if (status == -EAGAIN)
|
||||
continue;
|
||||
if (clp->cl_cons_state ==
|
||||
NFS_CS_SESSION_INITING)
|
||||
nfs_mark_client_ready(clp, status);
|
||||
goto out_error;
|
||||
}
|
||||
clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
|
||||
@ -1136,7 +1160,16 @@ static void nfs4_state_manager(struct nfs_client *clp)
|
||||
if (status != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Setup the session */
|
||||
if (nfs4_has_session(clp) &&
|
||||
test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) {
|
||||
status = nfs4_initialize_session(clp);
|
||||
if (status) {
|
||||
if (status == -NFS4ERR_STALE_CLIENTID)
|
||||
continue;
|
||||
goto out_error;
|
||||
}
|
||||
}
|
||||
/* First recover reboot state... */
|
||||
if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) {
|
||||
status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops);
|
||||
|
Reference in New Issue
Block a user