Commit 6bdb5f21 authored by Bryan Schumaker's avatar Bryan Schumaker Committed by Trond Myklebust

NFS: Add sequence_priviliged_ops for nfs4_proc_sequence()

If I mount an NFS v4.1 server to a single client multiple times and then
run xfstests over each mountpoint I usually get the client into a state
where recovery deadlocks.  The server informs the client of a
cb_path_down sequence error, the client then does a
bind_connection_to_session and checks the status of the lease.

I found that bind_connection_to_session sets the NFS4_SESSION_DRAINING
flag on the client, but this flag is never unset before
nfs4_check_lease() reaches nfs4_proc_sequence().  This causes the client
to deadlock, halting all NFS activity to the server.  nfs4_proc_sequence()
is only called by the state manager, so I can change it to run in privileged
mode to bypass the NFS4_SESSION_DRAINING check and avoid the deadlock.
Signed-off-by: default avatarBryan Schumaker <bjschuma@netapp.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@vger.kernel.org
parent f994c43d
...@@ -6136,13 +6136,26 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data) ...@@ -6136,13 +6136,26 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
rpc_call_start(task); rpc_call_start(task);
} }
static void nfs41_sequence_prepare_privileged(struct rpc_task *task, void *data)
{
rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
nfs41_sequence_prepare(task, data);
}
static const struct rpc_call_ops nfs41_sequence_ops = { static const struct rpc_call_ops nfs41_sequence_ops = {
.rpc_call_done = nfs41_sequence_call_done, .rpc_call_done = nfs41_sequence_call_done,
.rpc_call_prepare = nfs41_sequence_prepare, .rpc_call_prepare = nfs41_sequence_prepare,
.rpc_release = nfs41_sequence_release, .rpc_release = nfs41_sequence_release,
}; };
static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred) static const struct rpc_call_ops nfs41_sequence_privileged_ops = {
.rpc_call_done = nfs41_sequence_call_done,
.rpc_call_prepare = nfs41_sequence_prepare_privileged,
.rpc_release = nfs41_sequence_release,
};
static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred,
const struct rpc_call_ops *seq_ops)
{ {
struct nfs4_sequence_data *calldata; struct nfs4_sequence_data *calldata;
struct rpc_message msg = { struct rpc_message msg = {
...@@ -6152,7 +6165,7 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_ ...@@ -6152,7 +6165,7 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_
struct rpc_task_setup task_setup_data = { struct rpc_task_setup task_setup_data = {
.rpc_client = clp->cl_rpcclient, .rpc_client = clp->cl_rpcclient,
.rpc_message = &msg, .rpc_message = &msg,
.callback_ops = &nfs41_sequence_ops, .callback_ops = seq_ops,
.flags = RPC_TASK_ASYNC | RPC_TASK_SOFT, .flags = RPC_TASK_ASYNC | RPC_TASK_SOFT,
}; };
...@@ -6179,7 +6192,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr ...@@ -6179,7 +6192,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr
if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0) if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0)
return 0; return 0;
task = _nfs41_proc_sequence(clp, cred); task = _nfs41_proc_sequence(clp, cred, &nfs41_sequence_ops);
if (IS_ERR(task)) if (IS_ERR(task))
ret = PTR_ERR(task); ret = PTR_ERR(task);
else else
...@@ -6193,7 +6206,7 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred) ...@@ -6193,7 +6206,7 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
struct rpc_task *task; struct rpc_task *task;
int ret; int ret;
task = _nfs41_proc_sequence(clp, cred); task = _nfs41_proc_sequence(clp, cred, &nfs41_sequence_privileged_ops);
if (IS_ERR(task)) { if (IS_ERR(task)) {
ret = PTR_ERR(task); ret = PTR_ERR(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