diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-12-05 19:32:19 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-12-05 19:32:19 -0500 |
commit | 35dc1d74a8d97a302a202ccb6751bf2bdbf5173e (patch) | |
tree | 0791d69bc97fac30b9f52e7f96479e31386bb6f8 /fs/nfs | |
parent | d61e612a728fb9bf848c4383f8f6645e822d5b57 (diff) |
NFSv41: Fix up some bugs in the NFS4CLNT_SESSION_DRAINING code
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 17 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 4 |
2 files changed, 10 insertions, 11 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index c06a2bade59e..9da7a872ee0e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -318,13 +318,14 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp | |||
318 | * so we need to scan down from highest_used_slotid to 0 looking for the now | 318 | * so we need to scan down from highest_used_slotid to 0 looking for the now |
319 | * highest slotid in use. | 319 | * highest slotid in use. |
320 | * If none found, highest_used_slotid is set to -1. | 320 | * If none found, highest_used_slotid is set to -1. |
321 | * | ||
322 | * Must be called while holding tbl->slot_tbl_lock | ||
321 | */ | 323 | */ |
322 | static void | 324 | static void |
323 | nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) | 325 | nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) |
324 | { | 326 | { |
325 | int slotid = free_slotid; | 327 | int slotid = free_slotid; |
326 | 328 | ||
327 | spin_lock(&tbl->slot_tbl_lock); | ||
328 | /* clear used bit in bitmap */ | 329 | /* clear used bit in bitmap */ |
329 | __clear_bit(slotid, tbl->used_slots); | 330 | __clear_bit(slotid, tbl->used_slots); |
330 | 331 | ||
@@ -336,7 +337,6 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) | |||
336 | else | 337 | else |
337 | tbl->highest_used_slotid = -1; | 338 | tbl->highest_used_slotid = -1; |
338 | } | 339 | } |
339 | spin_unlock(&tbl->slot_tbl_lock); | ||
340 | dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__, | 340 | dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__, |
341 | free_slotid, tbl->highest_used_slotid); | 341 | free_slotid, tbl->highest_used_slotid); |
342 | } | 342 | } |
@@ -351,22 +351,23 @@ static void nfs41_sequence_free_slot(const struct nfs_client *clp, | |||
351 | /* just wake up the next guy waiting since | 351 | /* just wake up the next guy waiting since |
352 | * we may have not consumed a slot after all */ | 352 | * we may have not consumed a slot after all */ |
353 | dprintk("%s: No slot\n", __func__); | 353 | dprintk("%s: No slot\n", __func__); |
354 | } else { | 354 | return; |
355 | nfs4_free_slot(tbl, res->sr_slotid); | ||
356 | res->sr_slotid = NFS4_MAX_SLOT_TABLE; | ||
357 | } | 355 | } |
358 | 356 | ||
357 | spin_lock(&tbl->slot_tbl_lock); | ||
358 | nfs4_free_slot(tbl, res->sr_slotid); | ||
359 | |||
359 | /* Signal state manager thread if session is drained */ | 360 | /* Signal state manager thread if session is drained */ |
360 | if (test_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) { | 361 | if (test_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) { |
361 | spin_lock(&tbl->slot_tbl_lock); | ||
362 | if (tbl->highest_used_slotid == -1) { | 362 | if (tbl->highest_used_slotid == -1) { |
363 | dprintk("%s COMPLETE: Session Drained\n", __func__); | 363 | dprintk("%s COMPLETE: Session Drained\n", __func__); |
364 | complete(&clp->cl_session->complete); | 364 | complete(&clp->cl_session->complete); |
365 | } | 365 | } |
366 | spin_unlock(&tbl->slot_tbl_lock); | ||
367 | } else { | 366 | } else { |
368 | rpc_wake_up_next(&tbl->slot_tbl_waitq); | 367 | rpc_wake_up_next(&tbl->slot_tbl_waitq); |
369 | } | 368 | } |
369 | spin_unlock(&tbl->slot_tbl_lock); | ||
370 | res->sr_slotid = NFS4_MAX_SLOT_TABLE; | ||
370 | } | 371 | } |
371 | 372 | ||
372 | static void nfs41_sequence_done(struct nfs_client *clp, | 373 | static void nfs41_sequence_done(struct nfs_client *clp, |
@@ -470,7 +471,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session, | |||
470 | */ | 471 | */ |
471 | dprintk("%s Schedule Session Reset\n", __func__); | 472 | dprintk("%s Schedule Session Reset\n", __func__); |
472 | rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); | 473 | rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); |
473 | nfs4_schedule_state_manager(session->clp); | ||
474 | spin_unlock(&tbl->slot_tbl_lock); | 474 | spin_unlock(&tbl->slot_tbl_lock); |
475 | return -EAGAIN; | 475 | return -EAGAIN; |
476 | } | 476 | } |
@@ -4489,7 +4489,6 @@ static int nfs4_reset_slot_tables(struct nfs4_session *session) | |||
4489 | 1); | 4489 | 1); |
4490 | if (status) | 4490 | if (status) |
4491 | return status; | 4491 | return status; |
4492 | init_completion(&session->complete); | ||
4493 | 4492 | ||
4494 | status = nfs4_reset_slot_table(&session->bc_slot_table, | 4493 | status = nfs4_reset_slot_table(&session->bc_slot_table, |
4495 | session->bc_attrs.max_reqs, | 4494 | session->bc_attrs.max_reqs, |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 37f020eb92f2..ef9622e500e4 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -1220,10 +1220,10 @@ static int nfs4_reset_session(struct nfs_client *clp) | |||
1220 | struct nfs4_slot_table *tbl = &ses->fc_slot_table; | 1220 | struct nfs4_slot_table *tbl = &ses->fc_slot_table; |
1221 | int status; | 1221 | int status; |
1222 | 1222 | ||
1223 | INIT_COMPLETION(ses->complete); | ||
1224 | spin_lock(&tbl->slot_tbl_lock); | 1223 | spin_lock(&tbl->slot_tbl_lock); |
1225 | set_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state); | 1224 | set_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state); |
1226 | if (tbl->highest_used_slotid != -1) { | 1225 | if (tbl->highest_used_slotid != -1) { |
1226 | INIT_COMPLETION(ses->complete); | ||
1227 | spin_unlock(&tbl->slot_tbl_lock); | 1227 | spin_unlock(&tbl->slot_tbl_lock); |
1228 | status = wait_for_completion_interruptible(&ses->complete); | 1228 | status = wait_for_completion_interruptible(&ses->complete); |
1229 | if (status) /* -ERESTARTSYS */ | 1229 | if (status) /* -ERESTARTSYS */ |
@@ -1247,7 +1247,7 @@ static int nfs4_reset_session(struct nfs_client *clp) | |||
1247 | out: | 1247 | out: |
1248 | /* Wake up the next rpc task even on error */ | 1248 | /* Wake up the next rpc task even on error */ |
1249 | clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state); | 1249 | clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state); |
1250 | rpc_wake_up_next(&clp->cl_session->fc_slot_table.slot_tbl_waitq); | 1250 | rpc_wake_up(&clp->cl_session->fc_slot_table.slot_tbl_waitq); |
1251 | return status; | 1251 | return status; |
1252 | } | 1252 | } |
1253 | 1253 | ||