diff options
author | Andy Adamson <andros@netapp.com> | 2009-12-04 15:52:24 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-12-04 15:52:24 -0500 |
commit | 4d643d1dfa9349164fe928e255f68020d91dbfe0 (patch) | |
tree | 1dde84268d81698e3f84cc3f20d90ddc234ba33f /fs | |
parent | 7285f2d2ffd4b7ab4ffb70a47759ee209c30017b (diff) |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs4_fs.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 7 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 35 |
3 files changed, 19 insertions, 25 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 6ea07a3c75d4..99d507d22f23 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -200,9 +200,11 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t); | |||
200 | /* nfs4proc.c */ | 200 | /* nfs4proc.c */ |
201 | extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *); | 201 | extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *); |
202 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); | 202 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); |
203 | extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred); | ||
203 | extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); | 204 | extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); |
204 | extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); | 205 | extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); |
205 | extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *); | 206 | extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *); |
207 | extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *); | ||
206 | extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait); | 208 | extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait); |
207 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); | 209 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); |
208 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); | 210 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0f9b7541e049..528b60a23ed5 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -4315,7 +4315,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, | |||
4315 | * NFS4ERR_BADSESSION in the sequence operation, and will therefore | 4315 | * NFS4ERR_BADSESSION in the sequence operation, and will therefore |
4316 | * be in some phase of session reset. | 4316 | * be in some phase of session reset. |
4317 | */ | 4317 | */ |
4318 | static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) | 4318 | int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) |
4319 | { | 4319 | { |
4320 | nfs4_verifier verifier; | 4320 | nfs4_verifier verifier; |
4321 | struct nfs41_exchange_id_args args = { | 4321 | struct nfs41_exchange_id_args args = { |
@@ -4601,7 +4601,6 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp) | |||
4601 | if (!session) | 4601 | if (!session) |
4602 | return NULL; | 4602 | return NULL; |
4603 | 4603 | ||
4604 | set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); | ||
4605 | /* | 4604 | /* |
4606 | * The create session reply races with the server back | 4605 | * The create session reply races with the server back |
4607 | * channel probe. Mark the client NFS_CS_SESSION_INITING | 4606 | * channel probe. Mark the client NFS_CS_SESSION_INITING |
@@ -4967,7 +4966,7 @@ struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = { | |||
4967 | .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, | 4966 | .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, |
4968 | .recover_open = nfs4_open_reclaim, | 4967 | .recover_open = nfs4_open_reclaim, |
4969 | .recover_lock = nfs4_lock_reclaim, | 4968 | .recover_lock = nfs4_lock_reclaim, |
4970 | .establish_clid = nfs4_proc_exchange_id, | 4969 | .establish_clid = nfs41_init_clientid, |
4971 | .get_clid_cred = nfs4_get_exchange_id_cred, | 4970 | .get_clid_cred = nfs4_get_exchange_id_cred, |
4972 | }; | 4971 | }; |
4973 | #endif /* CONFIG_NFS_V4_1 */ | 4972 | #endif /* CONFIG_NFS_V4_1 */ |
@@ -4987,7 +4986,7 @@ struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = { | |||
4987 | .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, | 4986 | .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, |
4988 | .recover_open = nfs4_open_expired, | 4987 | .recover_open = nfs4_open_expired, |
4989 | .recover_lock = nfs4_lock_expired, | 4988 | .recover_lock = nfs4_lock_expired, |
4990 | .establish_clid = nfs4_proc_exchange_id, | 4989 | .establish_clid = nfs41_init_clientid, |
4991 | .get_clid_cred = nfs4_get_exchange_id_cred, | 4990 | .get_clid_cred = nfs4_get_exchange_id_cred, |
4992 | }; | 4991 | }; |
4993 | #endif /* CONFIG_NFS_V4_1 */ | 4992 | #endif /* CONFIG_NFS_V4_1 */ |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 2eb0059bd693..967fc76a2463 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -116,6 +116,19 @@ struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp) | |||
116 | 116 | ||
117 | #if defined(CONFIG_NFS_V4_1) | 117 | #if defined(CONFIG_NFS_V4_1) |
118 | 118 | ||
119 | int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) | ||
120 | { | ||
121 | int status; | ||
122 | |||
123 | status = nfs4_proc_exchange_id(clp, cred); | ||
124 | if (status == 0) | ||
125 | /* create session schedules state renewal upon success */ | ||
126 | status = nfs4_proc_create_session(clp, 0); | ||
127 | if (status == 0) | ||
128 | nfs_mark_client_ready(clp, NFS_CS_READY); | ||
129 | return status; | ||
130 | } | ||
131 | |||
119 | struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp) | 132 | struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp) |
120 | { | 133 | { |
121 | struct rpc_cred *cred; | 134 | struct rpc_cred *cred; |
@@ -1162,7 +1175,6 @@ static void nfs4_session_recovery_handle_error(struct nfs_client *clp, int err) | |||
1162 | switch (err) { | 1175 | switch (err) { |
1163 | case -NFS4ERR_STALE_CLIENTID: | 1176 | case -NFS4ERR_STALE_CLIENTID: |
1164 | set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); | 1177 | set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); |
1165 | set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); | ||
1166 | } | 1178 | } |
1167 | } | 1179 | } |
1168 | 1180 | ||
@@ -1188,24 +1200,8 @@ out: | |||
1188 | return status; | 1200 | return status; |
1189 | } | 1201 | } |
1190 | 1202 | ||
1191 | static int nfs4_initialize_session(struct nfs_client *clp) | ||
1192 | { | ||
1193 | int status; | ||
1194 | |||
1195 | status = nfs4_proc_create_session(clp, 0); | ||
1196 | if (!status) { | ||
1197 | nfs_mark_client_ready(clp, NFS_CS_READY); | ||
1198 | } else if (status == -NFS4ERR_STALE_CLIENTID) { | ||
1199 | set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); | ||
1200 | set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); | ||
1201 | } else { | ||
1202 | nfs_mark_client_ready(clp, status); | ||
1203 | } | ||
1204 | return status; | ||
1205 | } | ||
1206 | #else /* CONFIG_NFS_V4_1 */ | 1203 | #else /* CONFIG_NFS_V4_1 */ |
1207 | static int nfs4_reset_session(struct nfs_client *clp) { return 0; } | 1204 | static int nfs4_reset_session(struct nfs_client *clp) { return 0; } |
1208 | static int nfs4_initialize_session(struct nfs_client *clp) { return 0; } | ||
1209 | #endif /* CONFIG_NFS_V4_1 */ | 1205 | #endif /* CONFIG_NFS_V4_1 */ |
1210 | 1206 | ||
1211 | /* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors | 1207 | /* 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) | |||
1262 | /* Initialize or reset the session */ | 1258 | /* Initialize or reset the session */ |
1263 | if (test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state) | 1259 | if (test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state) |
1264 | && nfs4_has_session(clp)) { | 1260 | && nfs4_has_session(clp)) { |
1265 | if (clp->cl_cons_state == NFS_CS_SESSION_INITING) | 1261 | status = nfs4_reset_session(clp); |
1266 | status = nfs4_initialize_session(clp); | ||
1267 | else | ||
1268 | status = nfs4_reset_session(clp); | ||
1269 | if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) | 1262 | if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) |
1270 | continue; | 1263 | continue; |
1271 | if (status < 0) | 1264 | if (status < 0) |