aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-08-28 10:28:25 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-08-28 14:23:26 -0400
commit07e8dcbda71ef87e9cbdc42b5bb16a44c1ab839b (patch)
tree09746429d46c78b9c217805eb17b3e026063ae9a
parent045d2a6d076a2ecd7043ea543ea198af943f8b16 (diff)
NFSv4.1: Defer bumping the slot sequence number until we free the slot
For operations like OPEN or LAYOUTGET, which return recallable state (i.e. delegations and layouts) we want to enable the mechanism for resolving recall races in RFC5661 Section 2.10.6.3. To do so, we will want to defer bumping the slot's sequence number until we have finished processing the RPC results. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--fs/nfs/nfs4proc.c9
-rw-r--r--fs/nfs/nfs4session.h3
2 files changed, 9 insertions, 3 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0cc0c319cfdd..de4a89d3d740 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -666,6 +666,11 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
666 tbl = slot->table; 666 tbl = slot->table;
667 session = tbl->session; 667 session = tbl->session;
668 668
669 /* Bump the slot sequence number */
670 if (slot->seq_done)
671 slot->seq_nr++;
672 slot->seq_done = 0;
673
669 spin_lock(&tbl->slot_tbl_lock); 674 spin_lock(&tbl->slot_tbl_lock);
670 /* Be nice to the server: try to ensure that the last transmitted 675 /* Be nice to the server: try to ensure that the last transmitted
671 * value for highest_user_slotid <= target_highest_slotid 676 * value for highest_user_slotid <= target_highest_slotid
@@ -716,7 +721,7 @@ int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
716 switch (res->sr_status) { 721 switch (res->sr_status) {
717 case 0: 722 case 0:
718 /* Update the slot's sequence and clientid lease timer */ 723 /* Update the slot's sequence and clientid lease timer */
719 ++slot->seq_nr; 724 slot->seq_done = 1;
720 clp = session->clp; 725 clp = session->clp;
721 do_renew_lease(clp, res->sr_timestamp); 726 do_renew_lease(clp, res->sr_timestamp);
722 /* Check sequence flags */ 727 /* Check sequence flags */
@@ -771,7 +776,7 @@ int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
771 goto retry_nowait; 776 goto retry_nowait;
772 default: 777 default:
773 /* Just update the slot sequence no. */ 778 /* Just update the slot sequence no. */
774 ++slot->seq_nr; 779 slot->seq_done = 1;
775 } 780 }
776out: 781out:
777 /* The session may be reset by one of the error handlers. */ 782 /* The session may be reset by one of the error handlers. */
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h
index fa75d7db3db3..f703b755351b 100644
--- a/fs/nfs/nfs4session.h
+++ b/fs/nfs/nfs4session.h
@@ -21,7 +21,8 @@ struct nfs4_slot {
21 unsigned long generation; 21 unsigned long generation;
22 u32 slot_nr; 22 u32 slot_nr;
23 u32 seq_nr; 23 u32 seq_nr;
24 unsigned int interrupted : 1; 24 unsigned int interrupted : 1,
25 seq_done : 1;
25}; 26};
26 27
27/* Sessions */ 28/* Sessions */