Hi, all:
When reviewing the code of nfs4_run_open_task, if the rpc_task start
failed, the opendata reference held from kref_get would not be
released even return to upper callers.
I'm wonder that does there leak the opendata?
static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
{
...
struct rpc_task_setup task_setup_data = {
...
. callback_ops = &nfs4_open_ops,
. callback_data = data,
...
};
int status;
nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1);
kref_get(&data->kref);
...
task = rpc_run_task(&task_setup_data);
if (IS_ERR(task))
return PTR_ERR(task);
status = rpc_wait_for_completion_task(task);
if (status != 0) {
data->cancelled = true;
smp_wmb();
} else
status = data->rpc_status;
rpc_put_task(task);
return status;
}
Best regards,
Lin Yi
On Wed, 2020-04-22 at 10:50 +0800, 亿一 wrote:
> Hi, all:
> When reviewing the code of nfs4_run_open_task, if the rpc_task start
> failed, the opendata reference held from kref_get would not be
> released even return to upper callers.
> I'm wonder that does there leak the opendata?
>
> static int nfs4_run_open_task(struct nfs4_opendata *data, int
> isrecover)
> {
> ...
> struct rpc_task_setup task_setup_data = {
> ...
> . callback_ops = &nfs4_open_ops,
> . callback_data = data,
> ...
> };
> int status;
>
> nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1);
> kref_get(&data->kref);
> ...
>
> task = rpc_run_task(&task_setup_data);
> if (IS_ERR(task))
> return PTR_ERR(task);
> status = rpc_wait_for_completion_task(task);
> if (status != 0) {
> data->cancelled = true;
> smp_wmb();
> } else
> status = data->rpc_status;
> rpc_put_task(task);
>
> return status;
> }
>
> Best regards,
>
Please see commit 62b2417e84ba (
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=62b2417e84ba
)
Thanks
Trond
--
Trond Myklebust
Linux NFS client maintainer, Hammerspace
[email protected]