aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/callback_proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/callback_proc.c')
-rw-r--r--fs/nfs/callback_proc.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 197806fb87ff..29e3c1b011b7 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -327,10 +327,8 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
327 dprintk("%s slot table seqid: %u\n", __func__, slot->seq_nr); 327 dprintk("%s slot table seqid: %u\n", __func__, slot->seq_nr);
328 328
329 /* Normal */ 329 /* Normal */
330 if (likely(args->csa_sequenceid == slot->seq_nr + 1)) { 330 if (likely(args->csa_sequenceid == slot->seq_nr + 1))
331 slot->seq_nr++;
332 goto out_ok; 331 goto out_ok;
333 }
334 332
335 /* Replay */ 333 /* Replay */
336 if (args->csa_sequenceid == slot->seq_nr) { 334 if (args->csa_sequenceid == slot->seq_nr) {
@@ -418,6 +416,7 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
418 struct cb_process_state *cps) 416 struct cb_process_state *cps)
419{ 417{
420 struct nfs4_slot_table *tbl; 418 struct nfs4_slot_table *tbl;
419 struct nfs4_slot *slot;
421 struct nfs_client *clp; 420 struct nfs_client *clp;
422 int i; 421 int i;
423 __be32 status = htonl(NFS4ERR_BADSESSION); 422 __be32 status = htonl(NFS4ERR_BADSESSION);
@@ -429,25 +428,32 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
429 428
430 if (!(clp->cl_session->flags & SESSION4_BACK_CHAN)) 429 if (!(clp->cl_session->flags & SESSION4_BACK_CHAN))
431 goto out; 430 goto out;
431
432 tbl = &clp->cl_session->bc_slot_table; 432 tbl = &clp->cl_session->bc_slot_table;
433 slot = tbl->slots + args->csa_slotid;
433 434
434 spin_lock(&tbl->slot_tbl_lock); 435 spin_lock(&tbl->slot_tbl_lock);
435 /* state manager is resetting the session */ 436 /* state manager is resetting the session */
436 if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) { 437 if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) {
437 spin_unlock(&tbl->slot_tbl_lock);
438 status = htonl(NFS4ERR_DELAY); 438 status = htonl(NFS4ERR_DELAY);
439 /* Return NFS4ERR_BADSESSION if we're draining the session 439 /* Return NFS4ERR_BADSESSION if we're draining the session
440 * in order to reset it. 440 * in order to reset it.
441 */ 441 */
442 if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state)) 442 if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state))
443 status = htonl(NFS4ERR_BADSESSION); 443 status = htonl(NFS4ERR_BADSESSION);
444 goto out; 444 goto out_unlock;
445 } 445 }
446 446
447 status = validate_seqid(&clp->cl_session->bc_slot_table, args); 447 memcpy(&res->csr_sessionid, &args->csa_sessionid,
448 spin_unlock(&tbl->slot_tbl_lock); 448 sizeof(res->csr_sessionid));
449 res->csr_sequenceid = args->csa_sequenceid;
450 res->csr_slotid = args->csa_slotid;
451 res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
452 res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
453
454 status = validate_seqid(tbl, args);
449 if (status) 455 if (status)
450 goto out; 456 goto out_unlock;
451 457
452 cps->slotid = args->csa_slotid; 458 cps->slotid = args->csa_slotid;
453 459
@@ -458,15 +464,17 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
458 */ 464 */
459 if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists)) { 465 if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists)) {
460 status = htonl(NFS4ERR_DELAY); 466 status = htonl(NFS4ERR_DELAY);
461 goto out; 467 goto out_unlock;
462 } 468 }
463 469
464 memcpy(&res->csr_sessionid, &args->csa_sessionid, 470 /*
465 sizeof(res->csr_sessionid)); 471 * RFC5661 20.9.3
466 res->csr_sequenceid = args->csa_sequenceid; 472 * If CB_SEQUENCE returns an error, then the state of the slot
467 res->csr_slotid = args->csa_slotid; 473 * (sequence ID, cached reply) MUST NOT change.
468 res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; 474 */
469 res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; 475 slot->seq_nr++;
476out_unlock:
477 spin_unlock(&tbl->slot_tbl_lock);
470 478
471out: 479out:
472 cps->clp = clp; /* put in nfs4_callback_compound */ 480 cps->clp = clp; /* put in nfs4_callback_compound */