diff mbox

[Version,2,8/8] NFS test and add multi-addrs for session trunking

Message ID 1456336587-17374-9-git-send-email-andros@netapp.com (mailing list archive)
State New, archived
Headers show

Commit Message

Andy Adamson Feb. 24, 2016, 5:56 p.m. UTC
From: Andy Adamson <andros@netapp.com>

Signed-off-by: Andy Adamson <andros@netapp.com>
---
 fs/nfs/internal.h          |  2 ++
 fs/nfs/nfs4client.c        | 39 +++++++++++++++++++++++++++++++++++++++
 fs/nfs/nfs4proc.c          | 36 ++++++++++++++++++++++++++++++++++++
 net/sunrpc/xprtmultipath.c |  3 +++
 4 files changed, 80 insertions(+)
diff mbox

Patch

diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index e11056c..9322869 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -214,6 +214,8 @@  extern struct nfs_client *nfs3_set_ds_client(struct nfs_client *mds_clp,
 			const struct sockaddr *ds_addr, int ds_addrlen,
 			int ds_proto, unsigned int ds_timeo,
 			unsigned int ds_retrans, rpc_authflavor_t au_flavor);
+extern void nfs_try_multiaddr(struct nfs_parsed_mount_data *mnt,
+			struct rpc_clnt *clnt);
 #ifdef CONFIG_PROC_FS
 extern int __init nfs_fs_proc_init(void);
 extern void nfs_fs_proc_exit(void);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 1606a14..1ec745a 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -1012,6 +1012,43 @@  out:
 	return error;
 }
 
+/**
+ * Add rpc_xprts to an existing RPC client
+ */
+void nfs4_try_multiaddr(struct nfs_parsed_mount_data *mnt,
+			struct nfs_client *clp)
+{
+	struct multi_addr *multip = mnt->multiaddrs;
+	struct nfs4_add_xprt_data xprtdata = {
+		.clp = clp,
+	};
+	int i;
+
+	dprintk("NFS:   Try adding %u multi addrs\n", mnt->num_multi);
+
+	if (mnt->num_multi == 0)
+		return;
+
+	xprtdata.cred = nfs4_get_clid_cred(clp);
+
+	for (i = 0; i < mnt->num_multi; i++) {
+		struct xprt_create xprt_args = {
+			.ident = XPRT_TRANSPORT_TCP,
+			.net = mnt->net,
+			.dstaddr = (struct sockaddr *)&multip->addr,
+			.addrlen = multip->addrlen,
+			.servername = multip->hostname,
+		};
+		/* Add this address as an alias */
+		rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
+				  nfs4_test_session_trunk_and_add_xprt,
+				  &xprtdata);
+		multip++;
+	}
+	if (xprtdata.cred)
+		put_rpccred(xprtdata.cred);
+}
+
 /*
  * Create a version 4 volume record
  */
@@ -1068,6 +1105,8 @@  static int nfs4_init_server(struct nfs_server *server,
 	error = nfs_init_server_rpcclient(server, &timeparms,
 					  data->selected_flavor);
 
+	if (!error)
+		nfs4_try_multiaddr(data, server->nfs_client);
 error:
 	/* Done */
 	dprintk("<-- nfs4_init_server() = %d\n", error);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index aaaa5a4..4a8a7a3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -7206,6 +7206,42 @@  int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
 	return _nfs4_proc_exchange_id(clp, cred, SP4_NONE, NULL);
 }
 
+/**
+ * nfs4_test_session_trunk_and_add_xprt - Test for session trunking with a
+ * synchronous exchange_id call, and add a new transport to the rpc_clnt
+ *
+ * @clnt: struct rpc_clnt to get new transport
+ * @xps:  the rpc_xprt_switch to hold the new transport
+ * @xprt: the rpc_xprt to test
+ * @data: call data for _nfs4_proc_exchange_id.
+ *
+ */
+int nfs4_test_session_trunk_and_add_xprt(struct rpc_clnt *clnt,
+					struct rpc_xprt_switch *xps,
+					struct rpc_xprt *xprt,
+					void *data)
+{
+	struct nfs4_add_xprt_data *xdata = (struct nfs4_add_xprt_data *)data;
+	u32 sp4_how;
+	int status;
+
+	sp4_how = (xdata->clp->cl_sp4_flags == 0 ? SP4_NONE : SP4_MACH_CRED);
+	dprintk("--> %s sp4_how %d\n", __func__, sp4_how);
+
+	/* Ensure these stick around for the rpc call */
+	xps = xprt_switch_get(xps);
+	xprt = xprt_get(xprt);
+
+	/* Sync call */
+	status = _nfs4_proc_exchange_id(xdata->clp, xdata->cred, sp4_how, xprt);
+
+	xprt_put(xprt);
+	xprt_switch_put(xps);
+
+	dprintk("<-- %s status %d\n", __func__, status);
+	return status;
+}
+
 static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
 		struct rpc_cred *cred)
 {
diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c
index e7fd769..360f64c 100644
--- a/net/sunrpc/xprtmultipath.c
+++ b/net/sunrpc/xprtmultipath.c
@@ -53,6 +53,7 @@  void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps,
 		xprt_switch_add_xprt_locked(xps, xprt);
 	spin_unlock(&xps->xps_lock);
 }
+EXPORT_SYMBOL_GPL(rpc_xprt_switch_add_xprt);
 
 static void xprt_switch_remove_xprt_locked(struct rpc_xprt_switch *xps,
 		struct rpc_xprt *xprt)
@@ -145,6 +146,7 @@  struct rpc_xprt_switch *xprt_switch_get(struct rpc_xprt_switch *xps)
 		return xps;
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(xprt_switch_get);
 
 /**
  * xprt_switch_put - Release a reference to a rpc_xprt_switch
@@ -157,6 +159,7 @@  void xprt_switch_put(struct rpc_xprt_switch *xps)
 	if (xps != NULL)
 		kref_put(&xps->xps_kref, xprt_switch_free);
 }
+EXPORT_SYMBOL_GPL(xprt_switch_put);
 
 /**
  * rpc_xprt_switch_set_roundrobin - Set a round-robin policy on rpc_xprt_switch