From: Trond Myklebust <trond.myklebust@primarydata.com>
Date: Fri, 28 Apr 2017 13:25:33 -0400
Subject: [PATCH] NFSv4: Allow multiple connections to NFSv4.x (x>0) servers
Patch-mainline: Submitted, linux-nfs@vger.kernel.org
References: fate#322786
If the user specifies the -onconn=<number> mount option, and the transport
protocol is TCP, then set up <number> connections to the server. The
connections will all go to the same IP address.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Acked-by: NeilBrown <neilb@suse.com>
---
fs/nfs/client.c | 2 ++
fs/nfs/internal.h | 1 +
fs/nfs/nfs4client.c | 10 ++++++++--
include/linux/nfs_fs_sb.h | 1 +
4 files changed, 12 insertions(+), 2 deletions(-)
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -180,6 +180,7 @@ struct nfs_client *nfs_alloc_client(cons
clp->cl_rpcclient = ERR_PTR(-EINVAL);
clp->cl_proto = cl_init->proto;
+ clp->cl_nconnect = cl_init->nconnect;
clp->cl_net = get_net(cl_init->net);
cred = rpc_lookup_machine_cred("*");
@@ -498,6 +499,7 @@ int nfs_create_rpc_client(struct nfs_cli
struct rpc_create_args args = {
.net = clp->cl_net,
.protocol = clp->cl_proto,
+ .nconnect = clp->cl_nconnect,
.address = (struct sockaddr *)&clp->cl_addr,
.addrsize = clp->cl_addrlen,
.timeout = cl_init->timeparms,
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -78,6 +78,7 @@ struct nfs_client_initdata {
struct nfs_subversion *nfs_mod;
int proto;
u32 minorversion;
+ unsigned int nconnect;
struct net *net;
const struct rpc_timeout *timeparms;
};
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -839,7 +839,8 @@ static int nfs4_set_client(struct nfs_se
const size_t addrlen,
const char *ip_addr,
int proto, const struct rpc_timeout *timeparms,
- u32 minorversion, struct net *net)
+ u32 minorversion, unsigned int nconnect,
+ struct net *net)
{
struct nfs_client_initdata cl_init = {
.hostname = hostname,
@@ -854,6 +855,8 @@ static int nfs4_set_client(struct nfs_se
};
struct nfs_client *clp;
+ if (minorversion > 0 && proto == XPRT_TRANSPORT_TCP)
+ cl_init.nconnect = nconnect;
if (server->flags & NFS_MOUNT_NORESVPORT)
set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
if (server->options & NFS_OPTION_MIGRATION)
@@ -1047,6 +1050,7 @@ static int nfs4_init_server(struct nfs_s
data->nfs_server.protocol,
&timeparms,
data->minorversion,
+ data->nfs_server.nconnect,
data->net);
if (error < 0)
return error;
@@ -1131,6 +1135,7 @@ struct nfs_server *nfs4_create_referral_
rpc_protocol(parent_server->client),
parent_server->client->cl_timeout,
parent_client->cl_mvops->minor_version,
+ parent_client->cl_nconnect,
parent_client->cl_net);
if (error < 0)
goto error;
@@ -1222,7 +1227,8 @@ int nfs4_update_server(struct nfs_server
nfs_server_remove_lists(server);
error = nfs4_set_client(server, hostname, sap, salen, buf,
clp->cl_proto, clnt->cl_timeout,
- clp->cl_minorversion, net);
+ clp->cl_minorversion,
+ clp->cl_nconnect, net);
if (error != 0) {
nfs_server_insert_lists(server);
return error;
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -55,6 +55,7 @@ struct nfs_client {
struct nfs_subversion * cl_nfs_mod; /* pointer to nfs version module */
u32 cl_minorversion;/* NFSv4 minorversion */
+ unsigned int cl_nconnect; /* Number of connections */
struct rpc_cred *cl_machine_cred;
#if IS_ENABLED(CONFIG_NFS_V4)