Fedora Core 2 - 1.492
[linux-2.6.git] / kernel / sysctl.c
1 /*
2  * sysctl.c: General linux system control interface
3  *
4  * Begun 24 March 1995, Stephen Tweedie
5  * Added /proc support, Dec 1995
6  * Added bdflush entry and intvec min/max checking, 2/23/96, Tom Dyas.
7  * Added hooks for /proc/sys/net (minor, minor patch), 96/4/1, Mike Shaver.
8  * Added kernel/java-{interpreter,appletviewer}, 96/5/10, Mike Shaver.
9  * Dynamic registration fixes, Stephen Tweedie.
10  * Added kswapd-interval, ctrl-alt-del, printk stuff, 1/8/97, Chris Horn.
11  * Made sysctl support optional via CONFIG_SYSCTL, 1/10/97, Chris
12  *  Horn.
13  * Added proc_doulongvec_ms_jiffies_minmax, 09/08/99, Carlos H. Bauer.
14  * Added proc_doulongvec_minmax, 09/08/99, Carlos H. Bauer.
15  * Changed linked lists to use list.h instead of lists.h, 02/24/00, Bill
16  *  Wendling.
17  * The list_for_each() macro wasn't appropriate for the sysctl loop.
18  *  Removed it and replaced it with older style, 03/23/00, Bill Wendling
19  */
20
21 #include <linux/config.h>
22 #include <linux/module.h>
23 #include <linux/mm.h>
24 #include <linux/swap.h>
25 #include <linux/slab.h>
26 #include <linux/sysctl.h>
27 #include <linux/proc_fs.h>
28 #include <linux/ctype.h>
29 #include <linux/utsname.h>
30 #include <linux/capability.h>
31 #include <linux/smp_lock.h>
32 #include <linux/init.h>
33 #include <linux/kernel.h>
34 #include <linux/sysrq.h>
35 #include <linux/highuid.h>
36 #include <linux/writeback.h>
37 #include <linux/hugetlb.h>
38 #include <linux/security.h>
39 #include <linux/initrd.h>
40 #include <linux/times.h>
41 #include <linux/limits.h>
42 #include <linux/dcache.h>
43
44 #include <asm/uaccess.h>
45
46 #ifdef CONFIG_ROOT_NFS
47 #include <linux/nfs_fs.h>
48 #endif
49
50 #if defined(CONFIG_SYSCTL)
51
52 /* External variables not in a header file. */
53 extern int panic_timeout;
54 extern int C_A_D;
55 extern int sysctl_overcommit_memory;
56 extern int sysctl_overcommit_ratio;
57 extern int max_threads;
58 extern int sysrq_enabled;
59 extern int core_uses_pid;
60 extern char core_pattern[];
61 extern int cad_pid;
62 extern int pid_max;
63 extern int sysctl_lower_zone_protection;
64 extern int min_free_kbytes;
65 extern int printk_ratelimit_jiffies;
66 extern int printk_ratelimit_burst;
67
68 extern unsigned int vdso_enabled;
69
70 int exec_shield = 1;
71 int exec_shield_randomize = 1;
72
73 static int __init setup_exec_shield(char *str)
74 {
75         get_option (&str, &exec_shield);
76
77         return 1;
78 }
79
80 __setup("exec-shield=", setup_exec_shield);
81
82 static int __init setup_exec_shield_randomize(char *str)
83 {
84         get_option (&str, &exec_shield_randomize);
85
86         return 1;
87 }
88
89 __setup("exec-shield-randomize=", setup_exec_shield_randomize);
90
91 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
92 static int maxolduid = 65535;
93 static int minolduid;
94
95 static int ngroups_max = NGROUPS_MAX;
96
97 #ifdef CONFIG_KMOD
98 extern char modprobe_path[];
99 #endif
100 #ifdef CONFIG_HOTPLUG
101 extern char hotplug_path[];
102 #endif
103 #ifdef CONFIG_CHR_DEV_SG
104 extern int sg_big_buff;
105 #endif
106 #ifdef CONFIG_SYSVIPC
107 extern size_t shm_ctlmax;
108 extern size_t shm_ctlall;
109 extern int shm_ctlmni;
110 extern int msg_ctlmax;
111 extern int msg_ctlmnb;
112 extern int msg_ctlmni;
113 extern int sem_ctls[];
114 #endif
115
116 #ifdef __sparc__
117 extern char reboot_command [];
118 extern int stop_a_enabled;
119 extern int scons_pwroff;
120 #endif
121
122 #ifdef __hppa__
123 extern int pwrsw_enabled;
124 extern int unaligned_enabled;
125 #endif
126
127 #ifdef CONFIG_ARCH_S390
128 #ifdef CONFIG_MATHEMU
129 extern int sysctl_ieee_emulation_warnings;
130 #endif
131 extern int sysctl_userprocess_debug;
132 #endif
133
134 extern int sysctl_hz_timer;
135
136 #if defined(CONFIG_PPC32) && defined(CONFIG_6xx)
137 extern unsigned long powersave_nap;
138 int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
139                   void *buffer, size_t *lenp);
140 #endif
141
142 #ifdef CONFIG_BSD_PROCESS_ACCT
143 extern int acct_parm[];
144 #endif
145
146 static int parse_table(int __user *, int, void __user *, size_t __user *, void __user *, size_t,
147                        ctl_table *, void **);
148 static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
149                   void __user *buffer, size_t *lenp);
150
151 static ctl_table root_table[];
152 static struct ctl_table_header root_table_header =
153         { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
154
155 static ctl_table kern_table[];
156 static ctl_table vm_table[];
157 #ifdef CONFIG_NET
158 extern ctl_table net_table[];
159 #endif
160 static ctl_table proc_table[];
161 static ctl_table fs_table[];
162 static ctl_table debug_table[];
163 static ctl_table dev_table[];
164 extern ctl_table random_table[];
165 #ifdef CONFIG_UNIX98_PTYS
166 extern ctl_table pty_table[];
167 #endif
168
169 /* /proc declarations: */
170
171 #ifdef CONFIG_PROC_FS
172
173 static ssize_t proc_readsys(struct file *, char __user *, size_t, loff_t *);
174 static ssize_t proc_writesys(struct file *, const char __user *, size_t, loff_t *);
175 static int proc_opensys(struct inode *, struct file *);
176
177 struct file_operations proc_sys_file_operations = {
178         .open           = proc_opensys,
179         .read           = proc_readsys,
180         .write          = proc_writesys,
181 };
182
183 extern struct proc_dir_entry *proc_sys_root;
184
185 static void register_proc_table(ctl_table *, struct proc_dir_entry *);
186 static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
187 #endif
188
189 /* The default sysctl tables: */
190
191 static ctl_table root_table[] = {
192         {
193                 .ctl_name       = CTL_KERN,
194                 .procname       = "kernel",
195                 .mode           = 0555,
196                 .child          = kern_table,
197         },
198         {
199                 .ctl_name       = CTL_VM,
200                 .procname       = "vm",
201                 .mode           = 0555,
202                 .child          = vm_table,
203         },
204 #ifdef CONFIG_NET
205         {
206                 .ctl_name       = CTL_NET,
207                 .procname       = "net",
208                 .mode           = 0555,
209                 .child          = net_table,
210         },
211 #endif
212         {
213                 .ctl_name       = CTL_PROC,
214                 .procname       = "proc",
215                 .mode           = 0555,
216                 .child          = proc_table,
217         },
218         {
219                 .ctl_name       = CTL_FS,
220                 .procname       = "fs",
221                 .mode           = 0555,
222                 .child          = fs_table,
223         },
224         {
225                 .ctl_name       = CTL_DEBUG,
226                 .procname       = "debug",
227                 .mode           = 0555,
228                 .child          = debug_table,
229         },
230         {
231                 .ctl_name       = CTL_DEV,
232                 .procname       = "dev",
233                 .mode           = 0555,
234                 .child          = dev_table,
235         },
236         { .ctl_name = 0 }
237 };
238
239 static ctl_table kern_table[] = {
240         {
241                 .ctl_name       = KERN_OSTYPE,
242                 .procname       = "ostype",
243                 .data           = system_utsname.sysname,
244                 .maxlen         = sizeof(system_utsname.sysname),
245                 .mode           = 0444,
246                 .proc_handler   = &proc_doutsstring,
247                 .strategy       = &sysctl_string,
248         },
249         {
250                 .ctl_name       = KERN_OSRELEASE,
251                 .procname       = "osrelease",
252                 .data           = system_utsname.release,
253                 .maxlen         = sizeof(system_utsname.release),
254                 .mode           = 0444,
255                 .proc_handler   = &proc_doutsstring,
256                 .strategy       = &sysctl_string,
257         },
258         {
259                 .ctl_name       = KERN_VERSION,
260                 .procname       = "version",
261                 .data           = system_utsname.version,
262                 .maxlen         = sizeof(system_utsname.version),
263                 .mode           = 0444,
264                 .proc_handler   = &proc_doutsstring,
265                 .strategy       = &sysctl_string,
266         },
267         {
268                 .ctl_name       = KERN_NODENAME,
269                 .procname       = "hostname",
270                 .data           = system_utsname.nodename,
271                 .maxlen         = sizeof(system_utsname.nodename),
272                 .mode           = 0644,
273                 .proc_handler   = &proc_doutsstring,
274                 .strategy       = &sysctl_string,
275         },
276         {
277                 .ctl_name       = KERN_DOMAINNAME,
278                 .procname       = "domainname",
279                 .data           = system_utsname.domainname,
280                 .maxlen         = sizeof(system_utsname.domainname),
281                 .mode           = 0644,
282                 .proc_handler   = &proc_doutsstring,
283                 .strategy       = &sysctl_string,
284         },
285         {
286                 .ctl_name       = KERN_PANIC,
287                 .procname       = "panic",
288                 .data           = &panic_timeout,
289                 .maxlen         = sizeof(int),
290                 .mode           = 0644,
291                 .proc_handler   = &proc_dointvec,
292         },
293         {
294                 .ctl_name       = KERN_PANIC,
295                 .procname       = "exec-shield",
296                 .data           = &exec_shield,
297                 .maxlen         = sizeof(int),
298                 .mode           = 0644,
299                 .proc_handler   = &proc_dointvec,
300         },
301         {
302                 .ctl_name       = KERN_PANIC,
303                 .procname       = "exec-shield-randomize",
304                 .data           = &exec_shield_randomize,
305                 .maxlen         = sizeof(int),
306                 .mode           = 0644,
307                 .proc_handler   = &proc_dointvec,
308         },
309         {
310                 .ctl_name       = KERN_PANIC,
311                 .procname       = "print-fatal-signals",
312                 .data           = &print_fatal_signals,
313                 .maxlen         = sizeof(int),
314                 .mode           = 0644,
315                 .proc_handler   = &proc_dointvec,
316         },
317 #if __i386__
318         {
319                 .ctl_name       = KERN_PANIC,
320                 .procname       = "vdso",
321                 .data           = &vdso_enabled,
322                 .maxlen         = sizeof(int),
323                 .mode           = 0644,
324                 .proc_handler   = &proc_dointvec,
325         },
326 #endif
327         {
328                 .ctl_name       = KERN_CORE_USES_PID,
329                 .procname       = "core_uses_pid",
330                 .data           = &core_uses_pid,
331                 .maxlen         = sizeof(int),
332                 .mode           = 0644,
333                 .proc_handler   = &proc_dointvec,
334         },
335         {
336                 .ctl_name       = KERN_CORE_PATTERN,
337                 .procname       = "core_pattern",
338                 .data           = core_pattern,
339                 .maxlen         = 64,
340                 .mode           = 0644,
341                 .proc_handler   = &proc_dostring,
342                 .strategy       = &sysctl_string,
343         },
344         {
345                 .ctl_name       = KERN_TAINTED,
346                 .procname       = "tainted",
347                 .data           = &tainted,
348                 .maxlen         = sizeof(int),
349                 .mode           = 0644,
350                 .proc_handler   = &proc_dointvec,
351         },
352         {
353                 .ctl_name       = KERN_CAP_BSET,
354                 .procname       = "cap-bound",
355                 .data           = &cap_bset,
356                 .maxlen         = sizeof(kernel_cap_t),
357                 .mode           = 0600,
358                 .proc_handler   = &proc_dointvec_bset,
359         },
360 #ifdef CONFIG_BLK_DEV_INITRD
361         {
362                 .ctl_name       = KERN_REALROOTDEV,
363                 .procname       = "real-root-dev",
364                 .data           = &real_root_dev,
365                 .maxlen         = sizeof(int),
366                 .mode           = 0644,
367                 .proc_handler   = &proc_dointvec,
368         },
369 #endif
370 #ifdef __sparc__
371         {
372                 .ctl_name       = KERN_SPARC_REBOOT,
373                 .procname       = "reboot-cmd",
374                 .data           = reboot_command,
375                 .maxlen         = 256,
376                 .mode           = 0644,
377                 .proc_handler   = &proc_dostring,
378                 .strategy       = &sysctl_string,
379         },
380         {
381                 .ctl_name       = KERN_SPARC_STOP_A,
382                 .procname       = "stop-a",
383                 .data           = &stop_a_enabled,
384                 .maxlen         = sizeof (int),
385                 .mode           = 0644,
386                 .proc_handler   = &proc_dointvec,
387         },
388         {
389                 .ctl_name       = KERN_SPARC_SCONS_PWROFF,
390                 .procname       = "scons-poweroff",
391                 .data           = &scons_pwroff,
392                 .maxlen         = sizeof (int),
393                 .mode           = 0644,
394                 .proc_handler   = &proc_dointvec,
395         },
396 #endif
397 #ifdef __hppa__
398         {
399                 .ctl_name       = KERN_HPPA_PWRSW,
400                 .procname       = "soft-power",
401                 .data           = &pwrsw_enabled,
402                 .maxlen         = sizeof (int),
403                 .mode           = 0644,
404                 .proc_handler   = &proc_dointvec,
405         },
406         {
407                 .ctl_name       = KERN_HPPA_UNALIGNED,
408                 .procname       = "unaligned-trap",
409                 .data           = &unaligned_enabled,
410                 .maxlen         = sizeof (int),
411                 .mode           = 0644,
412                 .proc_handler   = &proc_dointvec,
413         },
414 #endif
415 #if defined(CONFIG_PPC32) && defined(CONFIG_6xx)
416         {
417                 .ctl_name       = KERN_PPC_POWERSAVE_NAP,
418                 .procname       = "powersave-nap",
419                 .data           = &powersave_nap,
420                 .maxlen         = sizeof(int),
421                 .mode           = 0644,
422                 .proc_handler   = &proc_dointvec,
423         },
424         {
425                 .ctl_name       = KERN_PPC_L2CR,
426                 .procname       = "l2cr",
427                 .mode           = 0644,
428                 .proc_handler   = &proc_dol2crvec,
429         },
430 #endif
431         {
432                 .ctl_name       = KERN_CTLALTDEL,
433                 .procname       = "ctrl-alt-del",
434                 .data           = &C_A_D,
435                 .maxlen         = sizeof(int),
436                 .mode           = 0644,
437                 .proc_handler   = &proc_dointvec,
438         },
439         {
440                 .ctl_name       = KERN_PRINTK,
441                 .procname       = "printk",
442                 .data           = &console_loglevel,
443                 .maxlen         = 4*sizeof(int),
444                 .mode           = 0644,
445                 .proc_handler   = &proc_dointvec,
446         },
447 #ifdef CONFIG_KMOD
448         {
449                 .ctl_name       = KERN_MODPROBE,
450                 .procname       = "modprobe",
451                 .data           = &modprobe_path,
452                 .maxlen         = KMOD_PATH_LEN,
453                 .mode           = 0644,
454                 .proc_handler   = &proc_dostring,
455                 .strategy       = &sysctl_string,
456         },
457 #endif
458 #ifdef CONFIG_HOTPLUG
459         {
460                 .ctl_name       = KERN_HOTPLUG,
461                 .procname       = "hotplug",
462                 .data           = &hotplug_path,
463                 .maxlen         = KMOD_PATH_LEN,
464                 .mode           = 0644,
465                 .proc_handler   = &proc_dostring,
466                 .strategy       = &sysctl_string,
467         },
468 #endif
469 #ifdef CONFIG_CHR_DEV_SG
470         {
471                 .ctl_name       = KERN_SG_BIG_BUFF,
472                 .procname       = "sg-big-buff",
473                 .data           = &sg_big_buff,
474                 .maxlen         = sizeof (int),
475                 .mode           = 0444,
476                 .proc_handler   = &proc_dointvec,
477         },
478 #endif
479 #ifdef CONFIG_BSD_PROCESS_ACCT
480         {
481                 .ctl_name       = KERN_ACCT,
482                 .procname       = "acct",
483                 .data           = &acct_parm,
484                 .maxlen         = 3*sizeof(int),
485                 .mode           = 0644,
486                 .proc_handler   = &proc_dointvec,
487         },
488 #endif
489 #ifdef CONFIG_SYSVIPC
490         {
491                 .ctl_name       = KERN_SHMMAX,
492                 .procname       = "shmmax",
493                 .data           = &shm_ctlmax,
494                 .maxlen         = sizeof (size_t),
495                 .mode           = 0644,
496                 .proc_handler   = &proc_doulongvec_minmax,
497         },
498         {
499                 .ctl_name       = KERN_SHMALL,
500                 .procname       = "shmall",
501                 .data           = &shm_ctlall,
502                 .maxlen         = sizeof (size_t),
503                 .mode           = 0644,
504                 .proc_handler   = &proc_doulongvec_minmax,
505         },
506         {
507                 .ctl_name       = KERN_SHMMNI,
508                 .procname       = "shmmni",
509                 .data           = &shm_ctlmni,
510                 .maxlen         = sizeof (int),
511                 .mode           = 0644,
512                 .proc_handler   = &proc_dointvec,
513         },
514         {
515                 .ctl_name       = KERN_MSGMAX,
516                 .procname       = "msgmax",
517                 .data           = &msg_ctlmax,
518                 .maxlen         = sizeof (int),
519                 .mode           = 0644,
520                 .proc_handler   = &proc_dointvec,
521         },
522         {
523                 .ctl_name       = KERN_MSGMNI,
524                 .procname       = "msgmni",
525                 .data           = &msg_ctlmni,
526                 .maxlen         = sizeof (int),
527                 .mode           = 0644,
528                 .proc_handler   = &proc_dointvec,
529         },
530         {
531                 .ctl_name       = KERN_MSGMNB,
532                 .procname       =  "msgmnb",
533                 .data           = &msg_ctlmnb,
534                 .maxlen         = sizeof (int),
535                 .mode           = 0644,
536                 .proc_handler   = &proc_dointvec,
537         },
538         {
539                 .ctl_name       = KERN_SEM,
540                 .procname       = "sem",
541                 .data           = &sem_ctls,
542                 .maxlen         = 4*sizeof (int),
543                 .mode           = 0644,
544                 .proc_handler   = &proc_dointvec,
545         },
546 #endif
547 #ifdef CONFIG_MAGIC_SYSRQ
548         {
549                 .ctl_name       = KERN_SYSRQ,
550                 .procname       = "sysrq",
551                 .data           = &sysrq_enabled,
552                 .maxlen         = sizeof (int),
553                 .mode           = 0644,
554                 .proc_handler   = &proc_dointvec,
555         },
556 #endif
557         {
558                 .ctl_name       = KERN_CADPID,
559                 .procname       = "cad_pid",
560                 .data           = &cad_pid,
561                 .maxlen         = sizeof (int),
562                 .mode           = 0600,
563                 .proc_handler   = &proc_dointvec,
564         },
565         {
566                 .ctl_name       = KERN_MAX_THREADS,
567                 .procname       = "threads-max",
568                 .data           = &max_threads,
569                 .maxlen         = sizeof(int),
570                 .mode           = 0644,
571                 .proc_handler   = &proc_dointvec,
572         },
573         {
574                 .ctl_name       = KERN_RANDOM,
575                 .procname       = "random",
576                 .mode           = 0555,
577                 .child          = random_table,
578         },
579 #ifdef CONFIG_UNIX98_PTYS
580         {
581                 .ctl_name       = KERN_PTY,
582                 .procname       = "pty",
583                 .mode           = 0555,
584                 .child          = pty_table,
585         },
586 #endif
587         {
588                 .ctl_name       = KERN_OVERFLOWUID,
589                 .procname       = "overflowuid",
590                 .data           = &overflowuid,
591                 .maxlen         = sizeof(int),
592                 .mode           = 0644,
593                 .proc_handler   = &proc_dointvec_minmax,
594                 .strategy       = &sysctl_intvec,
595                 .extra1         = &minolduid,
596                 .extra2         = &maxolduid,
597         },
598         {
599                 .ctl_name       = KERN_OVERFLOWGID,
600                 .procname       = "overflowgid",
601                 .data           = &overflowgid,
602                 .maxlen         = sizeof(int),
603                 .mode           = 0644,
604                 .proc_handler   = &proc_dointvec_minmax,
605                 .strategy       = &sysctl_intvec,
606                 .extra1         = &minolduid,
607                 .extra2         = &maxolduid,
608         },
609 #ifdef CONFIG_ARCH_S390
610 #ifdef CONFIG_MATHEMU
611         {
612                 .ctl_name       = KERN_IEEE_EMULATION_WARNINGS,
613                 .procname       = "ieee_emulation_warnings",
614                 .data           = &sysctl_ieee_emulation_warnings,
615                 .maxlen         = sizeof(int),
616                 .mode           = 0644,
617                 .proc_handler   = &proc_dointvec,
618         },
619 #endif
620 #ifdef CONFIG_NO_IDLE_HZ
621         {
622                 .ctl_name       = KERN_HZ_TIMER,
623                 .procname       = "hz_timer",
624                 .data           = &sysctl_hz_timer,
625                 .maxlen         = sizeof(int),
626                 .mode           = 0644,
627                 .proc_handler   = &proc_dointvec,
628         },
629 #endif
630         {
631                 .ctl_name       = KERN_S390_USER_DEBUG_LOGGING,
632                 .procname       = "userprocess_debug",
633                 .data           = &sysctl_userprocess_debug,
634                 .maxlen         = sizeof(int),
635                 .mode           = 0644,
636                 .proc_handler   = &proc_dointvec,
637         },
638 #endif
639         {
640                 .ctl_name       = KERN_PIDMAX,
641                 .procname       = "pid_max",
642                 .data           = &pid_max,
643                 .maxlen         = sizeof (int),
644                 .mode           = 0644,
645                 .proc_handler   = &proc_dointvec,
646         },
647         {
648                 .ctl_name       = KERN_PANIC_ON_OOPS,
649                 .procname       = "panic_on_oops",
650                 .data           = &panic_on_oops,
651                 .maxlen         = sizeof(int),
652                 .mode           = 0644,
653                 .proc_handler   = &proc_dointvec,
654         },
655         {
656                 .ctl_name       = KERN_PRINTK_RATELIMIT,
657                 .procname       = "printk_ratelimit",
658                 .data           = &printk_ratelimit_jiffies,
659                 .maxlen         = sizeof(int),
660                 .mode           = 0644,
661                 .proc_handler   = &proc_dointvec_jiffies,
662                 .strategy       = &sysctl_jiffies,
663         },
664         {
665                 .ctl_name       = KERN_PRINTK_RATELIMIT_BURST,
666                 .procname       = "printk_ratelimit_burst",
667                 .data           = &printk_ratelimit_burst,
668                 .maxlen         = sizeof(int),
669                 .mode           = 0644,
670                 .proc_handler   = &proc_dointvec,
671         },
672         {
673                 .ctl_name       = KERN_NGROUPS_MAX,
674                 .procname       = "ngroups_max",
675                 .data           = &ngroups_max,
676                 .maxlen         = sizeof (int),
677                 .mode           = 0444,
678                 .proc_handler   = &proc_dointvec,
679         },
680         { .ctl_name = 0 }
681 };
682
683 /* Constants for minimum and maximum testing in vm_table.
684    We use these as one-element integer vectors. */
685 static int zero;
686 static int one_hundred = 100;
687
688
689 static ctl_table vm_table[] = {
690         {
691                 .ctl_name       = VM_OVERCOMMIT_MEMORY,
692                 .procname       = "overcommit_memory",
693                 .data           = &sysctl_overcommit_memory,
694                 .maxlen         = sizeof(sysctl_overcommit_memory),
695                 .mode           = 0644,
696                 .proc_handler   = &proc_dointvec,
697         },
698         {
699                 .ctl_name       = VM_OVERCOMMIT_RATIO,
700                 .procname       = "overcommit_ratio",
701                 .data           = &sysctl_overcommit_ratio,
702                 .maxlen         = sizeof(sysctl_overcommit_ratio),
703                 .mode           = 0644,
704                 .proc_handler   = &proc_dointvec,
705         },
706         {
707                 .ctl_name       = VM_PAGE_CLUSTER,
708                 .procname       = "page-cluster", 
709                 .data           = &page_cluster,
710                 .maxlen         = sizeof(int),
711                 .mode           = 0644,
712                 .proc_handler   = &proc_dointvec,
713         },
714         {
715                 .ctl_name       = VM_DIRTY_BACKGROUND,
716                 .procname       = "dirty_background_ratio",
717                 .data           = &dirty_background_ratio,
718                 .maxlen         = sizeof(dirty_background_ratio),
719                 .mode           = 0644,
720                 .proc_handler   = &proc_dointvec_minmax,
721                 .strategy       = &sysctl_intvec,
722                 .extra1         = &zero,
723                 .extra2         = &one_hundred,
724         },
725         {
726                 .ctl_name       = VM_DIRTY_RATIO,
727                 .procname       = "dirty_ratio",
728                 .data           = &vm_dirty_ratio,
729                 .maxlen         = sizeof(vm_dirty_ratio),
730                 .mode           = 0644,
731                 .proc_handler   = &proc_dointvec_minmax,
732                 .strategy       = &sysctl_intvec,
733                 .extra1         = &zero,
734                 .extra2         = &one_hundred,
735         },
736         {
737                 .ctl_name       = VM_DIRTY_WB_CS,
738                 .procname       = "dirty_writeback_centisecs",
739                 .data           = &dirty_writeback_centisecs,
740                 .maxlen         = sizeof(dirty_writeback_centisecs),
741                 .mode           = 0644,
742                 .proc_handler   = &dirty_writeback_centisecs_handler,
743         },
744         {
745                 .ctl_name       = VM_DIRTY_EXPIRE_CS,
746                 .procname       = "dirty_expire_centisecs",
747                 .data           = &dirty_expire_centisecs,
748                 .maxlen         = sizeof(dirty_expire_centisecs),
749                 .mode           = 0644,
750                 .proc_handler   = &proc_dointvec,
751         },
752         {
753                 .ctl_name       = VM_NR_PDFLUSH_THREADS,
754                 .procname       = "nr_pdflush_threads",
755                 .data           = &nr_pdflush_threads,
756                 .maxlen         = sizeof nr_pdflush_threads,
757                 .mode           = 0444 /* read-only*/,
758                 .proc_handler   = &proc_dointvec,
759         },
760         {
761                 .ctl_name       = VM_SWAPPINESS,
762                 .procname       = "swappiness",
763                 .data           = &vm_swappiness,
764                 .maxlen         = sizeof(vm_swappiness),
765                 .mode           = 0644,
766                 .proc_handler   = &proc_dointvec_minmax,
767                 .strategy       = &sysctl_intvec,
768                 .extra1         = &zero,
769                 .extra2         = &one_hundred,
770         },
771 #ifdef CONFIG_HUGETLB_PAGE
772          {
773                 .ctl_name       = VM_HUGETLB_PAGES,
774                 .procname       = "nr_hugepages",
775                 .data           = &max_huge_pages,
776                 .maxlen         = sizeof(unsigned long),
777                 .mode           = 0644,
778                 .proc_handler   = &hugetlb_sysctl_handler,
779                 .extra1         = (void *)&hugetlb_zero,
780                 .extra2         = (void *)&hugetlb_infinity,
781          },
782 #endif
783         {
784                 .ctl_name       = VM_LOWER_ZONE_PROTECTION,
785                 .procname       = "lower_zone_protection",
786                 .data           = &sysctl_lower_zone_protection,
787                 .maxlen         = sizeof(sysctl_lower_zone_protection),
788                 .mode           = 0644,
789                 .proc_handler   = &lower_zone_protection_sysctl_handler,
790                 .strategy       = &sysctl_intvec,
791                 .extra1         = &zero,
792         },
793         {
794                 .ctl_name       = VM_MIN_FREE_KBYTES,
795                 .procname       = "min_free_kbytes",
796                 .data           = &min_free_kbytes,
797                 .maxlen         = sizeof(min_free_kbytes),
798                 .mode           = 0644,
799                 .proc_handler   = &min_free_kbytes_sysctl_handler,
800                 .strategy       = &sysctl_intvec,
801                 .extra1         = &zero,
802         },
803         {
804                 .ctl_name       = VM_MAX_MAP_COUNT,
805                 .procname       = "max_map_count",
806                 .data           = &sysctl_max_map_count,
807                 .maxlen         = sizeof(sysctl_max_map_count),
808                 .mode           = 0644,
809                 .proc_handler   = &proc_dointvec
810         },
811         {
812                 .ctl_name       = VM_LAPTOP_MODE,
813                 .procname       = "laptop_mode",
814                 .data           = &laptop_mode,
815                 .maxlen         = sizeof(laptop_mode),
816                 .mode           = 0644,
817                 .proc_handler   = &proc_dointvec,
818                 .strategy       = &sysctl_intvec,
819                 .extra1         = &zero,
820         },
821         {
822                 .ctl_name       = VM_BLOCK_DUMP,
823                 .procname       = "block_dump",
824                 .data           = &block_dump,
825                 .maxlen         = sizeof(block_dump),
826                 .mode           = 0644,
827                 .proc_handler   = &proc_dointvec,
828                 .strategy       = &sysctl_intvec,
829                 .extra1         = &zero,
830         },
831         {
832                 .ctl_name       = VM_VFS_CACHE_PRESSURE,
833                 .procname       = "vfs_cache_pressure",
834                 .data           = &sysctl_vfs_cache_pressure,
835                 .maxlen         = sizeof(sysctl_vfs_cache_pressure),
836                 .mode           = 0644,
837                 .proc_handler   = &proc_dointvec,
838                 .strategy       = &sysctl_intvec,
839                 .extra1         = &zero,
840         },
841         { .ctl_name = 0 }
842 };
843
844 static ctl_table proc_table[] = {
845         { .ctl_name = 0 }
846 };
847
848 static ctl_table fs_table[] = {
849         {
850                 .ctl_name       = FS_NRINODE,
851                 .procname       = "inode-nr",
852                 .data           = &inodes_stat,
853                 .maxlen         = 2*sizeof(int),
854                 .mode           = 0444,
855                 .proc_handler   = &proc_dointvec,
856         },
857         {
858                 .ctl_name       = FS_STATINODE,
859                 .procname       = "inode-state",
860                 .data           = &inodes_stat,
861                 .maxlen         = 7*sizeof(int),
862                 .mode           = 0444,
863                 .proc_handler   = &proc_dointvec,
864         },
865         {
866                 .ctl_name       = FS_NRFILE,
867                 .procname       = "file-nr",
868                 .data           = &files_stat,
869                 .maxlen         = 3*sizeof(int),
870                 .mode           = 0444,
871                 .proc_handler   = &proc_dointvec,
872         },
873         {
874                 .ctl_name       = FS_MAXFILE,
875                 .procname       = "file-max",
876                 .data           = &files_stat.max_files,
877                 .maxlen         = sizeof(int),
878                 .mode           = 0644,
879                 .proc_handler   = &proc_dointvec,
880         },
881         {
882                 .ctl_name       = FS_DENTRY,
883                 .procname       = "dentry-state",
884                 .data           = &dentry_stat,
885                 .maxlen         = 6*sizeof(int),
886                 .mode           = 0444,
887                 .proc_handler   = &proc_dointvec,
888         },
889         {
890                 .ctl_name       = FS_OVERFLOWUID,
891                 .procname       = "overflowuid",
892                 .data           = &fs_overflowuid,
893                 .maxlen         = sizeof(int),
894                 .mode           = 0644,
895                 .proc_handler   = &proc_dointvec_minmax,
896                 .strategy       = &sysctl_intvec,
897                 .extra1         = &minolduid,
898                 .extra2         = &maxolduid,
899         },
900         {
901                 .ctl_name       = FS_OVERFLOWGID,
902                 .procname       = "overflowgid",
903                 .data           = &fs_overflowgid,
904                 .maxlen         = sizeof(int),
905                 .mode           = 0644,
906                 .proc_handler   = &proc_dointvec_minmax,
907                 .strategy       = &sysctl_intvec,
908                 .extra1         = &minolduid,
909                 .extra2         = &maxolduid,
910         },
911         {
912                 .ctl_name       = FS_LEASES,
913                 .procname       = "leases-enable",
914                 .data           = &leases_enable,
915                 .maxlen         = sizeof(int),
916                 .mode           = 0644,
917                 .proc_handler   = &proc_dointvec,
918         },
919         {
920                 .ctl_name       = FS_DIR_NOTIFY,
921                 .procname       = "dir-notify-enable",
922                 .data           = &dir_notify_enable,
923                 .maxlen         = sizeof(int),
924                 .mode           = 0644,
925                 .proc_handler   = &proc_dointvec,
926         },
927         {
928                 .ctl_name       = FS_LEASE_TIME,
929                 .procname       = "lease-break-time",
930                 .data           = &lease_break_time,
931                 .maxlen         = sizeof(int),
932                 .mode           = 0644,
933                 .proc_handler   = &proc_dointvec,
934         },
935         {
936                 .ctl_name       = FS_AIO_NR,
937                 .procname       = "aio-nr",
938                 .data           = &aio_nr,
939                 .maxlen         = sizeof(aio_nr),
940                 .mode           = 0444,
941                 .proc_handler   = &proc_dointvec,
942         },
943         {
944                 .ctl_name       = FS_AIO_MAX_NR,
945                 .procname       = "aio-max-nr",
946                 .data           = &aio_max_nr,
947                 .maxlen         = sizeof(aio_max_nr),
948                 .mode           = 0644,
949                 .proc_handler   = &proc_dointvec,
950         },
951         { .ctl_name = 0 }
952 };
953
954 static ctl_table debug_table[] = {
955         { .ctl_name = 0 }
956 };
957
958 static ctl_table dev_table[] = {
959         { .ctl_name = 0 }
960 };  
961
962 extern void init_irq_proc (void);
963
964 void __init sysctl_init(void)
965 {
966 #ifdef CONFIG_PROC_FS
967         register_proc_table(root_table, proc_sys_root);
968         init_irq_proc();
969 #endif
970 }
971
972 int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp,
973                void __user *newval, size_t newlen)
974 {
975         struct list_head *tmp;
976
977         if (nlen <= 0 || nlen >= CTL_MAXNAME)
978                 return -ENOTDIR;
979         if (oldval) {
980                 int old_len;
981                 if (!oldlenp || get_user(old_len, oldlenp))
982                         return -EFAULT;
983         }
984         tmp = &root_table_header.ctl_entry;
985         do {
986                 struct ctl_table_header *head =
987                         list_entry(tmp, struct ctl_table_header, ctl_entry);
988                 void *context = NULL;
989                 int error = parse_table(name, nlen, oldval, oldlenp, 
990                                         newval, newlen, head->ctl_table,
991                                         &context);
992                 if (context)
993                         kfree(context);
994                 if (error != -ENOTDIR)
995                         return error;
996                 tmp = tmp->next;
997         } while (tmp != &root_table_header.ctl_entry);
998         return -ENOTDIR;
999 }
1000
1001 asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
1002 {
1003         struct __sysctl_args tmp;
1004         int error;
1005
1006         if (copy_from_user(&tmp, args, sizeof(tmp)))
1007                 return -EFAULT;
1008
1009         lock_kernel();
1010         error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
1011                           tmp.newval, tmp.newlen);
1012         unlock_kernel();
1013         return error;
1014 }
1015
1016 /*
1017  * ctl_perm does NOT grant the superuser all rights automatically, because
1018  * some sysctl variables are readonly even to root.
1019  */
1020
1021 static int test_perm(int mode, int op)
1022 {
1023         if (!current->euid)
1024                 mode >>= 6;
1025         else if (in_egroup_p(0))
1026                 mode >>= 3;
1027         if ((mode & op & 0007) == op)
1028                 return 0;
1029         return -EACCES;
1030 }
1031
1032 static inline int ctl_perm(ctl_table *table, int op)
1033 {
1034         int error;
1035         error = security_sysctl(table, op);
1036         if (error)
1037                 return error;
1038         return test_perm(table->mode, op);
1039 }
1040
1041 static int parse_table(int __user *name, int nlen,
1042                        void __user *oldval, size_t __user *oldlenp,
1043                        void __user *newval, size_t newlen,
1044                        ctl_table *table, void **context)
1045 {
1046         int n;
1047 repeat:
1048         if (!nlen)
1049                 return -ENOTDIR;
1050         if (get_user(n, name))
1051                 return -EFAULT;
1052         for ( ; table->ctl_name; table++) {
1053                 if (n == table->ctl_name || table->ctl_name == CTL_ANY) {
1054                         int error;
1055                         if (table->child) {
1056                                 if (ctl_perm(table, 001))
1057                                         return -EPERM;
1058                                 if (table->strategy) {
1059                                         error = table->strategy(
1060                                                 table, name, nlen,
1061                                                 oldval, oldlenp,
1062                                                 newval, newlen, context);
1063                                         if (error)
1064                                                 return error;
1065                                 }
1066                                 name++;
1067                                 nlen--;
1068                                 table = table->child;
1069                                 goto repeat;
1070                         }
1071                         error = do_sysctl_strategy(table, name, nlen,
1072                                                    oldval, oldlenp,
1073                                                    newval, newlen, context);
1074                         return error;
1075                 }
1076         }
1077         return -ENOTDIR;
1078 }
1079
1080 /* Perform the actual read/write of a sysctl table entry. */
1081 int do_sysctl_strategy (ctl_table *table, 
1082                         int __user *name, int nlen,
1083                         void __user *oldval, size_t __user *oldlenp,
1084                         void __user *newval, size_t newlen, void **context)
1085 {
1086         int op = 0, rc;
1087         size_t len;
1088
1089         if (oldval)
1090                 op |= 004;
1091         if (newval) 
1092                 op |= 002;
1093         if (ctl_perm(table, op))
1094                 return -EPERM;
1095
1096         if (table->strategy) {
1097                 rc = table->strategy(table, name, nlen, oldval, oldlenp,
1098                                      newval, newlen, context);
1099                 if (rc < 0)
1100                         return rc;
1101                 if (rc > 0)
1102                         return 0;
1103         }
1104
1105         /* If there is no strategy routine, or if the strategy returns
1106          * zero, proceed with automatic r/w */
1107         if (table->data && table->maxlen) {
1108                 if (oldval && oldlenp) {
1109                         if (get_user(len, oldlenp))
1110                                 return -EFAULT;
1111                         if (len) {
1112                                 if (len > table->maxlen)
1113                                         len = table->maxlen;
1114                                 if(copy_to_user(oldval, table->data, len))
1115                                         return -EFAULT;
1116                                 if(put_user(len, oldlenp))
1117                                         return -EFAULT;
1118                         }
1119                 }
1120                 if (newval && newlen) {
1121                         len = newlen;
1122                         if (len > table->maxlen)
1123                                 len = table->maxlen;
1124                         if(copy_from_user(table->data, newval, len))
1125                                 return -EFAULT;
1126                 }
1127         }
1128         return 0;
1129 }
1130
1131 /**
1132  * register_sysctl_table - register a sysctl hierarchy
1133  * @table: the top-level table structure
1134  * @insert_at_head: whether the entry should be inserted in front or at the end
1135  *
1136  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
1137  * array. An entry with a ctl_name of 0 terminates the table. 
1138  *
1139  * The members of the &ctl_table structure are used as follows:
1140  *
1141  * ctl_name - This is the numeric sysctl value used by sysctl(2). The number
1142  *            must be unique within that level of sysctl
1143  *
1144  * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
1145  *            enter a sysctl file
1146  *
1147  * data - a pointer to data for use by proc_handler
1148  *
1149  * maxlen - the maximum size in bytes of the data
1150  *
1151  * mode - the file permissions for the /proc/sys file, and for sysctl(2)
1152  *
1153  * child - a pointer to the child sysctl table if this entry is a directory, or
1154  *         %NULL.
1155  *
1156  * proc_handler - the text handler routine (described below)
1157  *
1158  * strategy - the strategy routine (described below)
1159  *
1160  * de - for internal use by the sysctl routines
1161  *
1162  * extra1, extra2 - extra pointers usable by the proc handler routines
1163  *
1164  * Leaf nodes in the sysctl tree will be represented by a single file
1165  * under /proc; non-leaf nodes will be represented by directories.
1166  *
1167  * sysctl(2) can automatically manage read and write requests through
1168  * the sysctl table.  The data and maxlen fields of the ctl_table
1169  * struct enable minimal validation of the values being written to be
1170  * performed, and the mode field allows minimal authentication.
1171  *
1172  * More sophisticated management can be enabled by the provision of a
1173  * strategy routine with the table entry.  This will be called before
1174  * any automatic read or write of the data is performed.
1175  *
1176  * The strategy routine may return
1177  *
1178  * < 0 - Error occurred (error is passed to user process)
1179  *
1180  * 0   - OK - proceed with automatic read or write.
1181  *
1182  * > 0 - OK - read or write has been done by the strategy routine, so
1183  *       return immediately.
1184  *
1185  * There must be a proc_handler routine for any terminal nodes
1186  * mirrored under /proc/sys (non-terminals are handled by a built-in
1187  * directory handler).  Several default handlers are available to
1188  * cover common cases -
1189  *
1190  * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
1191  * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(), 
1192  * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax()
1193  *
1194  * It is the handler's job to read the input buffer from user memory
1195  * and process it. The handler should return 0 on success.
1196  *
1197  * This routine returns %NULL on a failure to register, and a pointer
1198  * to the table header on success.
1199  */
1200 struct ctl_table_header *register_sysctl_table(ctl_table * table, 
1201                                                int insert_at_head)
1202 {
1203         struct ctl_table_header *tmp;
1204         tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
1205         if (!tmp)
1206                 return NULL;
1207         tmp->ctl_table = table;
1208         INIT_LIST_HEAD(&tmp->ctl_entry);
1209         if (insert_at_head)
1210                 list_add(&tmp->ctl_entry, &root_table_header.ctl_entry);
1211         else
1212                 list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
1213 #ifdef CONFIG_PROC_FS
1214         register_proc_table(table, proc_sys_root);
1215 #endif
1216         return tmp;
1217 }
1218
1219 /**
1220  * unregister_sysctl_table - unregister a sysctl table hierarchy
1221  * @header: the header returned from register_sysctl_table
1222  *
1223  * Unregisters the sysctl table and all children. proc entries may not
1224  * actually be removed until they are no longer used by anyone.
1225  */
1226 void unregister_sysctl_table(struct ctl_table_header * header)
1227 {
1228         list_del(&header->ctl_entry);
1229 #ifdef CONFIG_PROC_FS
1230         unregister_proc_table(header->ctl_table, proc_sys_root);
1231 #endif
1232         kfree(header);
1233 }
1234
1235 /*
1236  * /proc/sys support
1237  */
1238
1239 #ifdef CONFIG_PROC_FS
1240
1241 /* Scan the sysctl entries in table and add them all into /proc */
1242 static void register_proc_table(ctl_table * table, struct proc_dir_entry *root)
1243 {
1244         struct proc_dir_entry *de;
1245         int len;
1246         mode_t mode;
1247         
1248         for (; table->ctl_name; table++) {
1249                 /* Can't do anything without a proc name. */
1250                 if (!table->procname)
1251                         continue;
1252                 /* Maybe we can't do anything with it... */
1253                 if (!table->proc_handler && !table->child) {
1254                         printk(KERN_WARNING "SYSCTL: Can't register %s\n",
1255                                 table->procname);
1256                         continue;
1257                 }
1258
1259                 len = strlen(table->procname);
1260                 mode = table->mode;
1261
1262                 de = NULL;
1263                 if (table->proc_handler)
1264                         mode |= S_IFREG;
1265                 else {
1266                         mode |= S_IFDIR;
1267                         for (de = root->subdir; de; de = de->next) {
1268                                 if (proc_match(len, table->procname, de))
1269                                         break;
1270                         }
1271                         /* If the subdir exists already, de is non-NULL */
1272                 }
1273
1274                 if (!de) {
1275                         de = create_proc_entry(table->procname, mode, root);
1276                         if (!de)
1277                                 continue;
1278                         de->data = (void *) table;
1279                         if (table->proc_handler)
1280                                 de->proc_fops = &proc_sys_file_operations;
1281                 }
1282                 table->de = de;
1283                 if (de->mode & S_IFDIR)
1284                         register_proc_table(table->child, de);
1285         }
1286 }
1287
1288 /*
1289  * Unregister a /proc sysctl table and any subdirectories.
1290  */
1291 static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root)
1292 {
1293         struct proc_dir_entry *de;
1294         for (; table->ctl_name; table++) {
1295                 if (!(de = table->de))
1296                         continue;
1297                 if (de->mode & S_IFDIR) {
1298                         if (!table->child) {
1299                                 printk (KERN_ALERT "Help - malformed sysctl tree on free\n");
1300                                 continue;
1301                         }
1302                         unregister_proc_table(table->child, de);
1303
1304                         /* Don't unregister directories which still have entries.. */
1305                         if (de->subdir)
1306                                 continue;
1307                 }
1308
1309                 /* Don't unregister proc entries that are still being used.. */
1310                 if (atomic_read(&de->count))
1311                         continue;
1312
1313                 table->de = NULL;
1314                 remove_proc_entry(table->procname, root);
1315         }
1316 }
1317
1318 static ssize_t do_rw_proc(int write, struct file * file, char __user * buf,
1319                           size_t count, loff_t *ppos)
1320 {
1321         int op;
1322         struct proc_dir_entry *de;
1323         struct ctl_table *table;
1324         size_t res;
1325         ssize_t error;
1326         
1327         de = PDE(file->f_dentry->d_inode);
1328         if (!de || !de->data)
1329                 return -ENOTDIR;
1330         table = (struct ctl_table *) de->data;
1331         if (!table || !table->proc_handler)
1332                 return -ENOTDIR;
1333         op = (write ? 002 : 004);
1334         if (ctl_perm(table, op))
1335                 return -EPERM;
1336         
1337         res = count;
1338
1339         /*
1340          * FIXME: we need to pass on ppos to the handler.
1341          */
1342
1343         error = (*table->proc_handler) (table, write, file, buf, &res);
1344         if (error)
1345                 return error;
1346         return res;
1347 }
1348
1349 static int proc_opensys(struct inode *inode, struct file *file)
1350 {
1351         if (file->f_mode & FMODE_WRITE) {
1352                 /*
1353                  * sysctl entries that are not writable,
1354                  * are _NOT_ writable, capabilities or not.
1355                  */
1356                 if (!(inode->i_mode & S_IWUSR))
1357                         return -EPERM;
1358         }
1359
1360         return 0;
1361 }
1362
1363 static ssize_t proc_readsys(struct file * file, char __user * buf,
1364                             size_t count, loff_t *ppos)
1365 {
1366         return do_rw_proc(0, file, buf, count, ppos);
1367 }
1368
1369 static ssize_t proc_writesys(struct file * file, const char __user * buf,
1370                              size_t count, loff_t *ppos)
1371 {
1372         return do_rw_proc(1, file, (char __user *) buf, count, ppos);
1373 }
1374
1375 /**
1376  * proc_dostring - read a string sysctl
1377  * @table: the sysctl table
1378  * @write: %TRUE if this is a write to the sysctl file
1379  * @filp: the file structure
1380  * @buffer: the user buffer
1381  * @lenp: the size of the user buffer
1382  *
1383  * Reads/writes a string from/to the user buffer. If the kernel
1384  * buffer provided is not large enough to hold the string, the
1385  * string is truncated. The copied string is %NULL-terminated.
1386  * If the string is being read by the user process, it is copied
1387  * and a newline '\n' is added. It is truncated if the buffer is
1388  * not large enough.
1389  *
1390  * Returns 0 on success.
1391  */
1392 int proc_dostring(ctl_table *table, int write, struct file *filp,
1393                   void __user *buffer, size_t *lenp)
1394 {
1395         size_t len;
1396         char __user *p;
1397         char c;
1398         
1399         if (!table->data || !table->maxlen || !*lenp ||
1400             (filp->f_pos && !write)) {
1401                 *lenp = 0;
1402                 return 0;
1403         }
1404         
1405         if (write) {
1406                 len = 0;
1407                 p = buffer;
1408                 while (len < *lenp) {
1409                         if (get_user(c, p++))
1410                                 return -EFAULT;
1411                         if (c == 0 || c == '\n')
1412                                 break;
1413                         len++;
1414                 }
1415                 if (len >= table->maxlen)
1416                         len = table->maxlen-1;
1417                 if(copy_from_user(table->data, buffer, len))
1418                         return -EFAULT;
1419                 ((char *) table->data)[len] = 0;
1420                 filp->f_pos += *lenp;
1421         } else {
1422                 len = strlen(table->data);
1423                 if (len > table->maxlen)
1424                         len = table->maxlen;
1425                 if (len > *lenp)
1426                         len = *lenp;
1427                 if (len)
1428                         if(copy_to_user(buffer, table->data, len))
1429                                 return -EFAULT;
1430                 if (len < *lenp) {
1431                         if(put_user('\n', ((char __user *) buffer) + len))
1432                                 return -EFAULT;
1433                         len++;
1434                 }
1435                 *lenp = len;
1436                 filp->f_pos += len;
1437         }
1438         return 0;
1439 }
1440
1441 /*
1442  *      Special case of dostring for the UTS structure. This has locks
1443  *      to observe. Should this be in kernel/sys.c ????
1444  */
1445  
1446 static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
1447                   void __user *buffer, size_t *lenp)
1448 {
1449         int r;
1450
1451         if (!write) {
1452                 down_read(&uts_sem);
1453                 r=proc_dostring(table,0,filp,buffer,lenp);
1454                 up_read(&uts_sem);
1455         } else {
1456                 down_write(&uts_sem);
1457                 r=proc_dostring(table,1,filp,buffer,lenp);
1458                 up_write(&uts_sem);
1459         }
1460         return r;
1461 }
1462
1463 static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
1464                                  int *valp,
1465                                  int write, void *data)
1466 {
1467         if (write) {
1468                 *valp = *negp ? -*lvalp : *lvalp;
1469         } else {
1470                 int val = *valp;
1471                 if (val < 0) {
1472                         *negp = -1;
1473                         *lvalp = (unsigned long)-val;
1474                 } else {
1475                         *negp = 0;
1476                         *lvalp = (unsigned long)val;
1477                 }
1478         }
1479         return 0;
1480 }
1481
1482 static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
1483                   void __user *buffer, size_t *lenp, 
1484                   int (*conv)(int *negp, unsigned long *lvalp, int *valp,
1485                               int write, void *data),
1486                   void *data)
1487 {
1488 #define TMPBUFLEN 20
1489         int *i, vleft, first=1, neg, val;
1490         unsigned long lval;
1491         size_t left, len;
1492         
1493         char buf[TMPBUFLEN], *p;
1494         char __user *s = buffer;
1495         
1496         if (!table->data || !table->maxlen || !*lenp ||
1497             (filp->f_pos && !write)) {
1498                 *lenp = 0;
1499                 return 0;
1500         }
1501         
1502         i = (int *) table->data;
1503         vleft = table->maxlen / sizeof(*i);
1504         left = *lenp;
1505
1506         if (!conv)
1507                 conv = do_proc_dointvec_conv;
1508
1509         for (; left && vleft--; i++, first=0) {
1510                 if (write) {
1511                         while (left) {
1512                                 char c;
1513                                 if (get_user(c, s))
1514                                         return -EFAULT;
1515                                 if (!isspace(c))
1516                                         break;
1517                                 left--;
1518                                 s++;
1519                         }
1520                         if (!left)
1521                                 break;
1522                         neg = 0;
1523                         len = left;
1524                         if (len > sizeof(buf) - 1)
1525                                 len = sizeof(buf) - 1;
1526                         if (copy_from_user(buf, s, len))
1527                                 return -EFAULT;
1528                         buf[len] = 0;
1529                         p = buf;
1530                         if (*p == '-' && left > 1) {
1531                                 neg = 1;
1532                                 left--, p++;
1533                         }
1534                         if (*p < '0' || *p > '9')
1535                                 break;
1536
1537                         lval = simple_strtoul(p, &p, 0);
1538
1539                         len = p-buf;
1540                         if ((len < left) && *p && !isspace(*p))
1541                                 break;
1542                         if (neg)
1543                                 val = -val;
1544                         s += len;
1545                         left -= len;
1546
1547                         if (conv(&neg, &lval, i, 1, data))
1548                                 break;
1549                 } else {
1550                         p = buf;
1551                         if (!first)
1552                                 *p++ = '\t';
1553         
1554                         if (conv(&neg, &lval, i, 0, data))
1555                                 break;
1556
1557                         sprintf(p, "%s%lu", neg ? "-" : "", lval);
1558                         len = strlen(buf);
1559                         if (len > left)
1560                                 len = left;
1561                         if(copy_to_user(s, buf, len))
1562                                 return -EFAULT;
1563                         left -= len;
1564                         s += len;
1565                 }
1566         }
1567
1568         if (!write && !first && left) {
1569                 if(put_user('\n', s))
1570                         return -EFAULT;
1571                 left--, s++;
1572         }
1573         if (write) {
1574                 while (left) {
1575                         char c;
1576                         if (get_user(c, s++))
1577                                 return -EFAULT;
1578                         if (!isspace(c))
1579                                 break;
1580                         left--;
1581                 }
1582         }
1583         if (write && first)
1584                 return -EINVAL;
1585         *lenp -= left;
1586         filp->f_pos += *lenp;
1587         return 0;
1588 #undef TMPBUFLEN
1589 }
1590
1591 /**
1592  * proc_dointvec - read a vector of integers
1593  * @table: the sysctl table
1594  * @write: %TRUE if this is a write to the sysctl file
1595  * @filp: the file structure
1596  * @buffer: the user buffer
1597  * @lenp: the size of the user buffer
1598  *
1599  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1600  * values from/to the user buffer, treated as an ASCII string. 
1601  *
1602  * Returns 0 on success.
1603  */
1604 int proc_dointvec(ctl_table *table, int write, struct file *filp,
1605                      void __user *buffer, size_t *lenp)
1606 {
1607     return do_proc_dointvec(table,write,filp,buffer,lenp,
1608                             NULL,NULL);
1609 }
1610
1611 #define OP_SET  0
1612 #define OP_AND  1
1613 #define OP_OR   2
1614 #define OP_MAX  3
1615 #define OP_MIN  4
1616
1617 static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
1618                                       int *valp,
1619                                       int write, void *data)
1620 {
1621         int op = *(int *)data;
1622         if (write) {
1623                 int val = *negp ? -*lvalp : *lvalp;
1624                 switch(op) {
1625                 case OP_SET:    *valp = val; break;
1626                 case OP_AND:    *valp &= val; break;
1627                 case OP_OR:     *valp |= val; break;
1628                 case OP_MAX:    if(*valp < val)
1629                                         *valp = val;
1630                                 break;
1631                 case OP_MIN:    if(*valp > val)
1632                                 *valp = val;
1633                                 break;
1634                 }
1635         } else {
1636                 int val = *valp;
1637                 if (val < 0) {
1638                         *negp = -1;
1639                         *lvalp = (unsigned long)-val;
1640                 } else {
1641                         *negp = 0;
1642                         *lvalp = (unsigned long)val;
1643                 }
1644         }
1645         return 0;
1646 }
1647
1648 /*
1649  *      init may raise the set.
1650  */
1651  
1652 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
1653                         void __user *buffer, size_t *lenp)
1654 {
1655         int op;
1656
1657         if (!capable(CAP_SYS_MODULE)) {
1658                 return -EPERM;
1659         }
1660
1661         op = (current->pid == 1) ? OP_SET : OP_AND;
1662         return do_proc_dointvec(table,write,filp,buffer,lenp,
1663                                 do_proc_dointvec_bset_conv,&op);
1664 }
1665
1666 struct do_proc_dointvec_minmax_conv_param {
1667         int *min;
1668         int *max;
1669 };
1670
1671 static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp, 
1672                                         int *valp, 
1673                                         int write, void *data)
1674 {
1675         struct do_proc_dointvec_minmax_conv_param *param = data;
1676         if (write) {
1677                 int val = *negp ? -*lvalp : *lvalp;
1678                 if ((param->min && *param->min > val) ||
1679                     (param->max && *param->max < val))
1680                         return -EINVAL;
1681                 *valp = val;
1682         } else {
1683                 int val = *valp;
1684                 if (val < 0) {
1685                         *negp = -1;
1686                         *lvalp = (unsigned long)-val;
1687                 } else {
1688                         *negp = 0;
1689                         *lvalp = (unsigned long)val;
1690                 }
1691         }
1692         return 0;
1693 }
1694
1695 /**
1696  * proc_dointvec_minmax - read a vector of integers with min/max values
1697  * @table: the sysctl table
1698  * @write: %TRUE if this is a write to the sysctl file
1699  * @filp: the file structure
1700  * @buffer: the user buffer
1701  * @lenp: the size of the user buffer
1702  *
1703  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1704  * values from/to the user buffer, treated as an ASCII string.
1705  *
1706  * This routine will ensure the values are within the range specified by
1707  * table->extra1 (min) and table->extra2 (max).
1708  *
1709  * Returns 0 on success.
1710  */
1711 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
1712                   void __user *buffer, size_t *lenp)
1713 {
1714         struct do_proc_dointvec_minmax_conv_param param = {
1715                 .min = (int *) table->extra1,
1716                 .max = (int *) table->extra2,
1717         };
1718         return do_proc_dointvec(table, write, filp, buffer, lenp,
1719                                 do_proc_dointvec_minmax_conv, &param);
1720 }
1721
1722 static int do_proc_doulongvec_minmax(ctl_table *table, int write,
1723                                      struct file *filp,
1724                                      void __user *buffer, size_t *lenp,
1725                                      unsigned long convmul,
1726                                      unsigned long convdiv)
1727 {
1728 #define TMPBUFLEN 20
1729         unsigned long *i, *min, *max, val;
1730         int vleft, first=1, neg;
1731         size_t len, left;
1732         char buf[TMPBUFLEN], *p;
1733         char __user *s = buffer;
1734         
1735         if (!table->data || !table->maxlen || !*lenp ||
1736             (filp->f_pos && !write)) {
1737                 *lenp = 0;
1738                 return 0;
1739         }
1740         
1741         i = (unsigned long *) table->data;
1742         min = (unsigned long *) table->extra1;
1743         max = (unsigned long *) table->extra2;
1744         vleft = table->maxlen / sizeof(unsigned long);
1745         left = *lenp;
1746         
1747         for (; left && vleft--; i++, min++, max++, first=0) {
1748                 if (write) {
1749                         while (left) {
1750                                 char c;
1751                                 if (get_user(c, s))
1752                                         return -EFAULT;
1753                                 if (!isspace(c))
1754                                         break;
1755                                 left--;
1756                                 s++;
1757                         }
1758                         if (!left)
1759                                 break;
1760                         neg = 0;
1761                         len = left;
1762                         if (len > TMPBUFLEN-1)
1763                                 len = TMPBUFLEN-1;
1764                         if (copy_from_user(buf, s, len))
1765                                 return -EFAULT;
1766                         buf[len] = 0;
1767                         p = buf;
1768                         if (*p == '-' && left > 1) {
1769                                 neg = 1;
1770                                 left--, p++;
1771                         }
1772                         if (*p < '0' || *p > '9')
1773                                 break;
1774                         val = simple_strtoul(p, &p, 0) * convmul / convdiv ;
1775                         len = p-buf;
1776                         if ((len < left) && *p && !isspace(*p))
1777                                 break;
1778                         if (neg)
1779                                 val = -val;
1780                         s += len;
1781                         left -= len;
1782
1783                         if(neg)
1784                                 continue;
1785                         if ((min && val < *min) || (max && val > *max))
1786                                 continue;
1787                         *i = val;
1788                 } else {
1789                         p = buf;
1790                         if (!first)
1791                                 *p++ = '\t';
1792                         sprintf(p, "%lu", convdiv * (*i) / convmul);
1793                         len = strlen(buf);
1794                         if (len > left)
1795                                 len = left;
1796                         if(copy_to_user(s, buf, len))
1797                                 return -EFAULT;
1798                         left -= len;
1799                         s += len;
1800                 }
1801         }
1802
1803         if (!write && !first && left) {
1804                 if(put_user('\n', s))
1805                         return -EFAULT;
1806                 left--, s++;
1807         }
1808         if (write) {
1809                 while (left) {
1810                         char c;
1811                         if (get_user(c, s++))
1812                                 return -EFAULT;
1813                         if (!isspace(c))
1814                                 break;
1815                         left--;
1816                 }
1817         }
1818         if (write && first)
1819                 return -EINVAL;
1820         *lenp -= left;
1821         filp->f_pos += *lenp;
1822         return 0;
1823 #undef TMPBUFLEN
1824 }
1825
1826 /**
1827  * proc_doulongvec_minmax - read a vector of long integers with min/max values
1828  * @table: the sysctl table
1829  * @write: %TRUE if this is a write to the sysctl file
1830  * @filp: the file structure
1831  * @buffer: the user buffer
1832  * @lenp: the size of the user buffer
1833  *
1834  * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
1835  * values from/to the user buffer, treated as an ASCII string.
1836  *
1837  * This routine will ensure the values are within the range specified by
1838  * table->extra1 (min) and table->extra2 (max).
1839  *
1840  * Returns 0 on success.
1841  */
1842 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
1843                            void __user *buffer, size_t *lenp)
1844 {
1845     return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, 1l, 1l);
1846 }
1847
1848 /**
1849  * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
1850  * @table: the sysctl table
1851  * @write: %TRUE if this is a write to the sysctl file
1852  * @filp: the file structure
1853  * @buffer: the user buffer
1854  * @lenp: the size of the user buffer
1855  *
1856  * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
1857  * values from/to the user buffer, treated as an ASCII string. The values
1858  * are treated as milliseconds, and converted to jiffies when they are stored.
1859  *
1860  * This routine will ensure the values are within the range specified by
1861  * table->extra1 (min) and table->extra2 (max).
1862  *
1863  * Returns 0 on success.
1864  */
1865 int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
1866                                       struct file *filp,
1867                                       void __user *buffer, size_t *lenp)
1868 {
1869     return do_proc_doulongvec_minmax(table, write, filp, buffer,
1870                                      lenp, HZ, 1000l);
1871 }
1872
1873
1874 static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp,
1875                                          int *valp,
1876                                          int write, void *data)
1877 {
1878         if (write) {
1879                 *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ);
1880         } else {
1881                 int val = *valp;
1882                 unsigned long lval;
1883                 if (val < 0) {
1884                         *negp = -1;
1885                         lval = (unsigned long)-val;
1886                 } else {
1887                         *negp = 0;
1888                         lval = (unsigned long)val;
1889                 }
1890                 *lvalp = lval / HZ;
1891         }
1892         return 0;
1893 }
1894
1895 static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp,
1896                                                 int *valp,
1897                                                 int write, void *data)
1898 {
1899         if (write) {
1900                 *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp);
1901         } else {
1902                 int val = *valp;
1903                 unsigned long lval;
1904                 if (val < 0) {
1905                         *negp = -1;
1906                         lval = (unsigned long)-val;
1907                 } else {
1908                         *negp = 0;
1909                         lval = (unsigned long)val;
1910                 }
1911                 *lvalp = jiffies_to_clock_t(lval);
1912         }
1913         return 0;
1914 }
1915
1916 /**
1917  * proc_dointvec_jiffies - read a vector of integers as seconds
1918  * @table: the sysctl table
1919  * @write: %TRUE if this is a write to the sysctl file
1920  * @filp: the file structure
1921  * @buffer: the user buffer
1922  * @lenp: the size of the user buffer
1923  *
1924  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1925  * values from/to the user buffer, treated as an ASCII string. 
1926  * The values read are assumed to be in seconds, and are converted into
1927  * jiffies.
1928  *
1929  * Returns 0 on success.
1930  */
1931 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
1932                           void __user *buffer, size_t *lenp)
1933 {
1934     return do_proc_dointvec(table,write,filp,buffer,lenp,
1935                             do_proc_dointvec_jiffies_conv,NULL);
1936 }
1937
1938 /**
1939  * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
1940  * @table: the sysctl table
1941  * @write: %TRUE if this is a write to the sysctl file
1942  * @filp: the file structure
1943  * @buffer: the user buffer
1944  * @lenp: the size of the user buffer
1945  *
1946  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1947  * values from/to the user buffer, treated as an ASCII string. 
1948  * The values read are assumed to be in 1/USER_HZ seconds, and 
1949  * are converted into jiffies.
1950  *
1951  * Returns 0 on success.
1952  */
1953 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
1954                                  void __user *buffer, size_t *lenp)
1955 {
1956     return do_proc_dointvec(table,write,filp,buffer,lenp,
1957                             do_proc_dointvec_userhz_jiffies_conv,NULL);
1958 }
1959
1960 #else /* CONFIG_PROC_FS */
1961
1962 int proc_dostring(ctl_table *table, int write, struct file *filp,
1963                   void __user *buffer, size_t *lenp)
1964 {
1965         return -ENOSYS;
1966 }
1967
1968 static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
1969                             void __user *buffer, size_t *lenp)
1970 {
1971         return -ENOSYS;
1972 }
1973
1974 int proc_dointvec(ctl_table *table, int write, struct file *filp,
1975                   void __user *buffer, size_t *lenp)
1976 {
1977         return -ENOSYS;
1978 }
1979
1980 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
1981                         void __user *buffer, size_t *lenp)
1982 {
1983         return -ENOSYS;
1984 }
1985
1986 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
1987                     void __user *buffer, size_t *lenp)
1988 {
1989         return -ENOSYS;
1990 }
1991
1992 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
1993                     void __user *buffer, size_t *lenp)
1994 {
1995         return -ENOSYS;
1996 }
1997
1998 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
1999                     void __user *buffer, size_t *lenp)
2000 {
2001         return -ENOSYS;
2002 }
2003
2004 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
2005                     void __user *buffer, size_t *lenp)
2006 {
2007         return -ENOSYS;
2008 }
2009
2010 int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
2011                                       struct file *filp,
2012                                       void __user *buffer, size_t *lenp)
2013 {
2014     return -ENOSYS;
2015 }
2016
2017
2018 #endif /* CONFIG_PROC_FS */
2019
2020
2021 /*
2022  * General sysctl support routines 
2023  */
2024
2025 /* The generic string strategy routine: */
2026 int sysctl_string(ctl_table *table, int __user *name, int nlen,
2027                   void __user *oldval, size_t __user *oldlenp,
2028                   void __user *newval, size_t newlen, void **context)
2029 {
2030         size_t l, len;
2031         
2032         if (!table->data || !table->maxlen) 
2033                 return -ENOTDIR;
2034         
2035         if (oldval && oldlenp) {
2036                 if (get_user(len, oldlenp))
2037                         return -EFAULT;
2038                 if (len) {
2039                         l = strlen(table->data);
2040                         if (len > l) len = l;
2041                         if (len >= table->maxlen)
2042                                 len = table->maxlen;
2043                         if(copy_to_user(oldval, table->data, len))
2044                                 return -EFAULT;
2045                         if(put_user(0, ((char __user *) oldval) + len))
2046                                 return -EFAULT;
2047                         if(put_user(len, oldlenp))
2048                                 return -EFAULT;
2049                 }
2050         }
2051         if (newval && newlen) {
2052                 len = newlen;
2053                 if (len > table->maxlen)
2054                         len = table->maxlen;
2055                 if(copy_from_user(table->data, newval, len))
2056                         return -EFAULT;
2057                 if (len == table->maxlen)
2058                         len--;
2059                 ((char *) table->data)[len] = 0;
2060         }
2061         return 0;
2062 }
2063
2064 /*
2065  * This function makes sure that all of the integers in the vector
2066  * are between the minimum and maximum values given in the arrays
2067  * table->extra1 and table->extra2, respectively.
2068  */
2069 int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
2070                 void __user *oldval, size_t __user *oldlenp,
2071                 void __user *newval, size_t newlen, void **context)
2072 {
2073
2074         if (newval && newlen) {
2075                 int __user *vec = (int __user *) newval;
2076                 int *min = (int *) table->extra1;
2077                 int *max = (int *) table->extra2;
2078                 size_t length;
2079                 int i;
2080
2081                 if (newlen % sizeof(int) != 0)
2082                         return -EINVAL;
2083
2084                 if (!table->extra1 && !table->extra2)
2085                         return 0;
2086
2087                 if (newlen > table->maxlen)
2088                         newlen = table->maxlen;
2089                 length = newlen / sizeof(int);
2090
2091                 for (i = 0; i < length; i++) {
2092                         int value;
2093                         if (get_user(value, vec + i))
2094                                 return -EFAULT;
2095                         if (min && value < min[i])
2096                                 return -EINVAL;
2097                         if (max && value > max[i])
2098                                 return -EINVAL;
2099                 }
2100         }
2101         return 0;
2102 }
2103
2104 /* Strategy function to convert jiffies to seconds */ 
2105 int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
2106                 void __user *oldval, size_t __user *oldlenp,
2107                 void __user *newval, size_t newlen, void **context)
2108 {
2109         if (oldval) {
2110                 size_t olen;
2111                 if (oldlenp) { 
2112                         if (get_user(olen, oldlenp))
2113                                 return -EFAULT;
2114                         if (olen!=sizeof(int))
2115                                 return -EINVAL; 
2116                 }
2117                 if (put_user(*(int *)(table->data)/HZ, (int __user *)oldval) ||
2118                     (oldlenp && put_user(sizeof(int),oldlenp)))
2119                         return -EFAULT;
2120         }
2121         if (newval && newlen) { 
2122                 int new;
2123                 if (newlen != sizeof(int))
2124                         return -EINVAL; 
2125                 if (get_user(new, (int __user *)newval))
2126                         return -EFAULT;
2127                 *(int *)(table->data) = new*HZ; 
2128         }
2129         return 1;
2130 }
2131
2132
2133 #else /* CONFIG_SYSCTL */
2134
2135
2136 asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
2137 {
2138         return -ENOSYS;
2139 }
2140
2141 int sysctl_string(ctl_table *table, int __user *name, int nlen,
2142                   void __user *oldval, size_t __user *oldlenp,
2143                   void __user *newval, size_t newlen, void **context)
2144 {
2145         return -ENOSYS;
2146 }
2147
2148 int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
2149                 void __user *oldval, size_t __user *oldlenp,
2150                 void __user *newval, size_t newlen, void **context)
2151 {
2152         return -ENOSYS;
2153 }
2154
2155 int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
2156                 void __user *oldval, size_t __user *oldlenp,
2157                 void __user *newval, size_t newlen, void **context)
2158 {
2159         return -ENOSYS;
2160 }
2161
2162 int proc_dostring(ctl_table *table, int write, struct file *filp,
2163                   void __user *buffer, size_t *lenp)
2164 {
2165         return -ENOSYS;
2166 }
2167
2168 int proc_dointvec(ctl_table *table, int write, struct file *filp,
2169                   void __user *buffer, size_t *lenp)
2170 {
2171         return -ENOSYS;
2172 }
2173
2174 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
2175                         void __user *buffer, size_t *lenp)
2176 {
2177         return -ENOSYS;
2178 }
2179
2180 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
2181                     void __user *buffer, size_t *lenp)
2182 {
2183         return -ENOSYS;
2184 }
2185
2186 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
2187                           void __user *buffer, size_t *lenp)
2188 {
2189         return -ENOSYS;
2190 }
2191
2192 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
2193                           void __user *buffer, size_t *lenp)
2194 {
2195         return -ENOSYS;
2196 }
2197
2198 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
2199                     void __user *buffer, size_t *lenp)
2200 {
2201         return -ENOSYS;
2202 }
2203
2204 int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
2205                                       struct file *filp,
2206                                       void __user *buffer, size_t *lenp)
2207 {
2208     return -ENOSYS;
2209 }
2210
2211 struct ctl_table_header * register_sysctl_table(ctl_table * table, 
2212                                                 int insert_at_head)
2213 {
2214         return NULL;
2215 }
2216
2217 void unregister_sysctl_table(struct ctl_table_header * table)
2218 {
2219 }
2220
2221 #endif /* CONFIG_SYSCTL */
2222
2223 /*
2224  * No sense putting this after each symbol definition, twice,
2225  * exception granted :-)
2226  */
2227 EXPORT_SYMBOL(proc_dointvec);
2228 EXPORT_SYMBOL(proc_dointvec_jiffies);
2229 EXPORT_SYMBOL(proc_dointvec_minmax);
2230 EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
2231 EXPORT_SYMBOL(proc_dostring);
2232 EXPORT_SYMBOL(proc_doulongvec_minmax);
2233 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
2234 EXPORT_SYMBOL(register_sysctl_table);
2235 EXPORT_SYMBOL(sysctl_intvec);
2236 EXPORT_SYMBOL(sysctl_jiffies);
2237 EXPORT_SYMBOL(sysctl_string);
2238 EXPORT_SYMBOL(unregister_sysctl_table);