From 413ceadd50d61d293ae56e09ce52a421e14e1026 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 4 Oct 2006 02:15:48 -0700 Subject: [PATCH] --- yaml --- r: 38367 b: refs/heads/master c: 596bbe53eb3abfe7326b2f5e8afd614265c319c8 h: refs/heads/master i: 38365: d2175e78b5e9be29b6782ea87e92d523ea5ba6cd 38363: b5189404a6b63b0a79d130e35b45d745d9be1f5c 38359: 14dbc4b03f3e82e64b0a8916a67eb912cc8c6cec 38351: 53c5f1f92f051628d91161bcc3f019c0c16a42da 38335: 0a931bbf2dadc7aa4fb9b20e19030ac320cdf789 v: v3 --- [refs] | 2 +- trunk/fs/nfsd/nfsctl.c | 33 ++++++++++++++++++++++++++++++++ trunk/fs/nfsd/nfssvc.c | 19 +++++++++++++++++- trunk/include/linux/nfsd/const.h | 4 ++-- trunk/include/linux/nfsd/nfsd.h | 1 + 5 files changed, 55 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 11df7e63fb30..5b6e3b20b89d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7adae489fe794e3e203ff168595f635d0b845e59 +refs/heads/master: 596bbe53eb3abfe7326b2f5e8afd614265c319c8 diff --git a/trunk/fs/nfsd/nfsctl.c b/trunk/fs/nfsd/nfsctl.c index 6c2ddfed2cfc..39aed901514b 100644 --- a/trunk/fs/nfsd/nfsctl.c +++ b/trunk/fs/nfsd/nfsctl.c @@ -57,6 +57,7 @@ enum { NFSD_Pool_Threads, NFSD_Versions, NFSD_Ports, + NFSD_MaxBlkSize, /* * The below MUST come last. Otherwise we leave a hole in nfsd_files[] * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops @@ -82,6 +83,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size); 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); #ifdef CONFIG_NFSD_V4 static ssize_t write_leasetime(struct file *file, char *buf, size_t size); static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); @@ -100,6 +102,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { [NFSD_Pool_Threads] = write_pool_threads, [NFSD_Versions] = write_versions, [NFSD_Ports] = write_ports, + [NFSD_MaxBlkSize] = write_maxblksize, #ifdef CONFIG_NFSD_V4 [NFSD_Leasetime] = write_leasetime, [NFSD_RecoveryDir] = write_recoverydir, @@ -555,6 +558,35 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size) return -EINVAL; } +int nfsd_max_blksize; + +static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) +{ + char *mesg = buf; + if (size > 0) { + int bsize; + int rv = get_int(&mesg, &bsize); + if (rv) + return rv; + /* force bsize into allowed range and + * required alignment. + */ + if (bsize < 1024) + bsize = 1024; + if (bsize > NFSSVC_MAXBLKSIZE) + bsize = NFSSVC_MAXBLKSIZE; + bsize &= ~(1024-1); + lock_kernel(); + if (nfsd_serv && nfsd_serv->sv_nrthreads) { + unlock_kernel(); + return -EBUSY; + } + nfsd_max_blksize = bsize; + unlock_kernel(); + } + return sprintf(buf, "%d\n", nfsd_max_blksize); +} + #ifdef CONFIG_NFSD_V4 extern time_t nfs4_leasetime(void); @@ -620,6 +652,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR}, [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}, #ifdef CONFIG_NFSD_V4 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, diff --git a/trunk/fs/nfsd/nfssvc.c b/trunk/fs/nfsd/nfssvc.c index 19443056ec30..0603baad5426 100644 --- a/trunk/fs/nfsd/nfssvc.c +++ b/trunk/fs/nfsd/nfssvc.c @@ -198,9 +198,26 @@ int nfsd_create_serv(void) unlock_kernel(); return 0; } + if (nfsd_max_blksize == 0) { + /* choose a suitable default */ + struct sysinfo i; + si_meminfo(&i); + /* Aim for 1/4096 of memory per thread + * This gives 1MB on 4Gig machines + * But only uses 32K on 128M machines. + * Bottom out at 8K on 32M and smaller. + * Of course, this is only a default. + */ + nfsd_max_blksize = NFSSVC_MAXBLKSIZE; + i.totalram >>= 12; + while (nfsd_max_blksize > i.totalram && + nfsd_max_blksize >= 8*1024*2) + nfsd_max_blksize /= 2; + } atomic_set(&nfsd_busy, 0); - nfsd_serv = svc_create_pooled(&nfsd_program, NFSD_BUFSIZE, + nfsd_serv = svc_create_pooled(&nfsd_program, + NFSD_BUFSIZE - NFSSVC_MAXBLKSIZE + nfsd_max_blksize, nfsd_last_thread, nfsd, SIG_NOCLEAN, THIS_MODULE); if (nfsd_serv == NULL) diff --git a/trunk/include/linux/nfsd/const.h b/trunk/include/linux/nfsd/const.h index adbddf007898..f478066f9cd5 100644 --- a/trunk/include/linux/nfsd/const.h +++ b/trunk/include/linux/nfsd/const.h @@ -21,9 +21,9 @@ #define NFSSVC_MAXVERS 3 /* - * Maximum blocksize supported by daemon currently at 32K + * Maximum blocksizes supported by daemon under various circumstances. */ -#define NFSSVC_MAXBLKSIZE (32*1024) +#define NFSSVC_MAXBLKSIZE RPCSVC_MAXPAYLOAD /* NFSv2 is limited by the protocol specification, see RFC 1094 */ #define NFSSVC_MAXBLKSIZE_V2 (8*1024) diff --git a/trunk/include/linux/nfsd/nfsd.h b/trunk/include/linux/nfsd/nfsd.h index e1dbc86c270b..259841bb2f6c 100644 --- a/trunk/include/linux/nfsd/nfsd.h +++ b/trunk/include/linux/nfsd/nfsd.h @@ -145,6 +145,7 @@ int nfsd_vers(int vers, enum vers_op change); void nfsd_reset_versions(void); int nfsd_create_serv(void); +extern int nfsd_max_blksize; /* * NFSv4 State