diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-01-17 22:57:37 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-01-31 19:28:08 -0500 |
commit | 961a828df64979d2a9faeeeee043391670a193b9 (patch) | |
tree | 4b7ddaf1a19c589e3c8ec96b6c732faa507f2899 /fs/nfs/nfs4state.c | |
parent | 2aeb98f498ce37742b743080fdc6c8cf64053599 (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.c | 17 |
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) | |||
190 | static void nfs4_end_drain_session(struct nfs_client *clp) | 190 | static 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 | ||