summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKinglong Mee <kinglongmee@gmail.com>2015-06-02 06:58:46 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-06-11 14:00:40 -0400
commite937ee714b2df638275a61a99e0d033682f764d2 (patch)
treedaf249d4134ed0ad095982e5cc83cda4e1c98994
parent8eee52af27b96047894bd18649102a0d2de3c3bb (diff)
nfs: Only update callback sequnce id when CB_SEQUENCE success
When testing pnfs layout, nfsd got error NFS4ERR_SEQ_MISORDERED. It is caused by nfs return NFS4ERR_DELAY before validate_seqid(), don't update the sequnce id, but nfsd updates the sequnce id !!! According to RFC5661 20.9.3, " If CB_SEQUENCE returns an error, then the state of the slot (sequence ID, cached reply) MUST NOT change. " Signed-off-by: Kinglong Mee <kinglongmee@gmail.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--fs/nfs/callback_proc.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 197806fb87ff..7e9653aae5d8 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,7 +428,9 @@ __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 */
@@ -444,7 +445,7 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
444 goto out; 445 goto out;
445 } 446 }
446 447
447 status = validate_seqid(&clp->cl_session->bc_slot_table, args); 448 status = validate_seqid(tbl, args);
448 spin_unlock(&tbl->slot_tbl_lock); 449 spin_unlock(&tbl->slot_tbl_lock);
449 if (status) 450 if (status)
450 goto out; 451 goto out;
@@ -468,6 +469,13 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
468 res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; 469 res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
469 res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; 470 res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
470 471
472 /*
473 * RFC5661 20.9.3
474 * If CB_SEQUENCE returns an error, then the state of the slot
475 * (sequence ID, cached reply) MUST NOT change.
476 */
477 slot->seq_nr++;
478
471out: 479out:
472 cps->clp = clp; /* put in nfs4_callback_compound */ 480 cps->clp = clp; /* put in nfs4_callback_compound */
473 for (i = 0; i < args->csa_nrclists; i++) 481 for (i = 0; i < args->csa_nrclists; i++)