aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4session.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4session.c')
-rw-r--r--fs/nfs/nfs4session.c59
1 files changed, 56 insertions, 3 deletions
diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c
index 701170293ceb..066cfa101b41 100644
--- a/fs/nfs/nfs4session.c
+++ b/fs/nfs/nfs4session.c
@@ -217,11 +217,65 @@ static void nfs4_destroy_slot_tables(struct nfs4_session *session)
217 nfs4_shrink_slot_table(&session->bc_slot_table, 0); 217 nfs4_shrink_slot_table(&session->bc_slot_table, 0);
218} 218}
219 219
220static bool nfs41_assign_slot(struct rpc_task *task, void *pslot)
221{
222 struct nfs4_sequence_args *args = task->tk_msg.rpc_argp;
223 struct nfs4_sequence_res *res = task->tk_msg.rpc_resp;
224 struct nfs4_slot *slot = pslot;
225 struct nfs4_slot_table *tbl = slot->table;
226
227 if (nfs4_session_draining(tbl->session) && !args->sa_privileged)
228 return false;
229 slot->renewal_time = jiffies;
230 slot->generation = tbl->generation;
231 args->sa_slot = slot;
232 res->sr_slot = slot;
233 res->sr_status_flags = 0;
234 res->sr_status = 1;
235 return true;
236}
237
238static bool __nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
239 struct nfs4_slot *slot)
240{
241 if (rpc_wake_up_first(&tbl->slot_tbl_waitq, nfs41_assign_slot, slot))
242 return true;
243 return false;
244}
245
246bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
247 struct nfs4_slot *slot)
248{
249 if (slot->slot_nr > tbl->max_slotid)
250 return false;
251 return __nfs41_wake_and_assign_slot(tbl, slot);
252}
253
254static bool nfs41_try_wake_next_slot_table_entry(struct nfs4_slot_table *tbl)
255{
256 struct nfs4_slot *slot = nfs4_alloc_slot(tbl);
257 if (!IS_ERR(slot)) {
258 bool ret = __nfs41_wake_and_assign_slot(tbl, slot);
259 if (ret)
260 return ret;
261 nfs4_free_slot(tbl, slot);
262 }
263 return false;
264}
265
266void nfs41_wake_slot_table(struct nfs4_slot_table *tbl)
267{
268 for (;;) {
269 if (!nfs41_try_wake_next_slot_table_entry(tbl))
270 break;
271 }
272}
273
220/* Update the client's idea of target_highest_slotid */ 274/* Update the client's idea of target_highest_slotid */
221static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl, 275static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl,
222 u32 target_highest_slotid) 276 u32 target_highest_slotid)
223{ 277{
224 unsigned int max_slotid, i; 278 unsigned int max_slotid;
225 279
226 if (tbl->target_highest_slotid == target_highest_slotid) 280 if (tbl->target_highest_slotid == target_highest_slotid)
227 return; 281 return;
@@ -229,9 +283,8 @@ static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl,
229 tbl->generation++; 283 tbl->generation++;
230 284
231 max_slotid = min(NFS4_MAX_SLOT_TABLE - 1, tbl->target_highest_slotid); 285 max_slotid = min(NFS4_MAX_SLOT_TABLE - 1, tbl->target_highest_slotid);
232 for (i = tbl->max_slotid + 1; i <= max_slotid; i++)
233 rpc_wake_up_next(&tbl->slot_tbl_waitq);
234 tbl->max_slotid = max_slotid; 286 tbl->max_slotid = max_slotid;
287 nfs41_wake_slot_table(tbl);
235} 288}
236 289
237void nfs41_set_target_slotid(struct nfs4_slot_table *tbl, 290void nfs41_set_target_slotid(struct nfs4_slot_table *tbl,