session: handle NFS4ERR_BADSLOT errors

NFS4ERR_BADSLOT indicates that the supplied slotid is outside the server's expected range.  update table.max_slots to this value to prevent it from being used again, then acquire a new slot and retry the rpc

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2012-05-10 12:26:32 -04:00 committed by Olga Kornievskaia
parent a3146af76d
commit 30e8df149e
3 changed files with 37 additions and 0 deletions

View file

@ -370,6 +370,10 @@ void nfs41_session_sequence(
nfs41_session *session, nfs41_session *session,
bool_t cachethis); bool_t cachethis);
int nfs41_session_bad_slot(
IN nfs41_session *session,
IN OUT struct __nfs41_sequence_args *args);
/* nfs41_server.c */ /* nfs41_server.c */
void nfs41_server_list_init(); void nfs41_server_list_init();

View file

@ -254,6 +254,12 @@ retry:
goto do_retry; goto do_retry;
goto out; goto out;
case NFS4ERR_BADSLOT:
/* free the slot and retry with a new one */
if (op1 != OP_SEQUENCE || nfs41_session_bad_slot(session, args))
goto out;
goto retry;
case NFS4ERR_GRACE: case NFS4ERR_GRACE:
case NFS4ERR_DELAY: case NFS4ERR_DELAY:
#define RETRY_INDEFINITELY #define RETRY_INDEFINITELY

View file

@ -172,6 +172,33 @@ int nfs41_session_recall_slot(
return NFS4_OK; return NFS4_OK;
} }
int nfs41_session_bad_slot(
IN nfs41_session *session,
IN OUT nfs41_sequence_args *args)
{
nfs41_slot_table *table = &session->table;
int status = NFS4ERR_BADSLOT;
if (args->sa_slotid == 0) {
eprintf("server bug detected: NFS4ERR_BADSLOT for slotid=0\n");
goto out;
}
/* avoid using any slots >= bad_slotid */
EnterCriticalSection(&table->lock);
if (table->max_slots > args->sa_slotid)
resize_slot_table(table, args->sa_slotid);
LeaveCriticalSection(&table->lock);
/* get a new slot */
nfs41_session_free_slot(session, args->sa_slotid);
nfs41_session_get_slot(session, &args->sa_slotid,
&args->sa_sequenceid, &args->sa_highest_slotid);
status = NFS4_OK;
out:
return status;
}
void nfs41_session_sequence( void nfs41_session_sequence(
nfs41_sequence_args *args, nfs41_sequence_args *args,
nfs41_session *session, nfs41_session *session,