NFSv4: Allow multiple connections to NFSv4.x (x>0) servers
authorTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 27 Apr 2017 15:13:40 +0000 (11:13 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Sat, 6 Jul 2019 18:54:50 +0000 (14:54 -0400)
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>
fs/nfs/client.c
fs/nfs/internal.h
fs/nfs/nfs4client.c
include/linux/nfs_fs_sb.h

index d7e4f0848e28c77371769d9a4a45165e3770705e..fa6953e56a71dcec90de1c096e1b1a11cbdf365c 100644 (file)
@@ -175,6 +175,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
        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);
 
        clp->cl_principal = "*";
@@ -493,6 +494,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
        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,
index bba09dace5d64e8adcbe2f6f8f76bb9ac2031744..4a49dc1495c585917829024818586b225256486c 100644 (file)
@@ -82,6 +82,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;
        const struct cred *cred;
index 81b9b6d7927ac22c7b500c85c2f4a6cb7a4a61b6..5c244c440658b048ddae36243a7e05090566f35e 100644 (file)
@@ -859,7 +859,8 @@ static int nfs4_set_client(struct nfs_server *server,
                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,
@@ -875,6 +876,8 @@ static int nfs4_set_client(struct nfs_server *server,
        };
        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)
@@ -1074,6 +1077,7 @@ static int nfs4_init_server(struct nfs_server *server,
                        data->nfs_server.protocol,
                        &timeparms,
                        data->minorversion,
+                       data->nfs_server.nconnect,
                        data->net);
        if (error < 0)
                return error;
@@ -1163,6 +1167,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
                                XPRT_TRANSPORT_RDMA,
                                parent_server->client->cl_timeout,
                                parent_client->cl_mvops->minor_version,
+                               parent_client->cl_nconnect,
                                parent_client->cl_net);
        if (!error)
                goto init_server;
@@ -1176,6 +1181,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
                                XPRT_TRANSPORT_TCP,
                                parent_server->client->cl_timeout,
                                parent_client->cl_mvops->minor_version,
+                               parent_client->cl_nconnect,
                                parent_client->cl_net);
        if (error < 0)
                goto error;
@@ -1271,7 +1277,8 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname,
        set_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
        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);
        clear_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
        if (error != 0) {
                nfs_server_insert_lists(server);
index 1e78032a174bafc366ca4b9344cf298a69ddd70e..a87fe854f0083229a19167e65993111a79482084 100644 (file)
@@ -58,6 +58,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 */
        const char *            cl_principal;  /* used for machine cred */
 
 #if IS_ENABLED(CONFIG_NFS_V4)