Commit 85563073 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4.1: Handle NFS4ERR_BADSLOT errors correctly

Most (all) NFS4ERR_BADSLOT errors are due to the client failing to
respect the server's sr_highest_slotid limit. This mainly happens
due to reordered RPC requests.
The way to handle it is simply to drop the slot that we're using,
and retry using the new highest_slotid limits.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 7ce0171d
...@@ -422,6 +422,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res * ...@@ -422,6 +422,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
struct nfs4_slot *slot; struct nfs4_slot *slot;
unsigned long timestamp; unsigned long timestamp;
struct nfs_client *clp; struct nfs_client *clp;
int ret = 1;
/* /*
* sr_status remains 1 if an RPC level error occurred. The server * sr_status remains 1 if an RPC level error occurred. The server
...@@ -462,6 +463,16 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res * ...@@ -462,6 +463,16 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
slot->slot_nr, slot->slot_nr,
slot->seq_nr); slot->seq_nr);
goto out_retry; goto out_retry;
case -NFS4ERR_BADSLOT:
/*
* The slot id we used was probably retired. Try again
* using a different slot id.
*/
if (rpc_restart_call_prepare(task)) {
task->tk_status = 0;
ret = 0;
}
break;
default: default:
/* Just update the slot sequence no. */ /* Just update the slot sequence no. */
++slot->seq_nr; ++slot->seq_nr;
...@@ -470,7 +481,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res * ...@@ -470,7 +481,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
/* The session may be reset by one of the error handlers. */ /* The session may be reset by one of the error handlers. */
dprintk("%s: Error %d free the slot \n", __func__, res->sr_status); dprintk("%s: Error %d free the slot \n", __func__, res->sr_status);
nfs41_sequence_free_slot(res); nfs41_sequence_free_slot(res);
return 1; return ret;
out_retry: out_retry:
if (!rpc_restart_call(task)) if (!rpc_restart_call(task))
goto out; goto out;
......
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