Commit 7e134205 authored by Olga Kornievskaia's avatar Olga Kornievskaia Committed by Anna Schumaker

NFSv4 introduce max_connect mount options

This option will control up to how many xprts can the client
establish to the server with a distinct address (that means
nconnect connections are not counted towards this new limit).
This patch is setting up nfs structures to keeep track of the
max_connect limit (does not enforce it).

The default value is kept at 1 so that no current mounts that
don't want any additional connections would be effected. The
maximum value is set at 16.

Mounts to DS are not limited to default value of 1 but instead
set to the maximum default value of 16 (NFS_MAX_TRANSPORTS).
Signed-off-by: default avatarOlga Kornievskaia <kolga@netapp.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent df205d0a
...@@ -179,6 +179,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) ...@@ -179,6 +179,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
clp->cl_proto = cl_init->proto; clp->cl_proto = cl_init->proto;
clp->cl_nconnect = cl_init->nconnect; clp->cl_nconnect = cl_init->nconnect;
clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1;
clp->cl_net = get_net(cl_init->net); clp->cl_net = get_net(cl_init->net);
clp->cl_principal = "*"; clp->cl_principal = "*";
......
...@@ -60,6 +60,7 @@ enum nfs_param { ...@@ -60,6 +60,7 @@ enum nfs_param {
Opt_mountvers, Opt_mountvers,
Opt_namelen, Opt_namelen,
Opt_nconnect, Opt_nconnect,
Opt_max_connect,
Opt_port, Opt_port,
Opt_posix, Opt_posix,
Opt_proto, Opt_proto,
...@@ -158,6 +159,7 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = { ...@@ -158,6 +159,7 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = {
fsparam_u32 ("mountvers", Opt_mountvers), fsparam_u32 ("mountvers", Opt_mountvers),
fsparam_u32 ("namlen", Opt_namelen), fsparam_u32 ("namlen", Opt_namelen),
fsparam_u32 ("nconnect", Opt_nconnect), fsparam_u32 ("nconnect", Opt_nconnect),
fsparam_u32 ("max_connect", Opt_max_connect),
fsparam_string("nfsvers", Opt_vers), fsparam_string("nfsvers", Opt_vers),
fsparam_u32 ("port", Opt_port), fsparam_u32 ("port", Opt_port),
fsparam_flag_no("posix", Opt_posix), fsparam_flag_no("posix", Opt_posix),
...@@ -770,6 +772,11 @@ static int nfs_fs_context_parse_param(struct fs_context *fc, ...@@ -770,6 +772,11 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
goto out_of_bounds; goto out_of_bounds;
ctx->nfs_server.nconnect = result.uint_32; ctx->nfs_server.nconnect = result.uint_32;
break; break;
case Opt_max_connect:
if (result.uint_32 < 1 || result.uint_32 > NFS_MAX_TRANSPORTS)
goto out_of_bounds;
ctx->nfs_server.max_connect = result.uint_32;
break;
case Opt_lookupcache: case Opt_lookupcache:
switch (result.uint_32) { switch (result.uint_32) {
case Opt_lookupcache_all: case Opt_lookupcache_all:
......
...@@ -67,6 +67,7 @@ struct nfs_client_initdata { ...@@ -67,6 +67,7 @@ struct nfs_client_initdata {
int proto; int proto;
u32 minorversion; u32 minorversion;
unsigned int nconnect; unsigned int nconnect;
unsigned int max_connect;
struct net *net; struct net *net;
const struct rpc_timeout *timeparms; const struct rpc_timeout *timeparms;
const struct cred *cred; const struct cred *cred;
...@@ -121,6 +122,7 @@ struct nfs_fs_context { ...@@ -121,6 +122,7 @@ struct nfs_fs_context {
int port; int port;
unsigned short protocol; unsigned short protocol;
unsigned short nconnect; unsigned short nconnect;
unsigned short max_connect;
unsigned short export_path_len; unsigned short export_path_len;
} nfs_server; } nfs_server;
......
...@@ -865,6 +865,7 @@ static int nfs4_set_client(struct nfs_server *server, ...@@ -865,6 +865,7 @@ static int nfs4_set_client(struct nfs_server *server,
const char *ip_addr, const char *ip_addr,
int proto, const struct rpc_timeout *timeparms, int proto, const struct rpc_timeout *timeparms,
u32 minorversion, unsigned int nconnect, u32 minorversion, unsigned int nconnect,
unsigned int max_connect,
struct net *net) struct net *net)
{ {
struct nfs_client_initdata cl_init = { struct nfs_client_initdata cl_init = {
...@@ -883,6 +884,8 @@ static int nfs4_set_client(struct nfs_server *server, ...@@ -883,6 +884,8 @@ static int nfs4_set_client(struct nfs_server *server,
if (minorversion == 0) if (minorversion == 0)
__set_bit(NFS_CS_REUSEPORT, &cl_init.init_flags); __set_bit(NFS_CS_REUSEPORT, &cl_init.init_flags);
else
cl_init.max_connect = max_connect;
if (proto == XPRT_TRANSPORT_TCP) if (proto == XPRT_TRANSPORT_TCP)
cl_init.nconnect = nconnect; cl_init.nconnect = nconnect;
...@@ -952,8 +955,10 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv, ...@@ -952,8 +955,10 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
cl_init.hostname = buf; cl_init.hostname = buf;
if (mds_clp->cl_nconnect > 1 && ds_proto == XPRT_TRANSPORT_TCP) if (mds_clp->cl_nconnect > 1 && ds_proto == XPRT_TRANSPORT_TCP) {
cl_init.nconnect = mds_clp->cl_nconnect; cl_init.nconnect = mds_clp->cl_nconnect;
cl_init.max_connect = NFS_MAX_TRANSPORTS;
}
if (mds_srv->flags & NFS_MOUNT_NORESVPORT) if (mds_srv->flags & NFS_MOUNT_NORESVPORT)
__set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
...@@ -1122,6 +1127,7 @@ static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc) ...@@ -1122,6 +1127,7 @@ static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc)
&timeparms, &timeparms,
ctx->minorversion, ctx->minorversion,
ctx->nfs_server.nconnect, ctx->nfs_server.nconnect,
ctx->nfs_server.max_connect,
fc->net_ns); fc->net_ns);
if (error < 0) if (error < 0)
return error; return error;
...@@ -1211,6 +1217,7 @@ struct nfs_server *nfs4_create_referral_server(struct fs_context *fc) ...@@ -1211,6 +1217,7 @@ struct nfs_server *nfs4_create_referral_server(struct fs_context *fc)
parent_server->client->cl_timeout, parent_server->client->cl_timeout,
parent_client->cl_mvops->minor_version, parent_client->cl_mvops->minor_version,
parent_client->cl_nconnect, parent_client->cl_nconnect,
parent_client->cl_max_connect,
parent_client->cl_net); parent_client->cl_net);
if (!error) if (!error)
goto init_server; goto init_server;
...@@ -1226,6 +1233,7 @@ struct nfs_server *nfs4_create_referral_server(struct fs_context *fc) ...@@ -1226,6 +1233,7 @@ struct nfs_server *nfs4_create_referral_server(struct fs_context *fc)
parent_server->client->cl_timeout, parent_server->client->cl_timeout,
parent_client->cl_mvops->minor_version, parent_client->cl_mvops->minor_version,
parent_client->cl_nconnect, parent_client->cl_nconnect,
parent_client->cl_max_connect,
parent_client->cl_net); parent_client->cl_net);
if (error < 0) if (error < 0)
goto error; goto error;
...@@ -1323,7 +1331,7 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname, ...@@ -1323,7 +1331,7 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname,
error = nfs4_set_client(server, hostname, sap, salen, buf, error = nfs4_set_client(server, hostname, sap, salen, buf,
clp->cl_proto, clnt->cl_timeout, clp->cl_proto, clnt->cl_timeout,
clp->cl_minorversion, clp->cl_minorversion,
clp->cl_nconnect, net); clp->cl_nconnect, clp->cl_max_connect, net);
clear_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status); clear_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
if (error != 0) { if (error != 0) {
nfs_server_insert_lists(server); nfs_server_insert_lists(server);
......
...@@ -480,6 +480,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, ...@@ -480,6 +480,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
if (clp->cl_nconnect > 0) if (clp->cl_nconnect > 0)
seq_printf(m, ",nconnect=%u", clp->cl_nconnect); seq_printf(m, ",nconnect=%u", clp->cl_nconnect);
if (version == 4) { if (version == 4) {
if (clp->cl_max_connect > 1)
seq_printf(m, ",max_connect=%u", clp->cl_max_connect);
if (nfss->port != NFS_PORT) if (nfss->port != NFS_PORT)
seq_printf(m, ",port=%u", nfss->port); seq_printf(m, ",port=%u", nfss->port);
} else } else
......
...@@ -40,6 +40,11 @@ ...@@ -40,6 +40,11 @@
#include <linux/mempool.h> #include <linux/mempool.h>
/*
* These are the default for number of transports to different server IPs
*/
#define NFS_MAX_TRANSPORTS 16
/* /*
* These are the default flags for swap requests * These are the default flags for swap requests
*/ */
......
...@@ -62,6 +62,7 @@ struct nfs_client { ...@@ -62,6 +62,7 @@ struct nfs_client {
u32 cl_minorversion;/* NFSv4 minorversion */ u32 cl_minorversion;/* NFSv4 minorversion */
unsigned int cl_nconnect; /* Number of connections */ unsigned int cl_nconnect; /* Number of connections */
unsigned int cl_max_connect; /* max number of xprts allowed */
const char * cl_principal; /* used for machine cred */ const char * cl_principal; /* used for machine cred */
#if IS_ENABLED(CONFIG_NFS_V4) #if IS_ENABLED(CONFIG_NFS_V4)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment