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/client.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/client.c')
-rw-r--r-- | fs/nfs/client.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 1506adf4d4ed..d038dc5916e5 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -1284,16 +1284,18 @@ static int nfs4_init_callback(struct nfs_client *clp) | |||
1284 | int error; | 1284 | int error; |
1285 | 1285 | ||
1286 | if (clp->rpc_ops->version == 4) { | 1286 | if (clp->rpc_ops->version == 4) { |
1287 | struct rpc_xprt *xprt; | ||
1288 | |||
1289 | xprt = rcu_dereference_raw(clp->cl_rpcclient->cl_xprt); | ||
1290 | |||
1287 | if (nfs4_has_session(clp)) { | 1291 | if (nfs4_has_session(clp)) { |
1288 | error = xprt_setup_backchannel( | 1292 | error = xprt_setup_backchannel(xprt, |
1289 | clp->cl_rpcclient->cl_xprt, | ||
1290 | NFS41_BC_MIN_CALLBACKS); | 1293 | NFS41_BC_MIN_CALLBACKS); |
1291 | if (error < 0) | 1294 | if (error < 0) |
1292 | return error; | 1295 | return error; |
1293 | } | 1296 | } |
1294 | 1297 | ||
1295 | error = nfs_callback_up(clp->cl_mvops->minor_version, | 1298 | error = nfs_callback_up(clp->cl_mvops->minor_version, xprt); |
1296 | clp->cl_rpcclient->cl_xprt); | ||
1297 | if (error < 0) { | 1299 | if (error < 0) { |
1298 | dprintk("%s: failed to start callback. Error = %d\n", | 1300 | dprintk("%s: failed to start callback. Error = %d\n", |
1299 | __func__, error); | 1301 | __func__, error); |
@@ -1678,7 +1680,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, | |||
1678 | data->addrlen, | 1680 | data->addrlen, |
1679 | parent_client->cl_ipaddr, | 1681 | parent_client->cl_ipaddr, |
1680 | data->authflavor, | 1682 | data->authflavor, |
1681 | parent_server->client->cl_xprt->prot, | 1683 | rpc_protocol(parent_server->client), |
1682 | parent_server->client->cl_timeout, | 1684 | parent_server->client->cl_timeout, |
1683 | parent_client->cl_mvops->minor_version, | 1685 | parent_client->cl_mvops->minor_version, |
1684 | parent_client->net); | 1686 | parent_client->net); |
@@ -1905,12 +1907,14 @@ static int nfs_server_list_show(struct seq_file *m, void *v) | |||
1905 | if (clp->cl_cons_state != NFS_CS_READY) | 1907 | if (clp->cl_cons_state != NFS_CS_READY) |
1906 | return 0; | 1908 | return 0; |
1907 | 1909 | ||
1910 | rcu_read_lock(); | ||
1908 | seq_printf(m, "v%u %s %s %3d %s\n", | 1911 | seq_printf(m, "v%u %s %s %3d %s\n", |
1909 | clp->rpc_ops->version, | 1912 | clp->rpc_ops->version, |
1910 | rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR), | 1913 | rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR), |
1911 | rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT), | 1914 | rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT), |
1912 | atomic_read(&clp->cl_count), | 1915 | atomic_read(&clp->cl_count), |
1913 | clp->cl_hostname); | 1916 | clp->cl_hostname); |
1917 | rcu_read_unlock(); | ||
1914 | 1918 | ||
1915 | return 0; | 1919 | return 0; |
1916 | } | 1920 | } |
@@ -1993,6 +1997,7 @@ static int nfs_volume_list_show(struct seq_file *m, void *v) | |||
1993 | (unsigned long long) server->fsid.major, | 1997 | (unsigned long long) server->fsid.major, |
1994 | (unsigned long long) server->fsid.minor); | 1998 | (unsigned long long) server->fsid.minor); |
1995 | 1999 | ||
2000 | rcu_read_lock(); | ||
1996 | seq_printf(m, "v%u %s %s %-7s %-17s %s\n", | 2001 | seq_printf(m, "v%u %s %s %-7s %-17s %s\n", |
1997 | clp->rpc_ops->version, | 2002 | clp->rpc_ops->version, |
1998 | rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR), | 2003 | rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR), |
@@ -2000,6 +2005,7 @@ static int nfs_volume_list_show(struct seq_file *m, void *v) | |||
2000 | dev, | 2005 | dev, |
2001 | fsid, | 2006 | fsid, |
2002 | nfs_server_fscache_state(server)); | 2007 | nfs_server_fscache_state(server)); |
2008 | rcu_read_unlock(); | ||
2003 | 2009 | ||
2004 | return 0; | 2010 | return 0; |
2005 | } | 2011 | } |