aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-01-17 22:57:37 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-01-31 19:28:08 -0500
commit961a828df64979d2a9faeeeee043391670a193b9 (patch)
tree4b7ddaf1a19c589e3c8ec96b6c732faa507f2899 /fs/nfs/nfs4state.c
parent2aeb98f498ce37742b743080fdc6c8cf64053599 (diff)
SUNRPC: Fix potential races in xprt_lock_write_next()
We have to ensure that the wake up from the waitqueue and the assignment of xprt->snd_task are atomic. We can do this by assigning the snd_task while under the waitqueue spinlock. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index a42e60d3ee50..f0e9881c2aa2 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -190,23 +190,22 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp)
190static void nfs4_end_drain_session(struct nfs_client *clp) 190static void nfs4_end_drain_session(struct nfs_client *clp)
191{ 191{
192 struct nfs4_session *ses = clp->cl_session; 192 struct nfs4_session *ses = clp->cl_session;
193 struct nfs4_slot_table *tbl;
193 int max_slots; 194 int max_slots;
194 195
195 if (ses == NULL) 196 if (ses == NULL)
196 return; 197 return;
198 tbl = &ses->fc_slot_table;
197 if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) { 199 if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
198 spin_lock(&ses->fc_slot_table.slot_tbl_lock); 200 spin_lock(&tbl->slot_tbl_lock);
199 max_slots = ses->fc_slot_table.max_slots; 201 max_slots = tbl->max_slots;
200 while (max_slots--) { 202 while (max_slots--) {
201 struct rpc_task *task; 203 if (rpc_wake_up_first(&tbl->slot_tbl_waitq,
202 204 nfs4_set_task_privileged,
203 task = rpc_wake_up_next(&ses->fc_slot_table. 205 NULL) == NULL)
204 slot_tbl_waitq);
205 if (!task)
206 break; 206 break;
207 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
208 } 207 }
209 spin_unlock(&ses->fc_slot_table.slot_tbl_lock); 208 spin_unlock(&tbl->slot_tbl_lock);
210 } 209 }
211} 210}
212 211