aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 485e95e8fd62..6891dedd80f1 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -142,6 +142,11 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp)
142 return status; 142 return status;
143} 143}
144 144
145/*
146 * Back channel returns NFS4ERR_DELAY for new requests when
147 * NFS4_SESSION_DRAINING is set so there is no work to be done when draining
148 * is ended.
149 */
145static void nfs4_end_drain_session(struct nfs_client *clp) 150static void nfs4_end_drain_session(struct nfs_client *clp)
146{ 151{
147 struct nfs4_session *ses = clp->cl_session; 152 struct nfs4_session *ses = clp->cl_session;
@@ -165,22 +170,32 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
165 } 170 }
166} 171}
167 172
168static int nfs4_begin_drain_session(struct nfs_client *clp) 173static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl)
169{ 174{
170 struct nfs4_session *ses = clp->cl_session;
171 struct nfs4_slot_table *tbl = &ses->fc_slot_table;
172
173 spin_lock(&tbl->slot_tbl_lock); 175 spin_lock(&tbl->slot_tbl_lock);
174 set_bit(NFS4_SESSION_DRAINING, &ses->session_state);
175 if (tbl->highest_used_slotid != -1) { 176 if (tbl->highest_used_slotid != -1) {
176 INIT_COMPLETION(ses->complete); 177 INIT_COMPLETION(tbl->complete);
177 spin_unlock(&tbl->slot_tbl_lock); 178 spin_unlock(&tbl->slot_tbl_lock);
178 return wait_for_completion_interruptible(&ses->complete); 179 return wait_for_completion_interruptible(&tbl->complete);
179 } 180 }
180 spin_unlock(&tbl->slot_tbl_lock); 181 spin_unlock(&tbl->slot_tbl_lock);
181 return 0; 182 return 0;
182} 183}
183 184
185static int nfs4_begin_drain_session(struct nfs_client *clp)
186{
187 struct nfs4_session *ses = clp->cl_session;
188 int ret = 0;
189
190 set_bit(NFS4_SESSION_DRAINING, &ses->session_state);
191 /* back channel */
192 ret = nfs4_wait_on_slot_tbl(&ses->bc_slot_table);
193 if (ret)
194 return ret;
195 /* fore channel */
196 return nfs4_wait_on_slot_tbl(&ses->fc_slot_table);
197}
198
184int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) 199int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
185{ 200{
186 int status; 201 int status;