Trond Myklebust bf294b41ce SUNRPC: Close a race in __rpc_wait_for_completion_task()
Although they run as rpciod background tasks, under normal operation
(i.e. no SIGKILL), functions like nfs_sillyrename(), nfs4_proc_unlck()
and nfs4_do_close() want to be fully synchronous. This means that when we
exit, we want all references to the rpc_task to be gone, and we want
any dentry references etc. held by that task to be released.

For this reason these functions call __rpc_wait_for_completion_task(),
followed by rpc_put_task() in the expectation that the latter will be
releasing the last reference to the rpc_task, and thus ensuring that the
callback_ops->rpc_release() has been called synchronously.

This patch fixes a race which exists due to the fact that
rpciod calls rpc_complete_task() (in order to wake up the callers of
__rpc_wait_for_completion_task()) and then subsequently calls
rpc_put_task() without ensuring that these two steps are done atomically.

In order to avoid adding new spin locks, the patch uses the existing
waitqueue spin lock to order the rpc_task reference count releases between
the waiting process and rpciod.
The common case where nobody is waiting for completion is optimised for by
checking if the RPC_TASK_ASYNC flag is cleared and/or if the rpc_task
reference count is 1: in those cases we drop trying to grab the spin lock,
and immediately free up the rpc_task.

Those few processes that need to put the rpc_task from inside an
asynchronous context and that do not care about ordering are given a new
helper: rpc_put_task_async().

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2011-03-10 15:04:52 -05:00
..
2011-01-11 09:58:07 -06:00
2010-10-25 13:09:44 -07:00
2011-03-04 12:25:05 -08:00
2011-02-25 13:58:54 -08:00
2011-03-01 23:02:07 -08:00
2011-01-27 14:15:54 -08:00
2011-01-12 19:00:40 -08:00
2011-02-21 11:31:18 -08:00
2010-10-21 15:44:13 +02:00
2010-09-23 14:33:39 -07:00
2010-12-19 21:59:35 -08:00
2011-01-10 13:33:17 -08:00
2011-02-09 22:36:13 -08:00
2010-12-16 13:44:24 -08:00
2010-10-15 15:53:27 +02:00