aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-10-04 05:15:48 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:16 -0400
commit596bbe53eb3abfe7326b2f5e8afd614265c319c8 (patch)
tree31e1f008f8acb46d1a3a937538446a1447ed9c8f
parent7adae489fe794e3e203ff168595f635d0b845e59 (diff)
[PATCH] knfsd: Allow max size of NFSd payload to be configured
The max possible is the maximum RPC payload. The default depends on amount of total memory. The value can be set within reason as long as no nfsd threads are currently running. The value can also be ready, allowing the default to be determined after nfsd has started. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/nfsd/nfsctl.c33
-rw-r--r--fs/nfsd/nfssvc.c19
-rw-r--r--include/linux/nfsd/const.h4
-rw-r--r--include/linux/nfsd/nfsd.h1
4 files changed, 54 insertions, 3 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 6c2ddfed2cfc..39aed901514b 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -57,6 +57,7 @@ enum {
57 NFSD_Pool_Threads, 57 NFSD_Pool_Threads,
58 NFSD_Versions, 58 NFSD_Versions,
59 NFSD_Ports, 59 NFSD_Ports,
60 NFSD_MaxBlkSize,
60 /* 61 /*
61 * The below MUST come last. Otherwise we leave a hole in nfsd_files[] 62 * The below MUST come last. Otherwise we leave a hole in nfsd_files[]
62 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops 63 * 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);
82static ssize_t write_pool_threads(struct file *file, char *buf, size_t size); 83static ssize_t write_pool_threads(struct file *file, char *buf, size_t size);
83static ssize_t write_versions(struct file *file, char *buf, size_t size); 84static ssize_t write_versions(struct file *file, char *buf, size_t size);
84static ssize_t write_ports(struct file *file, char *buf, size_t size); 85static ssize_t write_ports(struct file *file, char *buf, size_t size);
86static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
85#ifdef CONFIG_NFSD_V4 87#ifdef CONFIG_NFSD_V4
86static ssize_t write_leasetime(struct file *file, char *buf, size_t size); 88static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
87static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); 89static 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) = {
100 [NFSD_Pool_Threads] = write_pool_threads, 102 [NFSD_Pool_Threads] = write_pool_threads,
101 [NFSD_Versions] = write_versions, 103 [NFSD_Versions] = write_versions,
102 [NFSD_Ports] = write_ports, 104 [NFSD_Ports] = write_ports,
105 [NFSD_MaxBlkSize] = write_maxblksize,
103#ifdef CONFIG_NFSD_V4 106#ifdef CONFIG_NFSD_V4
104 [NFSD_Leasetime] = write_leasetime, 107 [NFSD_Leasetime] = write_leasetime,
105 [NFSD_RecoveryDir] = write_recoverydir, 108 [NFSD_RecoveryDir] = write_recoverydir,
@@ -555,6 +558,35 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size)
555 return -EINVAL; 558 return -EINVAL;
556} 559}
557 560
561int nfsd_max_blksize;
562
563static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
564{
565 char *mesg = buf;
566 if (size > 0) {
567 int bsize;
568 int rv = get_int(&mesg, &bsize);
569 if (rv)
570 return rv;
571 /* force bsize into allowed range and
572 * required alignment.
573 */
574 if (bsize < 1024)
575 bsize = 1024;
576 if (bsize > NFSSVC_MAXBLKSIZE)
577 bsize = NFSSVC_MAXBLKSIZE;
578 bsize &= ~(1024-1);
579 lock_kernel();
580 if (nfsd_serv && nfsd_serv->sv_nrthreads) {
581 unlock_kernel();
582 return -EBUSY;
583 }
584 nfsd_max_blksize = bsize;
585 unlock_kernel();
586 }
587 return sprintf(buf, "%d\n", nfsd_max_blksize);
588}
589
558#ifdef CONFIG_NFSD_V4 590#ifdef CONFIG_NFSD_V4
559extern time_t nfs4_leasetime(void); 591extern time_t nfs4_leasetime(void);
560 592
@@ -620,6 +652,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
620 [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR}, 652 [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
621 [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, 653 [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
622 [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, 654 [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
655 [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
623#ifdef CONFIG_NFSD_V4 656#ifdef CONFIG_NFSD_V4
624 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, 657 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
625 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, 658 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 19443056ec30..0603baad5426 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -198,9 +198,26 @@ int nfsd_create_serv(void)
198 unlock_kernel(); 198 unlock_kernel();
199 return 0; 199 return 0;
200 } 200 }
201 if (nfsd_max_blksize == 0) {
202 /* choose a suitable default */
203 struct sysinfo i;
204 si_meminfo(&i);
205 /* Aim for 1/4096 of memory per thread
206 * This gives 1MB on 4Gig machines
207 * But only uses 32K on 128M machines.
208 * Bottom out at 8K on 32M and smaller.
209 * Of course, this is only a default.
210 */
211 nfsd_max_blksize = NFSSVC_MAXBLKSIZE;
212 i.totalram >>= 12;
213 while (nfsd_max_blksize > i.totalram &&
214 nfsd_max_blksize >= 8*1024*2)
215 nfsd_max_blksize /= 2;
216 }
201 217
202 atomic_set(&nfsd_busy, 0); 218 atomic_set(&nfsd_busy, 0);
203 nfsd_serv = svc_create_pooled(&nfsd_program, NFSD_BUFSIZE, 219 nfsd_serv = svc_create_pooled(&nfsd_program,
220 NFSD_BUFSIZE - NFSSVC_MAXBLKSIZE + nfsd_max_blksize,
204 nfsd_last_thread, 221 nfsd_last_thread,
205 nfsd, SIG_NOCLEAN, THIS_MODULE); 222 nfsd, SIG_NOCLEAN, THIS_MODULE);
206 if (nfsd_serv == NULL) 223 if (nfsd_serv == NULL)
diff --git a/include/linux/nfsd/const.h b/include/linux/nfsd/const.h
index adbddf007898..f478066f9cd5 100644
--- a/include/linux/nfsd/const.h
+++ b/include/linux/nfsd/const.h
@@ -21,9 +21,9 @@
21#define NFSSVC_MAXVERS 3 21#define NFSSVC_MAXVERS 3
22 22
23/* 23/*
24 * Maximum blocksize supported by daemon currently at 32K 24 * Maximum blocksizes supported by daemon under various circumstances.
25 */ 25 */
26#define NFSSVC_MAXBLKSIZE (32*1024) 26#define NFSSVC_MAXBLKSIZE RPCSVC_MAXPAYLOAD
27/* NFSv2 is limited by the protocol specification, see RFC 1094 */ 27/* NFSv2 is limited by the protocol specification, see RFC 1094 */
28#define NFSSVC_MAXBLKSIZE_V2 (8*1024) 28#define NFSSVC_MAXBLKSIZE_V2 (8*1024)
29 29
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index e1dbc86c270b..259841bb2f6c 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -145,6 +145,7 @@ int nfsd_vers(int vers, enum vers_op change);
145void nfsd_reset_versions(void); 145void nfsd_reset_versions(void);
146int nfsd_create_serv(void); 146int nfsd_create_serv(void);
147 147
148extern int nfsd_max_blksize;
148 149
149/* 150/*
150 * NFSv4 State 151 * NFSv4 State