Loading fs/nfs/nfs4_fs.h +1 −2 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ struct idmap; ((err) != NFSERR_NOFILEHANDLE)) enum nfs4_client_state { NFS4CLNT_OK = 0, NFS4CLNT_STATE_RECOVER = 0, }; /* Loading Loading @@ -76,7 +76,6 @@ struct nfs4_client { struct work_struct cl_renewd; struct work_struct cl_recoverd; wait_queue_head_t cl_waitq; struct rpc_wait_queue cl_rpcwaitq; /* used for the setclientid verifier */ Loading fs/nfs/nfs4proc.c +14 −13 Original line number Diff line number Diff line Loading @@ -2736,7 +2736,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) case -NFS4ERR_EXPIRED: rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL, NULL); nfs4_schedule_state_recovery(clp); if (test_bit(NFS4CLNT_OK, &clp->cl_state)) if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) rpc_wake_up_task(task); task->tk_status = 0; return -EAGAIN; Loading @@ -2753,25 +2753,25 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) return 0; } static int nfs4_wait_bit_interruptible(void *word) { if (signal_pending(current)) return -ERESTARTSYS; schedule(); return 0; } static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp) { DEFINE_WAIT(wait); sigset_t oldset; int interruptible, res = 0; int res; might_sleep(); rpc_clnt_sigmask(clnt, &oldset); interruptible = TASK_UNINTERRUPTIBLE; if (clnt->cl_intr) interruptible = TASK_INTERRUPTIBLE; prepare_to_wait(&clp->cl_waitq, &wait, interruptible); nfs4_schedule_state_recovery(clp); if (clnt->cl_intr && signalled()) res = -ERESTARTSYS; else if (!test_bit(NFS4CLNT_OK, &clp->cl_state)) schedule(); finish_wait(&clp->cl_waitq, &wait); res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER, nfs4_wait_bit_interruptible, TASK_INTERRUPTIBLE); rpc_clnt_sigunmask(clnt, &oldset); return res; } Loading Loading @@ -2814,6 +2814,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_STATEID: case -NFS4ERR_EXPIRED: nfs4_schedule_state_recovery(clp); ret = nfs4_wait_clnt_recover(server->client, clp); if (ret == 0) exception->retry = 1; Loading fs/nfs/nfs4state.c +13 −10 Original line number Diff line number Diff line Loading @@ -106,11 +106,10 @@ nfs4_alloc_client(struct in_addr *addr) INIT_WORK(&clp->cl_recoverd, nfs4_recover_state, clp); INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); INIT_LIST_HEAD(&clp->cl_superblocks); init_waitqueue_head(&clp->cl_waitq); rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); clp->cl_rpcclient = ERR_PTR(-EINVAL); clp->cl_boot_time = CURRENT_TIME; clp->cl_state = 1 << NFS4CLNT_OK; clp->cl_state = 0; return clp; } Loading Loading @@ -193,7 +192,6 @@ nfs4_put_client(struct nfs4_client *clp) list_del(&clp->cl_servers); spin_unlock(&state_spinlock); BUG_ON(!list_empty(&clp->cl_superblocks)); wake_up_all(&clp->cl_waitq); rpc_wake_up(&clp->cl_rpcwaitq); nfs4_kill_renewd(clp); nfs4_free_client(clp); Loading Loading @@ -741,6 +739,15 @@ struct reclaimer_args { struct completion complete; }; static inline void nfs4_clear_recover_bit(struct nfs4_client *clp) { smp_mb__before_clear_bit(); clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state); smp_mb__after_clear_bit(); wake_up_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER); rpc_wake_up(&clp->cl_rpcwaitq); } /* * State recovery routine */ Loading @@ -760,9 +767,7 @@ nfs4_recover_state(void *data) wait_for_completion(&args.complete); return; out_failed_clear: set_bit(NFS4CLNT_OK, &clp->cl_state); wake_up_all(&clp->cl_waitq); rpc_wake_up(&clp->cl_rpcwaitq); nfs4_clear_recover_bit(clp); } /* Loading @@ -773,7 +778,7 @@ nfs4_schedule_state_recovery(struct nfs4_client *clp) { if (!clp) return; if (test_and_clear_bit(NFS4CLNT_OK, &clp->cl_state)) if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) schedule_work(&clp->cl_recoverd); } Loading Loading @@ -943,13 +948,11 @@ static int reclaimer(void *ptr) } nfs_delegation_reap_unclaimed(clp); out: set_bit(NFS4CLNT_OK, &clp->cl_state); up_write(&clp->cl_sem); unlock_kernel(); wake_up_all(&clp->cl_waitq); rpc_wake_up(&clp->cl_rpcwaitq); if (status == -NFS4ERR_CB_PATH_DOWN) nfs_handle_cb_pathdown(clp); nfs4_clear_recover_bit(clp); nfs4_put_client(clp); return 0; out_error: Loading Loading
fs/nfs/nfs4_fs.h +1 −2 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ struct idmap; ((err) != NFSERR_NOFILEHANDLE)) enum nfs4_client_state { NFS4CLNT_OK = 0, NFS4CLNT_STATE_RECOVER = 0, }; /* Loading Loading @@ -76,7 +76,6 @@ struct nfs4_client { struct work_struct cl_renewd; struct work_struct cl_recoverd; wait_queue_head_t cl_waitq; struct rpc_wait_queue cl_rpcwaitq; /* used for the setclientid verifier */ Loading
fs/nfs/nfs4proc.c +14 −13 Original line number Diff line number Diff line Loading @@ -2736,7 +2736,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) case -NFS4ERR_EXPIRED: rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL, NULL); nfs4_schedule_state_recovery(clp); if (test_bit(NFS4CLNT_OK, &clp->cl_state)) if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) rpc_wake_up_task(task); task->tk_status = 0; return -EAGAIN; Loading @@ -2753,25 +2753,25 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) return 0; } static int nfs4_wait_bit_interruptible(void *word) { if (signal_pending(current)) return -ERESTARTSYS; schedule(); return 0; } static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp) { DEFINE_WAIT(wait); sigset_t oldset; int interruptible, res = 0; int res; might_sleep(); rpc_clnt_sigmask(clnt, &oldset); interruptible = TASK_UNINTERRUPTIBLE; if (clnt->cl_intr) interruptible = TASK_INTERRUPTIBLE; prepare_to_wait(&clp->cl_waitq, &wait, interruptible); nfs4_schedule_state_recovery(clp); if (clnt->cl_intr && signalled()) res = -ERESTARTSYS; else if (!test_bit(NFS4CLNT_OK, &clp->cl_state)) schedule(); finish_wait(&clp->cl_waitq, &wait); res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER, nfs4_wait_bit_interruptible, TASK_INTERRUPTIBLE); rpc_clnt_sigunmask(clnt, &oldset); return res; } Loading Loading @@ -2814,6 +2814,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_STATEID: case -NFS4ERR_EXPIRED: nfs4_schedule_state_recovery(clp); ret = nfs4_wait_clnt_recover(server->client, clp); if (ret == 0) exception->retry = 1; Loading
fs/nfs/nfs4state.c +13 −10 Original line number Diff line number Diff line Loading @@ -106,11 +106,10 @@ nfs4_alloc_client(struct in_addr *addr) INIT_WORK(&clp->cl_recoverd, nfs4_recover_state, clp); INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); INIT_LIST_HEAD(&clp->cl_superblocks); init_waitqueue_head(&clp->cl_waitq); rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); clp->cl_rpcclient = ERR_PTR(-EINVAL); clp->cl_boot_time = CURRENT_TIME; clp->cl_state = 1 << NFS4CLNT_OK; clp->cl_state = 0; return clp; } Loading Loading @@ -193,7 +192,6 @@ nfs4_put_client(struct nfs4_client *clp) list_del(&clp->cl_servers); spin_unlock(&state_spinlock); BUG_ON(!list_empty(&clp->cl_superblocks)); wake_up_all(&clp->cl_waitq); rpc_wake_up(&clp->cl_rpcwaitq); nfs4_kill_renewd(clp); nfs4_free_client(clp); Loading Loading @@ -741,6 +739,15 @@ struct reclaimer_args { struct completion complete; }; static inline void nfs4_clear_recover_bit(struct nfs4_client *clp) { smp_mb__before_clear_bit(); clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state); smp_mb__after_clear_bit(); wake_up_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER); rpc_wake_up(&clp->cl_rpcwaitq); } /* * State recovery routine */ Loading @@ -760,9 +767,7 @@ nfs4_recover_state(void *data) wait_for_completion(&args.complete); return; out_failed_clear: set_bit(NFS4CLNT_OK, &clp->cl_state); wake_up_all(&clp->cl_waitq); rpc_wake_up(&clp->cl_rpcwaitq); nfs4_clear_recover_bit(clp); } /* Loading @@ -773,7 +778,7 @@ nfs4_schedule_state_recovery(struct nfs4_client *clp) { if (!clp) return; if (test_and_clear_bit(NFS4CLNT_OK, &clp->cl_state)) if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) schedule_work(&clp->cl_recoverd); } Loading Loading @@ -943,13 +948,11 @@ static int reclaimer(void *ptr) } nfs_delegation_reap_unclaimed(clp); out: set_bit(NFS4CLNT_OK, &clp->cl_state); up_write(&clp->cl_sem); unlock_kernel(); wake_up_all(&clp->cl_waitq); rpc_wake_up(&clp->cl_rpcwaitq); if (status == -NFS4ERR_CB_PATH_DOWN) nfs_handle_cb_pathdown(clp); nfs4_clear_recover_bit(clp); nfs4_put_client(clp); return 0; out_error: Loading