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