Commit 433fbe4c8837e3cc2ba6a6374edf28737d01a2e9

Authored by Trond Myklebust
1 parent 26e976a884

NFSv4: State recovery cleanup

Use wait_on_bit() when waiting for state recovery to complete.

 Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

Showing 3 changed files with 28 additions and 25 deletions Side-by-side Diff

... ... @@ -38,7 +38,7 @@
38 38 ((err) != NFSERR_NOFILEHANDLE))
39 39  
40 40 enum nfs4_client_state {
41   - NFS4CLNT_OK = 0,
  41 + NFS4CLNT_STATE_RECOVER = 0,
42 42 };
43 43  
44 44 /*
... ... @@ -76,7 +76,6 @@
76 76 struct work_struct cl_renewd;
77 77 struct work_struct cl_recoverd;
78 78  
79   - wait_queue_head_t cl_waitq;
80 79 struct rpc_wait_queue cl_rpcwaitq;
81 80  
82 81 /* used for the setclientid verifier */
... ... @@ -2736,7 +2736,7 @@
2736 2736 case -NFS4ERR_EXPIRED:
2737 2737 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL, NULL);
2738 2738 nfs4_schedule_state_recovery(clp);
2739   - if (test_bit(NFS4CLNT_OK, &clp->cl_state))
  2739 + if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
2740 2740 rpc_wake_up_task(task);
2741 2741 task->tk_status = 0;
2742 2742 return -EAGAIN;
2743 2743  
2744 2744  
2745 2745  
... ... @@ -2753,25 +2753,25 @@
2753 2753 return 0;
2754 2754 }
2755 2755  
  2756 +static int nfs4_wait_bit_interruptible(void *word)
  2757 +{
  2758 + if (signal_pending(current))
  2759 + return -ERESTARTSYS;
  2760 + schedule();
  2761 + return 0;
  2762 +}
  2763 +
2756 2764 static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp)
2757 2765 {
2758   - DEFINE_WAIT(wait);
2759 2766 sigset_t oldset;
2760   - int interruptible, res = 0;
  2767 + int res;
2761 2768  
2762 2769 might_sleep();
2763 2770  
2764 2771 rpc_clnt_sigmask(clnt, &oldset);
2765   - interruptible = TASK_UNINTERRUPTIBLE;
2766   - if (clnt->cl_intr)
2767   - interruptible = TASK_INTERRUPTIBLE;
2768   - prepare_to_wait(&clp->cl_waitq, &wait, interruptible);
2769   - nfs4_schedule_state_recovery(clp);
2770   - if (clnt->cl_intr && signalled())
2771   - res = -ERESTARTSYS;
2772   - else if (!test_bit(NFS4CLNT_OK, &clp->cl_state))
2773   - schedule();
2774   - finish_wait(&clp->cl_waitq, &wait);
  2772 + res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER,
  2773 + nfs4_wait_bit_interruptible,
  2774 + TASK_INTERRUPTIBLE);
2775 2775 rpc_clnt_sigunmask(clnt, &oldset);
2776 2776 return res;
2777 2777 }
... ... @@ -2814,6 +2814,7 @@
2814 2814 case -NFS4ERR_STALE_CLIENTID:
2815 2815 case -NFS4ERR_STALE_STATEID:
2816 2816 case -NFS4ERR_EXPIRED:
  2817 + nfs4_schedule_state_recovery(clp);
2817 2818 ret = nfs4_wait_clnt_recover(server->client, clp);
2818 2819 if (ret == 0)
2819 2820 exception->retry = 1;
... ... @@ -106,11 +106,10 @@
106 106 INIT_WORK(&clp->cl_recoverd, nfs4_recover_state, clp);
107 107 INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp);
108 108 INIT_LIST_HEAD(&clp->cl_superblocks);
109   - init_waitqueue_head(&clp->cl_waitq);
110 109 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
111 110 clp->cl_rpcclient = ERR_PTR(-EINVAL);
112 111 clp->cl_boot_time = CURRENT_TIME;
113   - clp->cl_state = 1 << NFS4CLNT_OK;
  112 + clp->cl_state = 0;
114 113 return clp;
115 114 }
116 115  
... ... @@ -193,7 +192,6 @@
193 192 list_del(&clp->cl_servers);
194 193 spin_unlock(&state_spinlock);
195 194 BUG_ON(!list_empty(&clp->cl_superblocks));
196   - wake_up_all(&clp->cl_waitq);
197 195 rpc_wake_up(&clp->cl_rpcwaitq);
198 196 nfs4_kill_renewd(clp);
199 197 nfs4_free_client(clp);
... ... @@ -741,6 +739,15 @@
741 739 struct completion complete;
742 740 };
743 741  
  742 +static inline void nfs4_clear_recover_bit(struct nfs4_client *clp)
  743 +{
  744 + smp_mb__before_clear_bit();
  745 + clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state);
  746 + smp_mb__after_clear_bit();
  747 + wake_up_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER);
  748 + rpc_wake_up(&clp->cl_rpcwaitq);
  749 +}
  750 +
744 751 /*
745 752 * State recovery routine
746 753 */
... ... @@ -760,9 +767,7 @@
760 767 wait_for_completion(&args.complete);
761 768 return;
762 769 out_failed_clear:
763   - set_bit(NFS4CLNT_OK, &clp->cl_state);
764   - wake_up_all(&clp->cl_waitq);
765   - rpc_wake_up(&clp->cl_rpcwaitq);
  770 + nfs4_clear_recover_bit(clp);
766 771 }
767 772  
768 773 /*
... ... @@ -773,7 +778,7 @@
773 778 {
774 779 if (!clp)
775 780 return;
776   - if (test_and_clear_bit(NFS4CLNT_OK, &clp->cl_state))
  781 + if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
777 782 schedule_work(&clp->cl_recoverd);
778 783 }
779 784  
780 785  
781 786  
... ... @@ -943,13 +948,11 @@
943 948 }
944 949 nfs_delegation_reap_unclaimed(clp);
945 950 out:
946   - set_bit(NFS4CLNT_OK, &clp->cl_state);
947 951 up_write(&clp->cl_sem);
948 952 unlock_kernel();
949   - wake_up_all(&clp->cl_waitq);
950   - rpc_wake_up(&clp->cl_rpcwaitq);
951 953 if (status == -NFS4ERR_CB_PATH_DOWN)
952 954 nfs_handle_cb_pathdown(clp);
  955 + nfs4_clear_recover_bit(clp);
953 956 nfs4_put_client(clp);
954 957 return 0;
955 958 out_error: