nfs41: add create session into establish_clid

Reported-by: Trond Myklebust <trond.myklebust@netapp.com>

Resetting the clientid from the state manager could result in not confirming
the clientid due to create session not being called.

Move the create session call from the NFS4CLNT_SESSION_SETUP state manager
initialize session case into the NFS4CLNT_LEASE_EXPIRED case establish_clid
call.

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
Andy Adamson 2009-12-04 15:52:24 -05:00 committed by Trond Myklebust
parent 7285f2d2ff
commit 4d643d1dfa
3 changed files with 19 additions and 25 deletions

View File

@ -200,9 +200,11 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
/* nfs4proc.c */
extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *);
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait);
extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);

View File

@ -4315,7 +4315,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
* NFS4ERR_BADSESSION in the sequence operation, and will therefore
* be in some phase of session reset.
*/
static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
{
nfs4_verifier verifier;
struct nfs41_exchange_id_args args = {
@ -4601,7 +4601,6 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
if (!session)
return NULL;
set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
/*
* The create session reply races with the server back
* channel probe. Mark the client NFS_CS_SESSION_INITING
@ -4967,7 +4966,7 @@ struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
.state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
.recover_open = nfs4_open_reclaim,
.recover_lock = nfs4_lock_reclaim,
.establish_clid = nfs4_proc_exchange_id,
.establish_clid = nfs41_init_clientid,
.get_clid_cred = nfs4_get_exchange_id_cred,
};
#endif /* CONFIG_NFS_V4_1 */
@ -4987,7 +4986,7 @@ struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
.state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
.recover_open = nfs4_open_expired,
.recover_lock = nfs4_lock_expired,
.establish_clid = nfs4_proc_exchange_id,
.establish_clid = nfs41_init_clientid,
.get_clid_cred = nfs4_get_exchange_id_cred,
};
#endif /* CONFIG_NFS_V4_1 */

View File

@ -116,6 +116,19 @@ struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
#if defined(CONFIG_NFS_V4_1)
int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
{
int status;
status = nfs4_proc_exchange_id(clp, cred);
if (status == 0)
/* create session schedules state renewal upon success */
status = nfs4_proc_create_session(clp, 0);
if (status == 0)
nfs_mark_client_ready(clp, NFS_CS_READY);
return status;
}
struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp)
{
struct rpc_cred *cred;
@ -1162,7 +1175,6 @@ static void nfs4_session_recovery_handle_error(struct nfs_client *clp, int err)
switch (err) {
case -NFS4ERR_STALE_CLIENTID:
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
}
}
@ -1188,24 +1200,8 @@ out:
return status;
}
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_reset_session(struct nfs_client *clp) { return 0; }
static int nfs4_initialize_session(struct nfs_client *clp) { return 0; }
#endif /* CONFIG_NFS_V4_1 */
/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
@ -1262,10 +1258,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
/* Initialize or reset the session */
if (test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)
&& nfs4_has_session(clp)) {
if (clp->cl_cons_state == NFS_CS_SESSION_INITING)
status = nfs4_initialize_session(clp);
else
status = nfs4_reset_session(clp);
status = nfs4_reset_session(clp);
if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
continue;
if (status < 0)