aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/client.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-03-01 17:00:56 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-03-02 15:36:38 -0500
commit2446ab6070861aba2dd9229463ffbc40016a9f33 (patch)
tree2e366c3236788936b9f4f58c0787ae01c265f4a4 /fs/nfs/client.c
parenta3ca5651cb5eebe2e56e510bbf5cd60abc301c9f (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.c16
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}