aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandros Batsakis <batsakis@netapp.com>2009-12-15 00:27:56 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-12-15 13:55:18 -0500
commit689cf5c15baf603a8041565ff0bd0d65d1634fd7 (patch)
tree83fc6e666f0c099486cfcdb41b40c02d9fa163b7
parentcf3b01b54880debb01ea7d471123da5887a7c2cb (diff)
nfs: enforce FIFO ordering of operations trying to acquire slot
Signed-off-by: Alexandros Batsakis <batsakis@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4proc.c22
-rw-r--r--fs/nfs/nfs4state.c18
-rw-r--r--net/sunrpc/sched.c1
3 files changed, 35 insertions, 6 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index acd698baf8eb..02513da9a016 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -346,8 +346,12 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
346 */ 346 */
347static void nfs41_check_drain_session_complete(struct nfs4_session *ses) 347static void nfs41_check_drain_session_complete(struct nfs4_session *ses)
348{ 348{
349 struct rpc_task *task;
350
349 if (!test_bit(NFS4CLNT_SESSION_DRAINING, &ses->clp->cl_state)) { 351 if (!test_bit(NFS4CLNT_SESSION_DRAINING, &ses->clp->cl_state)) {
350 rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq); 352 task = rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq);
353 if (task)
354 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
351 return; 355 return;
352 } 356 }
353 357
@@ -483,6 +487,14 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
483 return -EAGAIN; 487 return -EAGAIN;
484 } 488 }
485 489
490 if (!rpc_queue_empty(&tbl->slot_tbl_waitq) &&
491 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
492 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
493 spin_unlock(&tbl->slot_tbl_lock);
494 dprintk("%s enforce FIFO order\n", __func__);
495 return -EAGAIN;
496 }
497
486 slotid = nfs4_find_slot(tbl); 498 slotid = nfs4_find_slot(tbl);
487 if (slotid == NFS4_MAX_SLOT_TABLE) { 499 if (slotid == NFS4_MAX_SLOT_TABLE) {
488 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 500 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
@@ -492,6 +504,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
492 } 504 }
493 spin_unlock(&tbl->slot_tbl_lock); 505 spin_unlock(&tbl->slot_tbl_lock);
494 506
507 rpc_task_set_priority(task, RPC_PRIORITY_NORMAL);
495 slot = tbl->slots + slotid; 508 slot = tbl->slots + slotid;
496 args->sa_session = session; 509 args->sa_session = session;
497 args->sa_slotid = slotid; 510 args->sa_slotid = slotid;
@@ -4401,11 +4414,12 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task,
4401 (struct nfs4_get_lease_time_data *)calldata; 4414 (struct nfs4_get_lease_time_data *)calldata;
4402 4415
4403 dprintk("--> %s\n", __func__); 4416 dprintk("--> %s\n", __func__);
4417 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
4404 /* just setup sequence, do not trigger session recovery 4418 /* just setup sequence, do not trigger session recovery
4405 since we're invoked within one */ 4419 since we're invoked within one */
4406 ret = nfs41_setup_sequence(data->clp->cl_session, 4420 ret = nfs41_setup_sequence(data->clp->cl_session,
4407 &data->args->la_seq_args, 4421 &data->args->la_seq_args,
4408 &data->res->lr_seq_res, 0, task); 4422 &data->res->lr_seq_res, 0, task);
4409 4423
4410 BUG_ON(ret == -EAGAIN); 4424 BUG_ON(ret == -EAGAIN);
4411 rpc_call_start(task); 4425 rpc_call_start(task);
@@ -4625,7 +4639,7 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4625 tbl = &session->fc_slot_table; 4639 tbl = &session->fc_slot_table;
4626 tbl->highest_used_slotid = -1; 4640 tbl->highest_used_slotid = -1;
4627 spin_lock_init(&tbl->slot_tbl_lock); 4641 spin_lock_init(&tbl->slot_tbl_lock);
4628 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); 4642 rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
4629 4643
4630 tbl = &session->bc_slot_table; 4644 tbl = &session->bc_slot_table;
4631 tbl->highest_used_slotid = -1; 4645 tbl->highest_used_slotid = -1;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index e76427e6346f..0e45075836b2 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -138,8 +138,22 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp)
138static void nfs41_end_drain_session(struct nfs_client *clp, 138static void nfs41_end_drain_session(struct nfs_client *clp,
139 struct nfs4_session *ses) 139 struct nfs4_session *ses)
140{ 140{
141 if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) 141 int max_slots;
142 rpc_wake_up(&ses->fc_slot_table.slot_tbl_waitq); 142
143 if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) {
144 spin_lock(&ses->fc_slot_table.slot_tbl_lock);
145 max_slots = ses->fc_slot_table.max_slots;
146 while (max_slots--) {
147 struct rpc_task *task;
148
149 task = rpc_wake_up_next(&ses->fc_slot_table.
150 slot_tbl_waitq);
151 if (!task)
152 break;
153 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
154 }
155 spin_unlock(&ses->fc_slot_table.slot_tbl_lock);
156 }
143} 157}
144 158
145static int nfs41_begin_drain_session(struct nfs_client *clp, 159static int nfs41_begin_drain_session(struct nfs_client *clp,
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 89ea8e69ec78..aae6907fd546 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -210,6 +210,7 @@ void rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qnam
210{ 210{
211 __rpc_init_priority_wait_queue(queue, qname, RPC_NR_PRIORITY); 211 __rpc_init_priority_wait_queue(queue, qname, RPC_NR_PRIORITY);
212} 212}
213EXPORT_SYMBOL_GPL(rpc_init_priority_wait_queue);
213 214
214void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname) 215void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname)
215{ 216{