Commit 2240a9e2 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4.1: We must release the sequence id when we fail to get a session slot

If we do not release the sequence id in cases where we fail to get a
session slot, then we can deadlock if we hit a recovery scenario.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@vger.kernel.org
parent 399f11c3
...@@ -1571,8 +1571,10 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) ...@@ -1571,8 +1571,10 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
data->timestamp = jiffies; data->timestamp = jiffies;
if (nfs4_setup_sequence(data->o_arg.server, if (nfs4_setup_sequence(data->o_arg.server,
&data->o_arg.seq_args, &data->o_arg.seq_args,
&data->o_res.seq_res, task)) &data->o_res.seq_res,
return; task) != 0)
nfs_release_seqid(data->o_arg.seqid);
else
rpc_call_start(task); rpc_call_start(task);
return; return;
unlock_no_action: unlock_no_action:
...@@ -2295,8 +2297,9 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) ...@@ -2295,8 +2297,9 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
if (nfs4_setup_sequence(NFS_SERVER(inode), if (nfs4_setup_sequence(NFS_SERVER(inode),
&calldata->arg.seq_args, &calldata->arg.seq_args,
&calldata->res.seq_res, &calldata->res.seq_res,
task)) task) != 0)
goto out; nfs_release_seqid(calldata->arg.seqid);
else
rpc_call_start(task); rpc_call_start(task);
out: out:
dprintk("%s: done!\n", __func__); dprintk("%s: done!\n", __func__);
...@@ -4544,8 +4547,10 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data) ...@@ -4544,8 +4547,10 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
calldata->timestamp = jiffies; calldata->timestamp = jiffies;
if (nfs4_setup_sequence(calldata->server, if (nfs4_setup_sequence(calldata->server,
&calldata->arg.seq_args, &calldata->arg.seq_args,
&calldata->res.seq_res, task)) &calldata->res.seq_res,
return; task) != 0)
nfs_release_seqid(calldata->arg.seqid);
else
rpc_call_start(task); rpc_call_start(task);
} }
...@@ -4691,7 +4696,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) ...@@ -4691,7 +4696,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
/* Do we need to do an open_to_lock_owner? */ /* Do we need to do an open_to_lock_owner? */
if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) {
if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0)
return; goto out_release_lock_seqid;
data->arg.open_stateid = &state->stateid; data->arg.open_stateid = &state->stateid;
data->arg.new_lock_owner = 1; data->arg.new_lock_owner = 1;
data->res.open_seqid = data->arg.open_seqid; data->res.open_seqid = data->arg.open_seqid;
...@@ -4700,10 +4705,15 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) ...@@ -4700,10 +4705,15 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
data->timestamp = jiffies; data->timestamp = jiffies;
if (nfs4_setup_sequence(data->server, if (nfs4_setup_sequence(data->server,
&data->arg.seq_args, &data->arg.seq_args,
&data->res.seq_res, task)) &data->res.seq_res,
return; task) == 0) {
rpc_call_start(task); rpc_call_start(task);
dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); return;
}
nfs_release_seqid(data->arg.open_seqid);
out_release_lock_seqid:
nfs_release_seqid(data->arg.lock_seqid);
dprintk("%s: done!, ret = %d\n", __func__, task->tk_status);
} }
static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata) static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
......
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