History

NFSv4/4.1: Fix nfs4_schedule_state_recovery abuses

nfs4_schedule_state_recovery() should only be used when we need to force the state manager to check the lease. If we just want to start the state manager in order to handle a state recovery situation, we should be using nfs4_schedule_state_manager(). This patch fixes the abuses of nfs4_schedule_state_recovery() by replacing its use with a set of helper functions that do the right thing.

Trond Myklebust committed 15 years ago

Commit 0400a6b1 parent c34c32e4 files · +52 −34Browse files

Unified · Split

4 files
  1. fs/nfs/nfs4_fs.h +7 −1
  2. fs/nfs/nfs4proc.c +23 −22
  3. fs/nfs/nfs4state.c +19 −6
  4. include/linux/nfs_fs_sb.h +3 −5
fs/nfs/nfs4_fs.h+7−1
@@ -298,6 +298,11 @@ struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp); · 297 unmodified lines
298#if defined(CONFIG_NFS_V4_1)298#if defined(CONFIG_NFS_V4_1)
299struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);299struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
300struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp);300struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp);
301extern void nfs4_schedule_session_recovery(struct nfs4_session *);
302#else
303static inline void nfs4_schedule_session_recovery(struct nfs4_session *session)
304{
305}
301#endif /* CONFIG_NFS_V4_1 */306#endif /* CONFIG_NFS_V4_1 */
302 307
303extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);308extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
@@ -307,8 +312,9 @@ extern void nfs4_put_open_state(struct nfs4_state *); · 3 unmodified lines
307extern void nfs4_close_state(struct path *, struct nfs4_state *, fmode_t);312extern void nfs4_close_state(struct path *, struct nfs4_state *, fmode_t);
308extern void nfs4_close_sync(struct path *, struct nfs4_state *, fmode_t);313extern void nfs4_close_sync(struct path *, struct nfs4_state *, fmode_t);
309extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);314extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
310extern void nfs4_schedule_state_recovery(struct nfs_client *);315extern void nfs4_schedule_lease_recovery(struct nfs_client *);
311extern void nfs4_schedule_state_manager(struct nfs_client *);316extern void nfs4_schedule_state_manager(struct nfs_client *);
317extern void nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *);
312extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state);318extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state);
313extern int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state);319extern int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state);
314extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);320extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
fs/nfs/nfs4proc.c+23−22
@@ -257,12 +257,13 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, · 256 unmodified lines
257 case -NFS4ERR_OPENMODE:257 case -NFS4ERR_OPENMODE:
258 if (state == NULL)258 if (state == NULL)
259 break;259 break;
260 nfs4_state_mark_reclaim_nograce(clp, state);260 nfs4_schedule_stateid_recovery(server, state);
261 goto do_state_recovery;261 goto wait_on_recovery;
262 case -NFS4ERR_STALE_STATEID:262 case -NFS4ERR_STALE_STATEID:
263 case -NFS4ERR_STALE_CLIENTID:263 case -NFS4ERR_STALE_CLIENTID:
264 case -NFS4ERR_EXPIRED:264 case -NFS4ERR_EXPIRED:
265 goto do_state_recovery;265 nfs4_schedule_lease_recovery(clp);
266 goto wait_on_recovery;
266#if defined(CONFIG_NFS_V4_1)267#if defined(CONFIG_NFS_V4_1)
267 case -NFS4ERR_BADSESSION:268 case -NFS4ERR_BADSESSION:
268 case -NFS4ERR_BADSLOT:269 case -NFS4ERR_BADSLOT:
@@ -273,7 +274,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, · 4 unmodified lines
273 case -NFS4ERR_SEQ_MISORDERED:274 case -NFS4ERR_SEQ_MISORDERED:
274 dprintk("%s ERROR: %d Reset session\n", __func__,275 dprintk("%s ERROR: %d Reset session\n", __func__,
275 errorcode);276 errorcode);
276 nfs4_schedule_state_recovery(clp);277 nfs4_schedule_session_recovery(clp->cl_session);
277 exception->retry = 1;278 exception->retry = 1;
278 break;279 break;
279#endif /* defined(CONFIG_NFS_V4_1) */280#endif /* defined(CONFIG_NFS_V4_1) */
@@ -296,8 +297,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, · 16 unmodified lines
296 }297 }
297 /* We failed to handle the error */298 /* We failed to handle the error */
298 return nfs4_map_errors(ret);299 return nfs4_map_errors(ret);
299do_state_recovery:300wait_on_recovery:
300 nfs4_schedule_state_recovery(clp);
301 ret = nfs4_wait_clnt_recover(clp);301 ret = nfs4_wait_clnt_recover(clp);
302 if (ret == 0)302 if (ret == 0)
303 exception->retry = 1;303 exception->retry = 1;
@@ -1256,14 +1256,13 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state · 952 unmodified lines
1256 case -NFS4ERR_BAD_HIGH_SLOT:1256 case -NFS4ERR_BAD_HIGH_SLOT:
1257 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:1257 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1258 case -NFS4ERR_DEADSESSION:1258 case -NFS4ERR_DEADSESSION:
1259 nfs4_schedule_state_recovery(1259 nfs4_schedule_session_recovery(server->nfs_client->cl_session);
1260 server->nfs_client);
1261 goto out;1260 goto out;
1262 case -NFS4ERR_STALE_CLIENTID:1261 case -NFS4ERR_STALE_CLIENTID:
1263 case -NFS4ERR_STALE_STATEID:1262 case -NFS4ERR_STALE_STATEID:
1264 case -NFS4ERR_EXPIRED:1263 case -NFS4ERR_EXPIRED:
1265 /* Don't recall a delegation if it was lost */1264 /* Don't recall a delegation if it was lost */
1266 nfs4_schedule_state_recovery(server->nfs_client);1265 nfs4_schedule_lease_recovery(server->nfs_client);
1267 goto out;1266 goto out;
1268 case -ERESTARTSYS:1267 case -ERESTARTSYS:
1269 /*1268 /*
@@ -1272,7 +1271,7 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state · 2 unmodified lines
1272 */1271 */
1273 case -NFS4ERR_ADMIN_REVOKED:1272 case -NFS4ERR_ADMIN_REVOKED:
1274 case -NFS4ERR_BAD_STATEID:1273 case -NFS4ERR_BAD_STATEID:
1275 nfs4_state_mark_reclaim_nograce(server->nfs_client, state);1274 nfs4_schedule_stateid_recovery(server, state);
1276 case -EKEYEXPIRED:1275 case -EKEYEXPIRED:
1277 /*1276 /*
1278 * User RPCSEC_GSS context has expired.1277 * User RPCSEC_GSS context has expired.
@@ -1588,7 +1587,7 @@ static int nfs4_recover_expired_lease(struct nfs_server *server) · 309 unmodified lines
1588 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&1587 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&
1589 !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state))1588 !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state))
1590 break;1589 break;
1591 nfs4_schedule_state_recovery(clp);1590 nfs4_schedule_state_manager(clp);
1592 ret = -EIO;1591 ret = -EIO;
1593 }1592 }
1594 return ret;1593 return ret;
@@ -3179,7 +3178,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *calldata) · 1584 unmodified lines
3179 if (task->tk_status < 0) {3178 if (task->tk_status < 0) {
3180 /* Unless we're shutting down, schedule state recovery! */3179 /* Unless we're shutting down, schedule state recovery! */
3181 if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) != 0)3180 if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) != 0)
3182 nfs4_schedule_state_recovery(clp);3181 nfs4_schedule_lease_recovery(clp);
3183 return;3182 return;
3184 }3183 }
3185 do_renew_lease(clp, timestamp);3184 do_renew_lease(clp, timestamp);
@@ -3504,12 +3503,13 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, · 318 unmodified lines
3504 case -NFS4ERR_OPENMODE:3503 case -NFS4ERR_OPENMODE:
3505 if (state == NULL)3504 if (state == NULL)
3506 break;3505 break;
3507 nfs4_state_mark_reclaim_nograce(clp, state);3506 nfs4_schedule_stateid_recovery(server, state);
3508 goto do_state_recovery;3507 goto wait_on_recovery;
3509 case -NFS4ERR_STALE_STATEID:3508 case -NFS4ERR_STALE_STATEID:
3510 case -NFS4ERR_STALE_CLIENTID:3509 case -NFS4ERR_STALE_CLIENTID:
3511 case -NFS4ERR_EXPIRED:3510 case -NFS4ERR_EXPIRED:
3512 goto do_state_recovery;3511 nfs4_schedule_lease_recovery(clp);
3512 goto wait_on_recovery;
3513#if defined(CONFIG_NFS_V4_1)3513#if defined(CONFIG_NFS_V4_1)
3514 case -NFS4ERR_BADSESSION:3514 case -NFS4ERR_BADSESSION:
3515 case -NFS4ERR_BADSLOT:3515 case -NFS4ERR_BADSLOT:
@@ -3520,7 +3520,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, · 4 unmodified lines
3520 case -NFS4ERR_SEQ_MISORDERED:3520 case -NFS4ERR_SEQ_MISORDERED:
3521 dprintk("%s ERROR %d, Reset session\n", __func__,3521 dprintk("%s ERROR %d, Reset session\n", __func__,
3522 task->tk_status);3522 task->tk_status);
3523 nfs4_schedule_state_recovery(clp);3523 nfs4_schedule_session_recovery(clp->cl_session);
3524 task->tk_status = 0;3524 task->tk_status = 0;
3525 return -EAGAIN;3525 return -EAGAIN;
3526#endif /* CONFIG_NFS_V4_1 */3526#endif /* CONFIG_NFS_V4_1 */
@@ -3537,9 +3537,8 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, · 10 unmodified lines
3537 }3537 }
3538 task->tk_status = nfs4_map_errors(task->tk_status);3538 task->tk_status = nfs4_map_errors(task->tk_status);
3539 return 0;3539 return 0;
3540do_state_recovery:3540wait_on_recovery:
3541 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);3541 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
3542 nfs4_schedule_state_recovery(clp);
3543 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)3542 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
3544 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);3543 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
3545 task->tk_status = 0;3544 task->tk_status = 0;
@@ -4406,12 +4405,14 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) · 860 unmodified lines
4406 case -NFS4ERR_EXPIRED:4405 case -NFS4ERR_EXPIRED:
4407 case -NFS4ERR_STALE_CLIENTID:4406 case -NFS4ERR_STALE_CLIENTID:
4408 case -NFS4ERR_STALE_STATEID:4407 case -NFS4ERR_STALE_STATEID:
4408 nfs4_schedule_lease_recovery(server->nfs_client);
4409 goto out;
4409 case -NFS4ERR_BADSESSION:4410 case -NFS4ERR_BADSESSION:
4410 case -NFS4ERR_BADSLOT:4411 case -NFS4ERR_BADSLOT:
4411 case -NFS4ERR_BAD_HIGH_SLOT:4412 case -NFS4ERR_BAD_HIGH_SLOT:
4412 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:4413 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
4413 case -NFS4ERR_DEADSESSION:4414 case -NFS4ERR_DEADSESSION:
4414 nfs4_schedule_state_recovery(server->nfs_client);4415 nfs4_schedule_session_recovery(server->nfs_client->cl_session);
4415 goto out;4416 goto out;
4416 case -ERESTARTSYS:4417 case -ERESTARTSYS:
4417 /*4418 /*
@@ -4421,7 +4422,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) · 3 unmodified lines
4421 case -NFS4ERR_ADMIN_REVOKED:4422 case -NFS4ERR_ADMIN_REVOKED:
4422 case -NFS4ERR_BAD_STATEID:4423 case -NFS4ERR_BAD_STATEID:
4423 case -NFS4ERR_OPENMODE:4424 case -NFS4ERR_OPENMODE:
4424 nfs4_state_mark_reclaim_nograce(server->nfs_client, state);4425 nfs4_schedule_stateid_recovery(server, state);
4425 err = 0;4426 err = 0;
4426 goto out;4427 goto out;
4427 case -EKEYEXPIRED:4428 case -EKEYEXPIRED:
@@ -5150,7 +5151,7 @@ static int nfs41_sequence_handle_errors(struct rpc_task *task, struct nfs_client · 722 unmodified lines
5150 rpc_delay(task, NFS4_POLL_RETRY_MAX);5151 rpc_delay(task, NFS4_POLL_RETRY_MAX);
5151 return -EAGAIN;5152 return -EAGAIN;
5152 default:5153 default:
5153 nfs4_schedule_state_recovery(clp);5154 nfs4_schedule_lease_recovery(clp);
5154 }5155 }
5155 return 0;5156 return 0;
5156}5157}
@@ -5291,7 +5292,7 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf · 134 unmodified lines
5291 rpc_delay(task, NFS4_POLL_RETRY_MAX);5292 rpc_delay(task, NFS4_POLL_RETRY_MAX);
5292 return -EAGAIN;5293 return -EAGAIN;
5293 default:5294 default:
5294 nfs4_schedule_state_recovery(clp);5295 nfs4_schedule_lease_recovery(clp);
5295 }5296 }
5296 return 0;5297 return 0;
5297}5298}
fs/nfs/nfs4state.c+19−6
@@ -1007,9 +1007,9 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) · 1006 unmodified lines
1007}1007}
1008 1008
1009/*1009/*
1010 * Schedule a state recovery attempt1010 * Schedule a lease recovery attempt
1011 */1011 */
1012void nfs4_schedule_state_recovery(struct nfs_client *clp)1012void nfs4_schedule_lease_recovery(struct nfs_client *clp)
1013{1013{
1014 if (!clp)1014 if (!clp)
1015 return;1015 return;
@@ -1041,6 +1041,14 @@ int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *s · 25 unmodified lines
1041 return 1;1041 return 1;
1042}1042}
1043 1043
1044void nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4_state *state)
1045{
1046 struct nfs_client *clp = server->nfs_client;
1047
1048 nfs4_state_mark_reclaim_nograce(clp, state);
1049 nfs4_schedule_state_manager(clp);
1050}
1051
1044static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops)1052static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops)
1045{1053{
1046 struct inode *inode = state->inode;1054 struct inode *inode = state->inode;
@@ -1436,10 +1444,15 @@ static int nfs4_reclaim_lease(struct nfs_client *clp) · 389 unmodified lines
1436}1444}
1437 1445
1438#ifdef CONFIG_NFS_V4_11446#ifdef CONFIG_NFS_V4_1
1447void nfs4_schedule_session_recovery(struct nfs4_session *session)
1448{
1449 nfs4_schedule_lease_recovery(session->clp);
1450}
1451
1439void nfs41_handle_recall_slot(struct nfs_client *clp)1452void nfs41_handle_recall_slot(struct nfs_client *clp)
1440{1453{
1441 set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);1454 set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
1442 nfs4_schedule_state_recovery(clp);1455 nfs4_schedule_state_manager(clp);
1443}1456}
1444 1457
1445static void nfs4_reset_all_state(struct nfs_client *clp)1458static void nfs4_reset_all_state(struct nfs_client *clp)
@@ -1447,7 +1460,7 @@ static void nfs4_reset_all_state(struct nfs_client *clp) · 1 unmodified line
1447 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {1460 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
1448 clp->cl_boot_time = CURRENT_TIME;1461 clp->cl_boot_time = CURRENT_TIME;
1449 nfs4_state_start_reclaim_nograce(clp);1462 nfs4_state_start_reclaim_nograce(clp);
1450 nfs4_schedule_state_recovery(clp);1463 nfs4_schedule_state_manager(clp);
1451 }1464 }
1452}1465}
1453 1466
@@ -1455,7 +1468,7 @@ static void nfs41_handle_server_reboot(struct nfs_client *clp) · 1 unmodified line
1455{1468{
1456 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {1469 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
1457 nfs4_state_start_reclaim_reboot(clp);1470 nfs4_state_start_reclaim_reboot(clp);
1458 nfs4_schedule_state_recovery(clp);1471 nfs4_schedule_state_manager(clp);
1459 }1472 }
1460}1473}
1461 1474
@@ -1475,7 +1488,7 @@ static void nfs41_handle_cb_path_down(struct nfs_client *clp) · 13 unmodified lines
1475{1488{
1476 nfs_expire_all_delegations(clp);1489 nfs_expire_all_delegations(clp);
1477 if (test_and_set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) == 0)1490 if (test_and_set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) == 0)
1478 nfs4_schedule_state_recovery(clp);1491 nfs4_schedule_state_manager(clp);
1479}1492}
1480 1493
1481void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)1494void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
include/linux/nfs_fs_sb.h+3−5
@@ -68,9 +68,7 @@ struct nfs_client { · 67 unmodified lines
68 unsigned char cl_id_uniquifier;68 unsigned char cl_id_uniquifier;
69 u32 cl_cb_ident; /* v4.0 callback identifier */69 u32 cl_cb_ident; /* v4.0 callback identifier */
70 const struct nfs4_minor_version_ops *cl_mvops;70 const struct nfs4_minor_version_ops *cl_mvops;
71#endif /* CONFIG_NFS_V4 */
72 71
73#ifdef CONFIG_NFS_V4_1
74 /* The sequence id to use for the next CREATE_SESSION */72 /* The sequence id to use for the next CREATE_SESSION */
75 u32 cl_seqid;73 u32 cl_seqid;
76 /* The flags used for obtaining the clientid during EXCHANGE_ID */74 /* The flags used for obtaining the clientid during EXCHANGE_ID */
@@ -78,7 +76,7 @@ struct nfs_client { · 1 unmodified line
78 struct nfs4_session *cl_session; /* sharred session */76 struct nfs4_session *cl_session; /* sharred session */
79 struct list_head cl_layouts;77 struct list_head cl_layouts;
80 struct pnfs_deviceid_cache *cl_devid_cache; /* pNFS deviceid cache */78 struct pnfs_deviceid_cache *cl_devid_cache; /* pNFS deviceid cache */
81#endif /* CONFIG_NFS_V4_1 */79#endif /* CONFIG_NFS_V4 */
82 80
83#ifdef CONFIG_NFS_FSCACHE81#ifdef CONFIG_NFS_FSCACHE
84 struct fscache_cookie *fscache; /* client index cache cookie */82 struct fscache_cookie *fscache; /* client index cache cookie */
@@ -183,7 +181,7 @@ struct nfs_server { · 98 unmodified lines
183/* maximum number of slots to use */181/* maximum number of slots to use */
184#define NFS4_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE182#define NFS4_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE
185 183
186#if defined(CONFIG_NFS_V4_1)184#if defined(CONFIG_NFS_V4)
187 185
188/* Sessions */186/* Sessions */
189#define SLOT_TABLE_SZ (NFS4_MAX_SLOT_TABLE/(8*sizeof(long)))187#define SLOT_TABLE_SZ (NFS4_MAX_SLOT_TABLE/(8*sizeof(long)))
@@ -223,5 +221,5 @@ struct nfs4_session { · 33 unmodified lines
223 struct nfs_client *clp;221 struct nfs_client *clp;
224};222};
225 223
226#endif /* CONFIG_NFS_V4_1 */224#endif /* CONFIG_NFS_V4 */
227#endif225#endif