Skip to content

Commit 2240a9e

Browse files
Trond MyklebustTrond Myklebust
authored andcommitted
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
1 parent 399f11c commit 2240a9e

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

fs/nfs/nfs4proc.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,9 +1571,11 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
15711571
data->timestamp = jiffies;
15721572
if (nfs4_setup_sequence(data->o_arg.server,
15731573
&data->o_arg.seq_args,
1574-
&data->o_res.seq_res, task))
1575-
return;
1576-
rpc_call_start(task);
1574+
&data->o_res.seq_res,
1575+
task) != 0)
1576+
nfs_release_seqid(data->o_arg.seqid);
1577+
else
1578+
rpc_call_start(task);
15771579
return;
15781580
unlock_no_action:
15791581
rcu_read_unlock();
@@ -2295,9 +2297,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
22952297
if (nfs4_setup_sequence(NFS_SERVER(inode),
22962298
&calldata->arg.seq_args,
22972299
&calldata->res.seq_res,
2298-
task))
2299-
goto out;
2300-
rpc_call_start(task);
2300+
task) != 0)
2301+
nfs_release_seqid(calldata->arg.seqid);
2302+
else
2303+
rpc_call_start(task);
23012304
out:
23022305
dprintk("%s: done!\n", __func__);
23032306
}
@@ -4544,9 +4547,11 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
45444547
calldata->timestamp = jiffies;
45454548
if (nfs4_setup_sequence(calldata->server,
45464549
&calldata->arg.seq_args,
4547-
&calldata->res.seq_res, task))
4548-
return;
4549-
rpc_call_start(task);
4550+
&calldata->res.seq_res,
4551+
task) != 0)
4552+
nfs_release_seqid(calldata->arg.seqid);
4553+
else
4554+
rpc_call_start(task);
45504555
}
45514556

45524557
static const struct rpc_call_ops nfs4_locku_ops = {
@@ -4691,7 +4696,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
46914696
/* Do we need to do an open_to_lock_owner? */
46924697
if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) {
46934698
if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0)
4694-
return;
4699+
goto out_release_lock_seqid;
46954700
data->arg.open_stateid = &state->stateid;
46964701
data->arg.new_lock_owner = 1;
46974702
data->res.open_seqid = data->arg.open_seqid;
@@ -4700,10 +4705,15 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
47004705
data->timestamp = jiffies;
47014706
if (nfs4_setup_sequence(data->server,
47024707
&data->arg.seq_args,
4703-
&data->res.seq_res, task))
4708+
&data->res.seq_res,
4709+
task) == 0) {
4710+
rpc_call_start(task);
47044711
return;
4705-
rpc_call_start(task);
4706-
dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
4712+
}
4713+
nfs_release_seqid(data->arg.open_seqid);
4714+
out_release_lock_seqid:
4715+
nfs_release_seqid(data->arg.lock_seqid);
4716+
dprintk("%s: done!, ret = %d\n", __func__, task->tk_status);
47074717
}
47084718

47094719
static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)

0 commit comments

Comments
 (0)