mirror of
https://github.com/torvalds/linux.git
synced 2024-12-30 14:52:05 +00:00
nfsd: add a new /proc/fs/nfsd/max_connections file
Currently, the maximum number of connections that nfsd will allow is based on the number of threads spawned. While this is fine for a default, there really isn't a clear relationship between the two. The number of threads corresponds to the number of concurrent requests that we want to allow the server to process at any given time. The connection limit corresponds to the maximum number of clients that we want to allow the server to handle. These are two entirely different quantities. Break the dependency on increasing threads in order to allow for more connections, by adding a new per-net parameter that can be set to a non-zero value. The default is still to base it on the number of threads, so there should be no behavior change for anyone who doesn't use it. Cc: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Jeff Layton <jlayton@primarydata.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
0f3a24b43b
commit
5b8db00bae
@ -102,6 +102,12 @@ struct nfsd_net {
|
||||
*/
|
||||
struct timeval nfssvc_boot;
|
||||
|
||||
/*
|
||||
* Max number of connections this nfsd container will allow. Defaults
|
||||
* to '0' which is means that it bases this on the number of threads.
|
||||
*/
|
||||
unsigned int max_connections;
|
||||
|
||||
struct svc_serv *nfsd_serv;
|
||||
};
|
||||
|
||||
|
@ -39,6 +39,7 @@ enum {
|
||||
NFSD_Versions,
|
||||
NFSD_Ports,
|
||||
NFSD_MaxBlkSize,
|
||||
NFSD_MaxConnections,
|
||||
NFSD_SupportedEnctypes,
|
||||
/*
|
||||
* The below MUST come last. Otherwise we leave a hole in nfsd_files[]
|
||||
@ -62,6 +63,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size);
|
||||
static ssize_t write_versions(struct file *file, char *buf, size_t size);
|
||||
static ssize_t write_ports(struct file *file, char *buf, size_t size);
|
||||
static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
|
||||
static ssize_t write_maxconn(struct file *file, char *buf, size_t size);
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
|
||||
static ssize_t write_gracetime(struct file *file, char *buf, size_t size);
|
||||
@ -77,6 +79,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
|
||||
[NFSD_Versions] = write_versions,
|
||||
[NFSD_Ports] = write_ports,
|
||||
[NFSD_MaxBlkSize] = write_maxblksize,
|
||||
[NFSD_MaxConnections] = write_maxconn,
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
[NFSD_Leasetime] = write_leasetime,
|
||||
[NFSD_Gracetime] = write_gracetime,
|
||||
@ -886,6 +889,44 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
|
||||
nfsd_max_blksize);
|
||||
}
|
||||
|
||||
/**
|
||||
* write_maxconn - Set or report the current max number of connections
|
||||
*
|
||||
* Input:
|
||||
* buf: ignored
|
||||
* size: zero
|
||||
* OR
|
||||
*
|
||||
* Input:
|
||||
* buf: C string containing an unsigned
|
||||
* integer value representing the new
|
||||
* number of max connections
|
||||
* size: non-zero length of C string in @buf
|
||||
* Output:
|
||||
* On success: passed-in buffer filled with '\n'-terminated C string
|
||||
* containing numeric value of max_connections setting
|
||||
* for this net namespace;
|
||||
* return code is the size in bytes of the string
|
||||
* On error: return code is zero or a negative errno value
|
||||
*/
|
||||
static ssize_t write_maxconn(struct file *file, char *buf, size_t size)
|
||||
{
|
||||
char *mesg = buf;
|
||||
struct net *net = file->f_dentry->d_sb->s_fs_info;
|
||||
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
|
||||
unsigned int maxconn = nn->max_connections;
|
||||
|
||||
if (size > 0) {
|
||||
int rv = get_uint(&mesg, &maxconn);
|
||||
|
||||
if (rv)
|
||||
return rv;
|
||||
nn->max_connections = maxconn;
|
||||
}
|
||||
|
||||
return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%u\n", maxconn);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
|
||||
time_t *time, struct nfsd_net *nn)
|
||||
@ -1061,6 +1102,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
|
||||
[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
|
||||
[NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
|
||||
[NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
|
||||
[NFSD_MaxConnections] = {"max_connections", &transaction_ops, S_IWUSR|S_IRUGO},
|
||||
#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
|
||||
[NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO},
|
||||
#endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */
|
||||
|
@ -405,6 +405,7 @@ int nfsd_create_serv(struct net *net)
|
||||
if (nn->nfsd_serv == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
nn->nfsd_serv->sv_maxconn = nn->max_connections;
|
||||
error = svc_bind(nn->nfsd_serv, net);
|
||||
if (error < 0) {
|
||||
svc_destroy(nn->nfsd_serv);
|
||||
@ -563,6 +564,7 @@ nfsd(void *vrqstp)
|
||||
struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
|
||||
struct svc_xprt *perm_sock = list_entry(rqstp->rq_server->sv_permsocks.next, typeof(struct svc_xprt), xpt_list);
|
||||
struct net *net = perm_sock->xpt_net;
|
||||
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
|
||||
int err;
|
||||
|
||||
/* Lock module and set up kernel thread */
|
||||
@ -596,6 +598,9 @@ nfsd(void *vrqstp)
|
||||
* The main request loop
|
||||
*/
|
||||
for (;;) {
|
||||
/* Update sv_maxconn if it has changed */
|
||||
rqstp->rq_server->sv_maxconn = nn->max_connections;
|
||||
|
||||
/*
|
||||
* Find a socket with data available and call its
|
||||
* recvfrom routine.
|
||||
|
Loading…
Reference in New Issue
Block a user