diff options
Diffstat (limited to 'fs/nfs/callback_proc.c')
| -rw-r--r-- | fs/nfs/callback_proc.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 74780f9f852c..43926add945b 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
| @@ -348,7 +348,7 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) | |||
| 348 | /* Normal */ | 348 | /* Normal */ |
| 349 | if (likely(args->csa_sequenceid == slot->seq_nr + 1)) { | 349 | if (likely(args->csa_sequenceid == slot->seq_nr + 1)) { |
| 350 | slot->seq_nr++; | 350 | slot->seq_nr++; |
| 351 | return htonl(NFS4_OK); | 351 | goto out_ok; |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | /* Replay */ | 354 | /* Replay */ |
| @@ -367,11 +367,14 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) | |||
| 367 | /* Wraparound */ | 367 | /* Wraparound */ |
| 368 | if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) { | 368 | if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) { |
| 369 | slot->seq_nr = 1; | 369 | slot->seq_nr = 1; |
| 370 | return htonl(NFS4_OK); | 370 | goto out_ok; |
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | /* Misordered request */ | 373 | /* Misordered request */ |
| 374 | return htonl(NFS4ERR_SEQ_MISORDERED); | 374 | return htonl(NFS4ERR_SEQ_MISORDERED); |
| 375 | out_ok: | ||
| 376 | tbl->highest_used_slotid = args->csa_slotid; | ||
| 377 | return htonl(NFS4_OK); | ||
| 375 | } | 378 | } |
| 376 | 379 | ||
| 377 | /* | 380 | /* |
| @@ -433,26 +436,37 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, | |||
| 433 | struct cb_sequenceres *res, | 436 | struct cb_sequenceres *res, |
| 434 | struct cb_process_state *cps) | 437 | struct cb_process_state *cps) |
| 435 | { | 438 | { |
| 439 | struct nfs4_slot_table *tbl; | ||
| 436 | struct nfs_client *clp; | 440 | struct nfs_client *clp; |
| 437 | int i; | 441 | int i; |
| 438 | __be32 status = htonl(NFS4ERR_BADSESSION); | 442 | __be32 status = htonl(NFS4ERR_BADSESSION); |
| 439 | 443 | ||
| 440 | cps->clp = NULL; | ||
| 441 | |||
| 442 | clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid); | 444 | clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid); |
| 443 | if (clp == NULL) | 445 | if (clp == NULL) |
| 444 | goto out; | 446 | goto out; |
| 445 | 447 | ||
| 448 | tbl = &clp->cl_session->bc_slot_table; | ||
| 449 | |||
| 450 | spin_lock(&tbl->slot_tbl_lock); | ||
| 446 | /* state manager is resetting the session */ | 451 | /* state manager is resetting the session */ |
| 447 | if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) { | 452 | if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) { |
| 448 | status = NFS4ERR_DELAY; | 453 | spin_unlock(&tbl->slot_tbl_lock); |
| 454 | status = htonl(NFS4ERR_DELAY); | ||
| 455 | /* Return NFS4ERR_BADSESSION if we're draining the session | ||
| 456 | * in order to reset it. | ||
| 457 | */ | ||
| 458 | if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state)) | ||
| 459 | status = htonl(NFS4ERR_BADSESSION); | ||
| 449 | goto out; | 460 | goto out; |
| 450 | } | 461 | } |
| 451 | 462 | ||
| 452 | status = validate_seqid(&clp->cl_session->bc_slot_table, args); | 463 | status = validate_seqid(&clp->cl_session->bc_slot_table, args); |
| 464 | spin_unlock(&tbl->slot_tbl_lock); | ||
| 453 | if (status) | 465 | if (status) |
| 454 | goto out; | 466 | goto out; |
| 455 | 467 | ||
| 468 | cps->slotid = args->csa_slotid; | ||
| 469 | |||
| 456 | /* | 470 | /* |
| 457 | * Check for pending referring calls. If a match is found, a | 471 | * Check for pending referring calls. If a match is found, a |
| 458 | * related callback was received before the response to the original | 472 | * related callback was received before the response to the original |
| @@ -469,7 +483,6 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, | |||
| 469 | res->csr_slotid = args->csa_slotid; | 483 | res->csr_slotid = args->csa_slotid; |
| 470 | res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; | 484 | res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; |
| 471 | res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; | 485 | res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; |
| 472 | nfs4_cb_take_slot(clp); | ||
| 473 | 486 | ||
| 474 | out: | 487 | out: |
| 475 | cps->clp = clp; /* put in nfs4_callback_compound */ | 488 | cps->clp = clp; /* put in nfs4_callback_compound */ |
