kernel-ark/net/sunrpc
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
..
auth_gss Merge branch 'for-2.6.38' of git://linux-nfs.org/~bfields/linux 2011-01-14 13:17:26 -08:00
xprtrdma sunrpc/xprtrdma: clean up workqueue usage 2010-10-21 10:11:45 -04:00
addr.c
auth_generic.c sunrpc: fix up rpcauth_remove_module section mismatch 2010-09-29 12:27:37 -04:00
auth_null.c SUNRPC: Move the bound cred to struct rpc_rqst 2010-08-04 08:54:09 -04:00
auth_unix.c SUNRPC: Move the bound cred to struct rpc_rqst 2010-08-04 08:54:09 -04:00
auth.c SUNRPC: New xdr_streams XDR decoder API 2010-12-16 12:37:25 -05:00
backchannel_rqst.c
bc_svc.c SUNRPC fix bc_send print 2011-01-06 14:46:23 -05:00
cache.c svcrpc: ensure cache_check caller sees updated entry 2011-01-04 16:49:25 -05:00
clnt.c net/sunrpc/clnt.c: Convert sprintf_symbol to %ps 2010-12-21 11:51:26 -05:00
Kconfig nfsd4: remove spkm3 2010-10-01 18:09:55 -04:00
Makefile
netns.h sunrpc: Make the ip_map_cache be per-net 2010-09-27 10:16:12 -04:00
rpc_pipe.c Merge branch 'nfs-for-2.6.38' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6 2011-01-11 15:11:56 -08:00
rpcb_clnt.c SUNRPC: New xdr_streams XDR decoder API 2010-12-16 12:37:25 -05:00
sched.c SUNRPC: Close a race in __rpc_wait_for_completion_task() 2011-03-10 15:04:52 -05:00
socklib.c
stats.c SUNRPC: Simplify rpc_alloc_iostats by removing pointless local variable 2010-11-16 11:58:51 -05:00
sunrpc_syms.c sunrpc: Make the ip_map_cache be per-net 2010-09-27 10:16:12 -04:00
sunrpc.h
svc_xprt.c rpc: keep backchannel xprt as long as server connection 2011-01-11 15:04:10 -05:00
svc.c Merge branch 'for-2.6.38' of git://linux-nfs.org/~bfields/linux 2011-01-14 13:17:26 -08:00
svcauth_unix.c SUNRPC: Remove more code when NFSD_DEPRECATED is not configured 2011-01-04 16:48:02 -05:00
svcauth.c net: sunrpc: kill unused macros 2010-12-17 15:48:21 -05:00
svcsock.c NFS do not find client in NFSv4 pg_authenticate 2011-01-25 15:26:51 -05:00
sysctl.c
timer.c
xdr.c NFS: Don't use vm_map_ram() in readdir 2011-01-10 14:45:01 -05:00
xprt.c rpc: allow xprt_class->setup to return a preexisting xprt 2011-01-11 15:04:10 -05:00
xprtsock.c Merge branch 'for-2.6.38' of git://linux-nfs.org/~bfields/linux 2011-01-14 13:17:26 -08:00