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