[PATCH 1/6] NFS: pre-clone the rpc_clnt

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Bryan Schumaker <bjschuma@xxxxxxxxxx>

A later patch will need an rpc_clnt with the correct authflavor to find
properties of a submount.  It's easiest to set up the rpc_clnt once and
pass it to nfs_clone_server() instead of cloning the clnt multiple times.

Signed-off-by: Bryan Schumaker <bjschuma@xxxxxxxxxx>
---
 fs/nfs/client.c        |   50 ++++++++++++++++++++++++++++--------------------
 fs/nfs/internal.h      |    3 ++-
 fs/nfs/namespace.c     |    8 +++++++-
 fs/nfs/nfs4namespace.c |    2 +-
 fs/nfs/super.c         |    4 ++--
 5 files changed, 41 insertions(+), 26 deletions(-)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index da7b5e4..1faa091 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -772,36 +772,45 @@ static inline void nfs_init_server_aclclient(struct nfs_server *server)
 /*
  * Create a general RPC client
  */
-static int nfs_init_server_rpcclient(struct nfs_server *server,
+static void nfs_init_server_rpcclient(struct nfs_server *server,
+				      struct rpc_clnt *client,
+				      const struct rpc_timeout *timeo)
+{
+	memcpy(&client->cl_timeout_default, timeo, sizeof(client->cl_timeout_default));
+
+	client->cl_timeout = &client->cl_timeout_default;
+	client->cl_softrtry = 0;
+	if (server->flags & NFS_MOUNT_SOFT)
+		client->cl_softrtry = 1;
+
+	server->client = client;
+}
+
+static int nfs_alloc_server_rpcclient(struct nfs_server *server,
 		const struct rpc_timeout *timeo,
 		rpc_authflavor_t pseudoflavour)
 {
+	struct rpc_clnt *client;
 	struct nfs_client *clp = server->nfs_client;
 
-	server->client = rpc_clone_client(clp->cl_rpcclient);
-	if (IS_ERR(server->client)) {
+	client = rpc_clone_client(clp->cl_rpcclient);
+	if (IS_ERR(client)) {
 		dprintk("%s: couldn't create rpc_client!\n", __func__);
 		return PTR_ERR(server->client);
 	}
 
-	memcpy(&server->client->cl_timeout_default,
-			timeo,
-			sizeof(server->client->cl_timeout_default));
-	server->client->cl_timeout = &server->client->cl_timeout_default;
-
 	if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) {
 		struct rpc_auth *auth;
 
-		auth = rpcauth_create(pseudoflavour, server->client);
+		auth = rpcauth_create(pseudoflavour, client);
 		if (IS_ERR(auth)) {
 			dprintk("%s: couldn't create credcache!\n", __func__);
+			rpc_shutdown_client(client);
 			return PTR_ERR(auth);
 		}
 	}
-	server->client->cl_softrtry = 0;
-	if (server->flags & NFS_MOUNT_SOFT)
-		server->client->cl_softrtry = 1;
 
+	nfs_init_server_rpcclient(server, client, timeo);
 	return 0;
 }
 
@@ -899,7 +908,7 @@ static int nfs_init_server(struct nfs_server *server,
 
 	server->port = data->nfs_server.port;
 
-	error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
+	error = nfs_alloc_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
 	if (error < 0)
 		goto error;
 
@@ -1626,7 +1635,7 @@ static int nfs4_init_server(struct nfs_server *server,
 
 	server->port = data->nfs_server.port;
 
-	error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
+	error = nfs_alloc_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
 
 error:
 	/* Done */
@@ -1697,7 +1706,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 				data->addr,
 				data->addrlen,
 				parent_client->cl_ipaddr,
-				data->authflavor,
+				data->client->cl_auth->au_flavor,
 				rpc_protocol(parent_server->client),
 				parent_server->client->cl_timeout,
 				parent_client->cl_mvops->minor_version,
@@ -1705,7 +1714,8 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 	if (error < 0)
 		goto error;
 
-	error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor);
+	error = nfs_alloc_server_rpcclient(server, parent_server->client->cl_timeout,
+					   data->client->cl_auth->au_flavor);
 	if (error < 0)
 		goto error;
 
@@ -1728,6 +1738,7 @@ error:
  * Clone an NFS2, NFS3 or NFS4 server record
  */
 struct nfs_server *nfs_clone_server(struct nfs_server *source,
+				    struct rpc_clnt *client,
 				    struct nfs_fh *fh,
 				    struct nfs_fattr *fattr)
 {
@@ -1756,11 +1767,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
 
 	server->fsid = fattr->fsid;
 
-	error = nfs_init_server_rpcclient(server,
-			source->client->cl_timeout,
-			source->client->cl_auth->au_flavor);
-	if (error < 0)
-		goto out_free_server;
+	nfs_init_server_rpcclient(server, client, source->client->cl_timeout);
 	if (!IS_ERR(source->client_acl))
 		nfs_init_server_aclclient(server);
 
@@ -1788,6 +1795,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
 	return server;
 
 out_free_server:
+	server->client = NULL;
 	nfs_free_fattr(fattr_fsinfo);
 	nfs_free_server(server);
 	dprintk("<-- nfs_clone_server() = error %d\n", error);
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 2476dc6..b499cd0 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -59,13 +59,13 @@ static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr)
 struct nfs_clone_mount {
 	const struct super_block *sb;
 	const struct dentry *dentry;
+	struct rpc_clnt *client;
 	struct nfs_fh *fh;
 	struct nfs_fattr *fattr;
 	char *hostname;
 	char *mnt_path;
 	struct sockaddr *addr;
 	size_t addrlen;
-	rpc_authflavor_t authflavor;
 };
 
 /*
@@ -164,6 +164,7 @@ extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
 						      struct nfs_fh *);
 extern void nfs_free_server(struct nfs_server *server);
 extern struct nfs_server *nfs_clone_server(struct nfs_server *,
+					   struct rpc_clnt *,
 					   struct nfs_fh *,
 					   struct nfs_fattr *);
 extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 1807866..3e40460 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -346,7 +346,6 @@ static struct vfsmount *nfs_do_submount(struct dentry *dentry,
 		.dentry = dentry,
 		.fh = fh,
 		.fattr = fattr,
-		.authflavor = authflavor,
 	};
 	struct vfsmount *mnt = ERR_PTR(-ENOMEM);
 	char *page = (char *) __get_free_page(GFP_USER);
@@ -363,7 +362,14 @@ static struct vfsmount *nfs_do_submount(struct dentry *dentry,
 	mnt = (struct vfsmount *)devname;
 	if (IS_ERR(devname))
 		goto free_page;
+
+	mountdata.client = rpc_clone_client(NFS_SB(dentry->d_sb)->client);
+	if (IS_ERR(mountdata.client))
+		goto free_page;
+
 	mnt = nfs_do_clone_mount(NFS_SB(dentry->d_sb), devname, &mountdata);
+	if (IS_ERR(mnt))
+		rpc_shutdown_client(mountdata.client);
 free_page:
 	free_page((unsigned long)page);
 out:
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 9c8eca3..28a4771 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -174,7 +174,7 @@ static struct vfsmount *nfs_follow_referral(struct dentry *dentry,
 	struct nfs_clone_mount mountdata = {
 		.sb = dentry->d_sb,
 		.dentry = dentry,
-		.authflavor = NFS_SB(dentry->d_sb)->client->cl_auth->au_flavor,
+		.client = NFS_SB(dentry->d_sb)->client,
 	};
 	char *page = NULL, *page2 = NULL;
 	int loc, error;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 37412f7..ce9c0c1 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2428,7 +2428,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
 	dprintk("--> nfs_xdev_mount()\n");
 
 	/* create a new volume representation */
-	server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
+	server = nfs_clone_server(NFS_SB(data->sb), data->client, data->fh, data->fattr);
 	if (IS_ERR(server)) {
 		error = PTR_ERR(server);
 		goto out_err_noserver;
@@ -2951,7 +2951,7 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
 	dprintk("--> nfs4_xdev_mount()\n");
 
 	/* create a new volume representation */
-	server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
+	server = nfs_clone_server(NFS_SB(data->sb), data->client, data->fh, data->fattr);
 	if (IS_ERR(server)) {
 		error = PTR_ERR(server);
 		goto out_err_noserver;
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux