mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 02:09:42 +00:00
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: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: stable@vger.kernel.org
This commit is contained in:
parent
399f11c3d8
commit
2240a9e2d0
1 changed files with 23 additions and 13 deletions
|
@ -1571,9 +1571,11 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
|
|||
data->timestamp = jiffies;
|
||||
if (nfs4_setup_sequence(data->o_arg.server,
|
||||
&data->o_arg.seq_args,
|
||||
&data->o_res.seq_res, task))
|
||||
return;
|
||||
rpc_call_start(task);
|
||||
&data->o_res.seq_res,
|
||||
task) != 0)
|
||||
nfs_release_seqid(data->o_arg.seqid);
|
||||
else
|
||||
rpc_call_start(task);
|
||||
return;
|
||||
unlock_no_action:
|
||||
rcu_read_unlock();
|
||||
|
@ -2295,9 +2297,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
|
|||
if (nfs4_setup_sequence(NFS_SERVER(inode),
|
||||
&calldata->arg.seq_args,
|
||||
&calldata->res.seq_res,
|
||||
task))
|
||||
goto out;
|
||||
rpc_call_start(task);
|
||||
task) != 0)
|
||||
nfs_release_seqid(calldata->arg.seqid);
|
||||
else
|
||||
rpc_call_start(task);
|
||||
out:
|
||||
dprintk("%s: done!\n", __func__);
|
||||
}
|
||||
|
@ -4544,9 +4547,11 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
|
|||
calldata->timestamp = jiffies;
|
||||
if (nfs4_setup_sequence(calldata->server,
|
||||
&calldata->arg.seq_args,
|
||||
&calldata->res.seq_res, task))
|
||||
return;
|
||||
rpc_call_start(task);
|
||||
&calldata->res.seq_res,
|
||||
task) != 0)
|
||||
nfs_release_seqid(calldata->arg.seqid);
|
||||
else
|
||||
rpc_call_start(task);
|
||||
}
|
||||
|
||||
static const struct rpc_call_ops nfs4_locku_ops = {
|
||||
|
@ -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? */
|
||||
if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) {
|
||||
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.new_lock_owner = 1;
|
||||
data->res.open_seqid = data->arg.open_seqid;
|
||||
|
@ -4700,10 +4705,15 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
|
|||
data->timestamp = jiffies;
|
||||
if (nfs4_setup_sequence(data->server,
|
||||
&data->arg.seq_args,
|
||||
&data->res.seq_res, task))
|
||||
&data->res.seq_res,
|
||||
task) == 0) {
|
||||
rpc_call_start(task);
|
||||
return;
|
||||
rpc_call_start(task);
|
||||
dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
|
||||
}
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue