Commit 07e8dcbd authored by Trond Myklebust's avatar Trond Myklebust

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: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 045d2a6d
...@@ -666,6 +666,11 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) ...@@ -666,6 +666,11 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
tbl = slot->table; tbl = slot->table;
session = tbl->session; session = tbl->session;
/* Bump the slot sequence number */
if (slot->seq_done)
slot->seq_nr++;
slot->seq_done = 0;
spin_lock(&tbl->slot_tbl_lock); spin_lock(&tbl->slot_tbl_lock);
/* Be nice to the server: try to ensure that the last transmitted /* Be nice to the server: try to ensure that the last transmitted
* value for highest_user_slotid <= target_highest_slotid * 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,7 +721,7 @@ int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
switch (res->sr_status) { switch (res->sr_status) {
case 0: case 0:
/* Update the slot's sequence and clientid lease timer */ /* Update the slot's sequence and clientid lease timer */
++slot->seq_nr; slot->seq_done = 1;
clp = session->clp; clp = session->clp;
do_renew_lease(clp, res->sr_timestamp); do_renew_lease(clp, res->sr_timestamp);
/* Check sequence flags */ /* Check sequence flags */
...@@ -771,7 +776,7 @@ int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) ...@@ -771,7 +776,7 @@ int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
goto retry_nowait; goto retry_nowait;
default: default:
/* Just update the slot sequence no. */ /* Just update the slot sequence no. */
++slot->seq_nr; slot->seq_done = 1;
} }
out: out:
/* The session may be reset by one of the error handlers. */ /* The session may be reset by one of the error handlers. */
......
...@@ -21,7 +21,8 @@ struct nfs4_slot { ...@@ -21,7 +21,8 @@ struct nfs4_slot {
unsigned long generation; unsigned long generation;
u32 slot_nr; u32 slot_nr;
u32 seq_nr; u32 seq_nr;
unsigned int interrupted : 1; unsigned int interrupted : 1,
seq_done : 1;
}; };
/* Sessions */ /* Sessions */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment