aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2011-01-05 21:04:34 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-01-06 14:46:25 -0500
commit42acd021824578fa0eeb6eb58d457c23ec5dc9c0 (patch)
tree7affe8e1108373906eefcea00498df088b6dfccb /fs/nfs/nfs4state.c
parentece0de633c4d9106c39ea9f0db1638c42ead2541 (diff)
NFS add session back channel draining
Currently session draining only drains the fore channel. The back channel processing must also be drained. Use the back channel highest_slot_used to indicate that a callback is being processed by the callback thread. Move the session complete to be per channel. When the session is draininig, wait for any current back channel processing to complete and stop all new back channel processing by returning NFS4ERR_DELAY to the back channel client. Drain the back channel, then the fore channel. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
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 485e95e8fd6..6891dedd80f 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;