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