diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-01 17:00:56 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-02 15:36:38 -0500 |
commit | 2446ab6070861aba2dd9229463ffbc40016a9f33 (patch) | |
tree | 2e366c3236788936b9f4f58c0787ae01c265f4a4 /fs/nfs/nfs4proc.c | |
parent | a3ca5651cb5eebe2e56e510bbf5cd60abc301c9f (diff) |
SUNRPC: Use RCU to dereference the rpc_clnt.cl_xprt field
A migration event will replace the rpc_xprt used by an rpc_clnt. To
ensure this can be done safely, all references to cl_xprt must now use
a form of rcu_dereference().
Special care is taken with rpc_peeraddr2str(), which returns a pointer
to memory whose lifetime is the same as the rpc_xprt.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
[ cel: fix lockdep splats and layering violations ]
[ cel: forward ported to 3.4 ]
[ cel: remove rpc_max_reqs(), add rpc_net_ns() ]
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6c8e170e2e6b..671510cc14c0 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -3833,6 +3833,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, | |||
3833 | *p = htonl((u32)clp->cl_boot_time.tv_nsec); | 3833 | *p = htonl((u32)clp->cl_boot_time.tv_nsec); |
3834 | 3834 | ||
3835 | for(;;) { | 3835 | for(;;) { |
3836 | rcu_read_lock(); | ||
3836 | setclientid.sc_name_len = scnprintf(setclientid.sc_name, | 3837 | setclientid.sc_name_len = scnprintf(setclientid.sc_name, |
3837 | sizeof(setclientid.sc_name), "%s/%s %s %s %u", | 3838 | sizeof(setclientid.sc_name), "%s/%s %s %s %u", |
3838 | clp->cl_ipaddr, | 3839 | clp->cl_ipaddr, |
@@ -3849,6 +3850,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, | |||
3849 | setclientid.sc_uaddr_len = scnprintf(setclientid.sc_uaddr, | 3850 | setclientid.sc_uaddr_len = scnprintf(setclientid.sc_uaddr, |
3850 | sizeof(setclientid.sc_uaddr), "%s.%u.%u", | 3851 | sizeof(setclientid.sc_uaddr), "%s.%u.%u", |
3851 | clp->cl_ipaddr, port >> 8, port & 255); | 3852 | clp->cl_ipaddr, port >> 8, port & 255); |
3853 | rcu_read_unlock(); | ||
3852 | 3854 | ||
3853 | status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); | 3855 | status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); |
3854 | if (status != -NFS4ERR_CLID_INUSE) | 3856 | if (status != -NFS4ERR_CLID_INUSE) |
@@ -5244,11 +5246,16 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp) | |||
5244 | 5246 | ||
5245 | void nfs4_destroy_session(struct nfs4_session *session) | 5247 | void nfs4_destroy_session(struct nfs4_session *session) |
5246 | { | 5248 | { |
5249 | struct rpc_xprt *xprt; | ||
5250 | |||
5247 | nfs4_proc_destroy_session(session); | 5251 | nfs4_proc_destroy_session(session); |
5252 | |||
5253 | rcu_read_lock(); | ||
5254 | xprt = rcu_dereference(session->clp->cl_rpcclient->cl_xprt); | ||
5255 | rcu_read_unlock(); | ||
5248 | dprintk("%s Destroy backchannel for xprt %p\n", | 5256 | dprintk("%s Destroy backchannel for xprt %p\n", |
5249 | __func__, session->clp->cl_rpcclient->cl_xprt); | 5257 | __func__, xprt); |
5250 | xprt_destroy_backchannel(session->clp->cl_rpcclient->cl_xprt, | 5258 | xprt_destroy_backchannel(xprt, NFS41_BC_MIN_CALLBACKS); |
5251 | NFS41_BC_MIN_CALLBACKS); | ||
5252 | nfs4_destroy_slot_tables(session); | 5259 | nfs4_destroy_slot_tables(session); |
5253 | kfree(session); | 5260 | kfree(session); |
5254 | } | 5261 | } |