diff options
| -rw-r--r-- | fs/nfs/nfs4proc.c | 22 | ||||
| -rw-r--r-- | fs/nfs/nfs4state.c | 18 | ||||
| -rw-r--r-- | net/sunrpc/sched.c | 1 | 
3 files changed, 35 insertions, 6 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index acd698baf8e..02513da9a01 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)   */  static void nfs41_check_drain_session_complete(struct nfs4_session *ses)  { +	struct rpc_task *task; +  	if (!test_bit(NFS4CLNT_SESSION_DRAINING, &ses->clp->cl_state)) { -		rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq); +		task = rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq); +		if (task) +			rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);  		return;  	} @@ -483,6 +487,14 @@ static int nfs41_setup_sequence(struct nfs4_session *session,  		return -EAGAIN;  	} +	if (!rpc_queue_empty(&tbl->slot_tbl_waitq) && +	    !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) { +		rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); +		spin_unlock(&tbl->slot_tbl_lock); +		dprintk("%s enforce FIFO order\n", __func__); +		return -EAGAIN; +	} +  	slotid = nfs4_find_slot(tbl);  	if (slotid == NFS4_MAX_SLOT_TABLE) {  		rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); @@ -492,6 +504,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,  	}  	spin_unlock(&tbl->slot_tbl_lock); +	rpc_task_set_priority(task, RPC_PRIORITY_NORMAL);  	slot = tbl->slots + slotid;  	args->sa_session = session;  	args->sa_slotid = slotid; @@ -4401,11 +4414,12 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task,  			(struct nfs4_get_lease_time_data *)calldata;  	dprintk("--> %s\n", __func__); +	rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);  	/* just setup sequence, do not trigger session recovery  	   since we're invoked within one */  	ret = nfs41_setup_sequence(data->clp->cl_session, -					&data->args->la_seq_args, -					&data->res->lr_seq_res, 0, task); +				   &data->args->la_seq_args, +				   &data->res->lr_seq_res, 0, task);  	BUG_ON(ret == -EAGAIN);  	rpc_call_start(task); @@ -4625,7 +4639,7 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)  	tbl = &session->fc_slot_table;  	tbl->highest_used_slotid = -1;  	spin_lock_init(&tbl->slot_tbl_lock); -	rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); +	rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");  	tbl = &session->bc_slot_table;  	tbl->highest_used_slotid = -1; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index e76427e6346..0e45075836b 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)  static void nfs41_end_drain_session(struct nfs_client *clp,  		struct nfs4_session *ses)  { -	if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) -		rpc_wake_up(&ses->fc_slot_table.slot_tbl_waitq); +	int max_slots; + +	if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) { +		spin_lock(&ses->fc_slot_table.slot_tbl_lock); +		max_slots = ses->fc_slot_table.max_slots; +		while (max_slots--) { +			struct rpc_task *task; + +			task = rpc_wake_up_next(&ses->fc_slot_table. +						slot_tbl_waitq); +			if (!task) +				break; +			rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED); +		} +		spin_unlock(&ses->fc_slot_table.slot_tbl_lock); +	}  }  static int nfs41_begin_drain_session(struct nfs_client *clp, diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 89ea8e69ec7..aae6907fd54 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  {  	__rpc_init_priority_wait_queue(queue, qname, RPC_NR_PRIORITY);  } +EXPORT_SYMBOL_GPL(rpc_init_priority_wait_queue);  void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname)  {  |