diff options
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 29 |
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 | */ | ||
145 | static void nfs4_end_drain_session(struct nfs_client *clp) | 150 | static 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 | ||
168 | static int nfs4_begin_drain_session(struct nfs_client *clp) | 173 | static 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 | ||
185 | static 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 | |||
184 | int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) | 199 | int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) |
185 | { | 200 | { |
186 | int status; | 201 | int status; |