NFS: Ensure that we handle NFS4ERR_STALE_STATEID correctly
Even if the server is crazy, we should be able to mark the stateid as being bad, to ensure it gets recovered. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
Родитель
03391693a9
Коммит
a2c0b9e291
|
@ -278,6 +278,7 @@ extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
|
||||||
extern void nfs4_schedule_state_recovery(struct nfs_client *);
|
extern void nfs4_schedule_state_recovery(struct nfs_client *);
|
||||||
extern void nfs4_schedule_state_manager(struct nfs_client *);
|
extern void nfs4_schedule_state_manager(struct nfs_client *);
|
||||||
extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state);
|
extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state);
|
||||||
|
extern int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state);
|
||||||
extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
|
extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
|
||||||
extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
|
extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
|
||||||
extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
|
extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
|
||||||
|
|
|
@ -249,14 +249,14 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
break;
|
break;
|
||||||
nfs4_state_mark_reclaim_nograce(clp, state);
|
nfs4_state_mark_reclaim_nograce(clp, state);
|
||||||
case -NFS4ERR_STALE_CLIENTID:
|
goto do_state_recovery;
|
||||||
case -NFS4ERR_STALE_STATEID:
|
case -NFS4ERR_STALE_STATEID:
|
||||||
|
if (state == NULL)
|
||||||
|
break;
|
||||||
|
nfs4_state_mark_reclaim_reboot(clp, state);
|
||||||
|
case -NFS4ERR_STALE_CLIENTID:
|
||||||
case -NFS4ERR_EXPIRED:
|
case -NFS4ERR_EXPIRED:
|
||||||
nfs4_schedule_state_recovery(clp);
|
goto do_state_recovery;
|
||||||
ret = nfs4_wait_clnt_recover(clp);
|
|
||||||
if (ret == 0)
|
|
||||||
exception->retry = 1;
|
|
||||||
break;
|
|
||||||
#if defined(CONFIG_NFS_V4_1)
|
#if defined(CONFIG_NFS_V4_1)
|
||||||
case -NFS4ERR_BADSESSION:
|
case -NFS4ERR_BADSESSION:
|
||||||
case -NFS4ERR_BADSLOT:
|
case -NFS4ERR_BADSLOT:
|
||||||
|
@ -289,6 +289,12 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
|
||||||
}
|
}
|
||||||
/* We failed to handle the error */
|
/* We failed to handle the error */
|
||||||
return nfs4_map_errors(ret);
|
return nfs4_map_errors(ret);
|
||||||
|
do_state_recovery:
|
||||||
|
nfs4_schedule_state_recovery(clp);
|
||||||
|
ret = nfs4_wait_clnt_recover(clp);
|
||||||
|
if (ret == 0)
|
||||||
|
exception->retry = 1;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3420,15 +3426,14 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
break;
|
break;
|
||||||
nfs4_state_mark_reclaim_nograce(clp, state);
|
nfs4_state_mark_reclaim_nograce(clp, state);
|
||||||
case -NFS4ERR_STALE_CLIENTID:
|
goto do_state_recovery;
|
||||||
case -NFS4ERR_STALE_STATEID:
|
case -NFS4ERR_STALE_STATEID:
|
||||||
|
if (state == NULL)
|
||||||
|
break;
|
||||||
|
nfs4_state_mark_reclaim_reboot(clp, state);
|
||||||
|
case -NFS4ERR_STALE_CLIENTID:
|
||||||
case -NFS4ERR_EXPIRED:
|
case -NFS4ERR_EXPIRED:
|
||||||
rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
|
goto do_state_recovery;
|
||||||
nfs4_schedule_state_recovery(clp);
|
|
||||||
if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
|
|
||||||
rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
|
|
||||||
task->tk_status = 0;
|
|
||||||
return -EAGAIN;
|
|
||||||
#if defined(CONFIG_NFS_V4_1)
|
#if defined(CONFIG_NFS_V4_1)
|
||||||
case -NFS4ERR_BADSESSION:
|
case -NFS4ERR_BADSESSION:
|
||||||
case -NFS4ERR_BADSLOT:
|
case -NFS4ERR_BADSLOT:
|
||||||
|
@ -3456,6 +3461,13 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
|
||||||
}
|
}
|
||||||
task->tk_status = nfs4_map_errors(task->tk_status);
|
task->tk_status = nfs4_map_errors(task->tk_status);
|
||||||
return 0;
|
return 0;
|
||||||
|
do_state_recovery:
|
||||||
|
rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
|
||||||
|
nfs4_schedule_state_recovery(clp);
|
||||||
|
if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
|
||||||
|
rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
|
||||||
|
task->tk_status = 0;
|
||||||
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -4099,6 +4111,12 @@ static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_
|
||||||
(lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
|
(lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
|
||||||
nfs4_state_mark_reclaim_nograce(clp, state);
|
nfs4_state_mark_reclaim_nograce(clp, state);
|
||||||
lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
|
lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
|
||||||
|
break;
|
||||||
|
case -NFS4ERR_STALE_STATEID:
|
||||||
|
if (new_lock_owner != 0 ||
|
||||||
|
(lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
|
||||||
|
nfs4_state_mark_reclaim_reboot(clp, state);
|
||||||
|
lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -901,7 +901,7 @@ void nfs4_schedule_state_recovery(struct nfs_client *clp)
|
||||||
nfs4_schedule_state_manager(clp);
|
nfs4_schedule_state_manager(clp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state)
|
int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state)
|
||||||
{
|
{
|
||||||
|
|
||||||
set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
|
set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче