[PATCH] SUNRPC: fix race in in-kernel RPC portmapper client
When submitting a request to a fast portmapper (such as the local rpcbind daemon), the request can complete before the parent task is even queued up on xprt->binding. Fix this by queuing before submitting the rpcbind request. Test plan: Connectathon locking test with UDP. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Родитель
b87c0adfea
Коммит
71bdcf8056
|
@ -101,11 +101,13 @@ void rpc_getport(struct rpc_task *task)
|
||||||
/* Autobind on cloned rpc clients is discouraged */
|
/* Autobind on cloned rpc clients is discouraged */
|
||||||
BUG_ON(clnt->cl_parent != clnt);
|
BUG_ON(clnt->cl_parent != clnt);
|
||||||
|
|
||||||
if (xprt_test_and_set_binding(xprt)) {
|
/* Put self on queue before sending rpcbind request, in case
|
||||||
task->tk_status = -EACCES; /* tell caller to check again */
|
* pmap_getport_done completes before we return from rpc_run_task */
|
||||||
rpc_sleep_on(&xprt->binding, task, NULL, NULL);
|
rpc_sleep_on(&xprt->binding, task, NULL, NULL);
|
||||||
return;
|
|
||||||
}
|
status = -EACCES; /* tell caller to check again */
|
||||||
|
if (xprt_test_and_set_binding(xprt))
|
||||||
|
goto bailout_nofree;
|
||||||
|
|
||||||
/* Someone else may have bound if we slept */
|
/* Someone else may have bound if we slept */
|
||||||
status = 0;
|
status = 0;
|
||||||
|
@ -134,8 +136,6 @@ void rpc_getport(struct rpc_task *task)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
rpc_release_task(child);
|
rpc_release_task(child);
|
||||||
|
|
||||||
rpc_sleep_on(&xprt->binding, task, NULL, NULL);
|
|
||||||
|
|
||||||
task->tk_xprt->stat.bind_count++;
|
task->tk_xprt->stat.bind_count++;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче