xref: /linux/kernel/sysctl.c (revision d67b569f5f620c0fb95d5212642746b7ba9d29e4)
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 		kfree(context);
1004 		if (error != -ENOTDIR)
1005 			return error;
1006 		tmp = tmp->next;
1007 	} while (tmp != &root_table_header.ctl_entry);
1008 	return -ENOTDIR;
1009 }
1010 
1011 asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
1012 {
1013 	struct __sysctl_args tmp;
1014 	int error;
1015 
1016 	if (copy_from_user(&tmp, args, sizeof(tmp)))
1017 		return -EFAULT;
1018 
1019 	lock_kernel();
1020 	error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
1021 			  tmp.newval, tmp.newlen);
1022 	unlock_kernel();
1023 	return error;
1024 }
1025 
1026 /*
1027  * ctl_perm does NOT grant the superuser all rights automatically, because
1028  * some sysctl variables are readonly even to root.
1029  */
1030 
1031 static int test_perm(int mode, int op)
1032 {
1033 	if (!current->euid)
1034 		mode >>= 6;
1035 	else if (in_egroup_p(0))
1036 		mode >>= 3;
1037 	if ((mode & op & 0007) == op)
1038 		return 0;
1039 	return -EACCES;
1040 }
1041 
1042 static inline int ctl_perm(ctl_table *table, int op)
1043 {
1044 	int error;
1045 	error = security_sysctl(table, op);
1046 	if (error)
1047 		return error;
1048 	return test_perm(table->mode, op);
1049 }
1050 
1051 static int parse_table(int __user *name, int nlen,
1052 		       void __user *oldval, size_t __user *oldlenp,
1053 		       void __user *newval, size_t newlen,
1054 		       ctl_table *table, void **context)
1055 {
1056 	int n;
1057 repeat:
1058 	if (!nlen)
1059 		return -ENOTDIR;
1060 	if (get_user(n, name))
1061 		return -EFAULT;
1062 	for ( ; table->ctl_name; table++) {
1063 		if (n == table->ctl_name || table->ctl_name == CTL_ANY) {
1064 			int error;
1065 			if (table->child) {
1066 				if (ctl_perm(table, 001))
1067 					return -EPERM;
1068 				if (table->strategy) {
1069 					error = table->strategy(
1070 						table, name, nlen,
1071 						oldval, oldlenp,
1072 						newval, newlen, context);
1073 					if (error)
1074 						return error;
1075 				}
1076 				name++;
1077 				nlen--;
1078 				table = table->child;
1079 				goto repeat;
1080 			}
1081 			error = do_sysctl_strategy(table, name, nlen,
1082 						   oldval, oldlenp,
1083 						   newval, newlen, context);
1084 			return error;
1085 		}
1086 	}
1087 	return -ENOTDIR;
1088 }
1089 
1090 /* Perform the actual read/write of a sysctl table entry. */
1091 int do_sysctl_strategy (ctl_table *table,
1092 			int __user *name, int nlen,
1093 			void __user *oldval, size_t __user *oldlenp,
1094 			void __user *newval, size_t newlen, void **context)
1095 {
1096 	int op = 0, rc;
1097 	size_t len;
1098 
1099 	if (oldval)
1100 		op |= 004;
1101 	if (newval)
1102 		op |= 002;
1103 	if (ctl_perm(table, op))
1104 		return -EPERM;
1105 
1106 	if (table->strategy) {
1107 		rc = table->strategy(table, name, nlen, oldval, oldlenp,
1108 				     newval, newlen, context);
1109 		if (rc < 0)
1110 			return rc;
1111 		if (rc > 0)
1112 			return 0;
1113 	}
1114 
1115 	/* If there is no strategy routine, or if the strategy returns
1116 	 * zero, proceed with automatic r/w */
1117 	if (table->data && table->maxlen) {
1118 		if (oldval && oldlenp) {
1119 			if (get_user(len, oldlenp))
1120 				return -EFAULT;
1121 			if (len) {
1122 				if (len > table->maxlen)
1123 					len = table->maxlen;
1124 				if(copy_to_user(oldval, table->data, len))
1125 					return -EFAULT;
1126 				if(put_user(len, oldlenp))
1127 					return -EFAULT;
1128 			}
1129 		}
1130 		if (newval && newlen) {
1131 			len = newlen;
1132 			if (len > table->maxlen)
1133 				len = table->maxlen;
1134 			if(copy_from_user(table->data, newval, len))
1135 				return -EFAULT;
1136 		}
1137 	}
1138 	return 0;
1139 }
1140 
1141 /**
1142  * register_sysctl_table - register a sysctl hierarchy
1143  * @table: the top-level table structure
1144  * @insert_at_head: whether the entry should be inserted in front or at the end
1145  *
1146  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
1147  * array. An entry with a ctl_name of 0 terminates the table.
1148  *
1149  * The members of the &ctl_table structure are used as follows:
1150  *
1151  * ctl_name - This is the numeric sysctl value used by sysctl(2). The number
1152  *            must be unique within that level of sysctl
1153  *
1154  * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
1155  *            enter a sysctl file
1156  *
1157  * data - a pointer to data for use by proc_handler
1158  *
1159  * maxlen - the maximum size in bytes of the data
1160  *
1161  * mode - the file permissions for the /proc/sys file, and for sysctl(2)
1162  *
1163  * child - a pointer to the child sysctl table if this entry is a directory, or
1164  *         %NULL.
1165  *
1166  * proc_handler - the text handler routine (described below)
1167  *
1168  * strategy - the strategy routine (described below)
1169  *
1170  * de - for internal use by the sysctl routines
1171  *
1172  * extra1, extra2 - extra pointers usable by the proc handler routines
1173  *
1174  * Leaf nodes in the sysctl tree will be represented by a single file
1175  * under /proc; non-leaf nodes will be represented by directories.
1176  *
1177  * sysctl(2) can automatically manage read and write requests through
1178  * the sysctl table.  The data and maxlen fields of the ctl_table
1179  * struct enable minimal validation of the values being written to be
1180  * performed, and the mode field allows minimal authentication.
1181  *
1182  * More sophisticated management can be enabled by the provision of a
1183  * strategy routine with the table entry.  This will be called before
1184  * any automatic read or write of the data is performed.
1185  *
1186  * The strategy routine may return
1187  *
1188  * < 0 - Error occurred (error is passed to user process)
1189  *
1190  * 0   - OK - proceed with automatic read or write.
1191  *
1192  * > 0 - OK - read or write has been done by the strategy routine, so
1193  *       return immediately.
1194  *
1195  * There must be a proc_handler routine for any terminal nodes
1196  * mirrored under /proc/sys (non-terminals are handled by a built-in
1197  * directory handler).  Several default handlers are available to
1198  * cover common cases -
1199  *
1200  * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
1201  * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(),
1202  * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax()
1203  *
1204  * It is the handler's job to read the input buffer from user memory
1205  * and process it. The handler should return 0 on success.
1206  *
1207  * This routine returns %NULL on a failure to register, and a pointer
1208  * to the table header on success.
1209  */
1210 struct ctl_table_header *register_sysctl_table(ctl_table * table,
1211 					       int insert_at_head)
1212 {
1213 	struct ctl_table_header *tmp;
1214 	tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
1215 	if (!tmp)
1216 		return NULL;
1217 	tmp->ctl_table = table;
1218 	INIT_LIST_HEAD(&tmp->ctl_entry);
1219 	if (insert_at_head)
1220 		list_add(&tmp->ctl_entry, &root_table_header.ctl_entry);
1221 	else
1222 		list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
1223 #ifdef CONFIG_PROC_FS
1224 	register_proc_table(table, proc_sys_root);
1225 #endif
1226 	return tmp;
1227 }
1228 
1229 /**
1230  * unregister_sysctl_table - unregister a sysctl table hierarchy
1231  * @header: the header returned from register_sysctl_table
1232  *
1233  * Unregisters the sysctl table and all children. proc entries may not
1234  * actually be removed until they are no longer used by anyone.
1235  */
1236 void unregister_sysctl_table(struct ctl_table_header * header)
1237 {
1238 	list_del(&header->ctl_entry);
1239 #ifdef CONFIG_PROC_FS
1240 	unregister_proc_table(header->ctl_table, proc_sys_root);
1241 #endif
1242 	kfree(header);
1243 }
1244 
1245 /*
1246  * /proc/sys support
1247  */
1248 
1249 #ifdef CONFIG_PROC_FS
1250 
1251 /* Scan the sysctl entries in table and add them all into /proc */
1252 static void register_proc_table(ctl_table * table, struct proc_dir_entry *root)
1253 {
1254 	struct proc_dir_entry *de;
1255 	int len;
1256 	mode_t mode;
1257 
1258 	for (; table->ctl_name; table++) {
1259 		/* Can't do anything without a proc name. */
1260 		if (!table->procname)
1261 			continue;
1262 		/* Maybe we can't do anything with it... */
1263 		if (!table->proc_handler && !table->child) {
1264 			printk(KERN_WARNING "SYSCTL: Can't register %s\n",
1265 				table->procname);
1266 			continue;
1267 		}
1268 
1269 		len = strlen(table->procname);
1270 		mode = table->mode;
1271 
1272 		de = NULL;
1273 		if (table->proc_handler)
1274 			mode |= S_IFREG;
1275 		else {
1276 			mode |= S_IFDIR;
1277 			for (de = root->subdir; de; de = de->next) {
1278 				if (proc_match(len, table->procname, de))
1279 					break;
1280 			}
1281 			/* If the subdir exists already, de is non-NULL */
1282 		}
1283 
1284 		if (!de) {
1285 			de = create_proc_entry(table->procname, mode, root);
1286 			if (!de)
1287 				continue;
1288 			de->data = (void *) table;
1289 			if (table->proc_handler)
1290 				de->proc_fops = &proc_sys_file_operations;
1291 		}
1292 		table->de = de;
1293 		if (de->mode & S_IFDIR)
1294 			register_proc_table(table->child, de);
1295 	}
1296 }
1297 
1298 /*
1299  * Unregister a /proc sysctl table and any subdirectories.
1300  */
1301 static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root)
1302 {
1303 	struct proc_dir_entry *de;
1304 	for (; table->ctl_name; table++) {
1305 		if (!(de = table->de))
1306 			continue;
1307 		if (de->mode & S_IFDIR) {
1308 			if (!table->child) {
1309 				printk (KERN_ALERT "Help - malformed sysctl tree on free\n");
1310 				continue;
1311 			}
1312 			unregister_proc_table(table->child, de);
1313 
1314 			/* Don't unregister directories which still have entries.. */
1315 			if (de->subdir)
1316 				continue;
1317 		}
1318 
1319 		/* Don't unregister proc entries that are still being used.. */
1320 		if (atomic_read(&de->count))
1321 			continue;
1322 
1323 		table->de = NULL;
1324 		remove_proc_entry(table->procname, root);
1325 	}
1326 }
1327 
1328 static ssize_t do_rw_proc(int write, struct file * file, char __user * buf,
1329 			  size_t count, loff_t *ppos)
1330 {
1331 	int op;
1332 	struct proc_dir_entry *de;
1333 	struct ctl_table *table;
1334 	size_t res;
1335 	ssize_t error;
1336 
1337 	de = PDE(file->f_dentry->d_inode);
1338 	if (!de || !de->data)
1339 		return -ENOTDIR;
1340 	table = (struct ctl_table *) de->data;
1341 	if (!table || !table->proc_handler)
1342 		return -ENOTDIR;
1343 	op = (write ? 002 : 004);
1344 	if (ctl_perm(table, op))
1345 		return -EPERM;
1346 
1347 	res = count;
1348 
1349 	error = (*table->proc_handler) (table, write, file, buf, &res, ppos);
1350 	if (error)
1351 		return error;
1352 	return res;
1353 }
1354 
1355 static int proc_opensys(struct inode *inode, struct file *file)
1356 {
1357 	if (file->f_mode & FMODE_WRITE) {
1358 		/*
1359 		 * sysctl entries that are not writable,
1360 		 * are _NOT_ writable, capabilities or not.
1361 		 */
1362 		if (!(inode->i_mode & S_IWUSR))
1363 			return -EPERM;
1364 	}
1365 
1366 	return 0;
1367 }
1368 
1369 static ssize_t proc_readsys(struct file * file, char __user * buf,
1370 			    size_t count, loff_t *ppos)
1371 {
1372 	return do_rw_proc(0, file, buf, count, ppos);
1373 }
1374 
1375 static ssize_t proc_writesys(struct file * file, const char __user * buf,
1376 			     size_t count, loff_t *ppos)
1377 {
1378 	return do_rw_proc(1, file, (char __user *) buf, count, ppos);
1379 }
1380 
1381 /**
1382  * proc_dostring - read a string sysctl
1383  * @table: the sysctl table
1384  * @write: %TRUE if this is a write to the sysctl file
1385  * @filp: the file structure
1386  * @buffer: the user buffer
1387  * @lenp: the size of the user buffer
1388  * @ppos: file position
1389  *
1390  * Reads/writes a string from/to the user buffer. If the kernel
1391  * buffer provided is not large enough to hold the string, the
1392  * string is truncated. The copied string is %NULL-terminated.
1393  * If the string is being read by the user process, it is copied
1394  * and a newline '\n' is added. It is truncated if the buffer is
1395  * not large enough.
1396  *
1397  * Returns 0 on success.
1398  */
1399 int proc_dostring(ctl_table *table, int write, struct file *filp,
1400 		  void __user *buffer, size_t *lenp, loff_t *ppos)
1401 {
1402 	size_t len;
1403 	char __user *p;
1404 	char c;
1405 
1406 	if (!table->data || !table->maxlen || !*lenp ||
1407 	    (*ppos && !write)) {
1408 		*lenp = 0;
1409 		return 0;
1410 	}
1411 
1412 	if (write) {
1413 		len = 0;
1414 		p = buffer;
1415 		while (len < *lenp) {
1416 			if (get_user(c, p++))
1417 				return -EFAULT;
1418 			if (c == 0 || c == '\n')
1419 				break;
1420 			len++;
1421 		}
1422 		if (len >= table->maxlen)
1423 			len = table->maxlen-1;
1424 		if(copy_from_user(table->data, buffer, len))
1425 			return -EFAULT;
1426 		((char *) table->data)[len] = 0;
1427 		*ppos += *lenp;
1428 	} else {
1429 		len = strlen(table->data);
1430 		if (len > table->maxlen)
1431 			len = table->maxlen;
1432 		if (len > *lenp)
1433 			len = *lenp;
1434 		if (len)
1435 			if(copy_to_user(buffer, table->data, len))
1436 				return -EFAULT;
1437 		if (len < *lenp) {
1438 			if(put_user('\n', ((char __user *) buffer) + len))
1439 				return -EFAULT;
1440 			len++;
1441 		}
1442 		*lenp = len;
1443 		*ppos += len;
1444 	}
1445 	return 0;
1446 }
1447 
1448 /*
1449  *	Special case of dostring for the UTS structure. This has locks
1450  *	to observe. Should this be in kernel/sys.c ????
1451  */
1452 
1453 static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
1454 		  void __user *buffer, size_t *lenp, loff_t *ppos)
1455 {
1456 	int r;
1457 
1458 	if (!write) {
1459 		down_read(&uts_sem);
1460 		r=proc_dostring(table,0,filp,buffer,lenp, ppos);
1461 		up_read(&uts_sem);
1462 	} else {
1463 		down_write(&uts_sem);
1464 		r=proc_dostring(table,1,filp,buffer,lenp, ppos);
1465 		up_write(&uts_sem);
1466 	}
1467 	return r;
1468 }
1469 
1470 static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
1471 				 int *valp,
1472 				 int write, void *data)
1473 {
1474 	if (write) {
1475 		*valp = *negp ? -*lvalp : *lvalp;
1476 	} else {
1477 		int val = *valp;
1478 		if (val < 0) {
1479 			*negp = -1;
1480 			*lvalp = (unsigned long)-val;
1481 		} else {
1482 			*negp = 0;
1483 			*lvalp = (unsigned long)val;
1484 		}
1485 	}
1486 	return 0;
1487 }
1488 
1489 static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
1490 		  void __user *buffer, size_t *lenp, loff_t *ppos,
1491 		  int (*conv)(int *negp, unsigned long *lvalp, int *valp,
1492 			      int write, void *data),
1493 		  void *data)
1494 {
1495 #define TMPBUFLEN 21
1496 	int *i, vleft, first=1, neg, val;
1497 	unsigned long lval;
1498 	size_t left, len;
1499 
1500 	char buf[TMPBUFLEN], *p;
1501 	char __user *s = buffer;
1502 
1503 	if (!table->data || !table->maxlen || !*lenp ||
1504 	    (*ppos && !write)) {
1505 		*lenp = 0;
1506 		return 0;
1507 	}
1508 
1509 	i = (int *) table->data;
1510 	vleft = table->maxlen / sizeof(*i);
1511 	left = *lenp;
1512 
1513 	if (!conv)
1514 		conv = do_proc_dointvec_conv;
1515 
1516 	for (; left && vleft--; i++, first=0) {
1517 		if (write) {
1518 			while (left) {
1519 				char c;
1520 				if (get_user(c, s))
1521 					return -EFAULT;
1522 				if (!isspace(c))
1523 					break;
1524 				left--;
1525 				s++;
1526 			}
1527 			if (!left)
1528 				break;
1529 			neg = 0;
1530 			len = left;
1531 			if (len > sizeof(buf) - 1)
1532 				len = sizeof(buf) - 1;
1533 			if (copy_from_user(buf, s, len))
1534 				return -EFAULT;
1535 			buf[len] = 0;
1536 			p = buf;
1537 			if (*p == '-' && left > 1) {
1538 				neg = 1;
1539 				left--, p++;
1540 			}
1541 			if (*p < '0' || *p > '9')
1542 				break;
1543 
1544 			lval = simple_strtoul(p, &p, 0);
1545 
1546 			len = p-buf;
1547 			if ((len < left) && *p && !isspace(*p))
1548 				break;
1549 			if (neg)
1550 				val = -val;
1551 			s += len;
1552 			left -= len;
1553 
1554 			if (conv(&neg, &lval, i, 1, data))
1555 				break;
1556 		} else {
1557 			p = buf;
1558 			if (!first)
1559 				*p++ = '\t';
1560 
1561 			if (conv(&neg, &lval, i, 0, data))
1562 				break;
1563 
1564 			sprintf(p, "%s%lu", neg ? "-" : "", lval);
1565 			len = strlen(buf);
1566 			if (len > left)
1567 				len = left;
1568 			if(copy_to_user(s, buf, len))
1569 				return -EFAULT;
1570 			left -= len;
1571 			s += len;
1572 		}
1573 	}
1574 
1575 	if (!write && !first && left) {
1576 		if(put_user('\n', s))
1577 			return -EFAULT;
1578 		left--, s++;
1579 	}
1580 	if (write) {
1581 		while (left) {
1582 			char c;
1583 			if (get_user(c, s++))
1584 				return -EFAULT;
1585 			if (!isspace(c))
1586 				break;
1587 			left--;
1588 		}
1589 	}
1590 	if (write && first)
1591 		return -EINVAL;
1592 	*lenp -= left;
1593 	*ppos += *lenp;
1594 	return 0;
1595 #undef TMPBUFLEN
1596 }
1597 
1598 /**
1599  * proc_dointvec - read a vector of integers
1600  * @table: the sysctl table
1601  * @write: %TRUE if this is a write to the sysctl file
1602  * @filp: the file structure
1603  * @buffer: the user buffer
1604  * @lenp: the size of the user buffer
1605  * @ppos: file position
1606  *
1607  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1608  * values from/to the user buffer, treated as an ASCII string.
1609  *
1610  * Returns 0 on success.
1611  */
1612 int proc_dointvec(ctl_table *table, int write, struct file *filp,
1613 		     void __user *buffer, size_t *lenp, loff_t *ppos)
1614 {
1615     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
1616 		    	    NULL,NULL);
1617 }
1618 
1619 #define OP_SET	0
1620 #define OP_AND	1
1621 #define OP_OR	2
1622 #define OP_MAX	3
1623 #define OP_MIN	4
1624 
1625 static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
1626 				      int *valp,
1627 				      int write, void *data)
1628 {
1629 	int op = *(int *)data;
1630 	if (write) {
1631 		int val = *negp ? -*lvalp : *lvalp;
1632 		switch(op) {
1633 		case OP_SET:	*valp = val; break;
1634 		case OP_AND:	*valp &= val; break;
1635 		case OP_OR:	*valp |= val; break;
1636 		case OP_MAX:	if(*valp < val)
1637 					*valp = val;
1638 				break;
1639 		case OP_MIN:	if(*valp > val)
1640 				*valp = val;
1641 				break;
1642 		}
1643 	} else {
1644 		int val = *valp;
1645 		if (val < 0) {
1646 			*negp = -1;
1647 			*lvalp = (unsigned long)-val;
1648 		} else {
1649 			*negp = 0;
1650 			*lvalp = (unsigned long)val;
1651 		}
1652 	}
1653 	return 0;
1654 }
1655 
1656 /*
1657  *	init may raise the set.
1658  */
1659 
1660 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
1661 			void __user *buffer, size_t *lenp, loff_t *ppos)
1662 {
1663 	int op;
1664 
1665 	if (!capable(CAP_SYS_MODULE)) {
1666 		return -EPERM;
1667 	}
1668 
1669 	op = (current->pid == 1) ? OP_SET : OP_AND;
1670 	return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
1671 				do_proc_dointvec_bset_conv,&op);
1672 }
1673 
1674 struct do_proc_dointvec_minmax_conv_param {
1675 	int *min;
1676 	int *max;
1677 };
1678 
1679 static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,
1680 					int *valp,
1681 					int write, void *data)
1682 {
1683 	struct do_proc_dointvec_minmax_conv_param *param = data;
1684 	if (write) {
1685 		int val = *negp ? -*lvalp : *lvalp;
1686 		if ((param->min && *param->min > val) ||
1687 		    (param->max && *param->max < val))
1688 			return -EINVAL;
1689 		*valp = val;
1690 	} else {
1691 		int val = *valp;
1692 		if (val < 0) {
1693 			*negp = -1;
1694 			*lvalp = (unsigned long)-val;
1695 		} else {
1696 			*negp = 0;
1697 			*lvalp = (unsigned long)val;
1698 		}
1699 	}
1700 	return 0;
1701 }
1702 
1703 /**
1704  * proc_dointvec_minmax - read a vector of integers with min/max values
1705  * @table: the sysctl table
1706  * @write: %TRUE if this is a write to the sysctl file
1707  * @filp: the file structure
1708  * @buffer: the user buffer
1709  * @lenp: the size of the user buffer
1710  * @ppos: file position
1711  *
1712  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1713  * values from/to the user buffer, treated as an ASCII string.
1714  *
1715  * This routine will ensure the values are within the range specified by
1716  * table->extra1 (min) and table->extra2 (max).
1717  *
1718  * Returns 0 on success.
1719  */
1720 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
1721 		  void __user *buffer, size_t *lenp, loff_t *ppos)
1722 {
1723 	struct do_proc_dointvec_minmax_conv_param param = {
1724 		.min = (int *) table->extra1,
1725 		.max = (int *) table->extra2,
1726 	};
1727 	return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
1728 				do_proc_dointvec_minmax_conv, &param);
1729 }
1730 
1731 static int do_proc_doulongvec_minmax(ctl_table *table, int write,
1732 				     struct file *filp,
1733 				     void __user *buffer,
1734 				     size_t *lenp, loff_t *ppos,
1735 				     unsigned long convmul,
1736 				     unsigned long convdiv)
1737 {
1738 #define TMPBUFLEN 21
1739 	unsigned long *i, *min, *max, val;
1740 	int vleft, first=1, neg;
1741 	size_t len, left;
1742 	char buf[TMPBUFLEN], *p;
1743 	char __user *s = buffer;
1744 
1745 	if (!table->data || !table->maxlen || !*lenp ||
1746 	    (*ppos && !write)) {
1747 		*lenp = 0;
1748 		return 0;
1749 	}
1750 
1751 	i = (unsigned long *) table->data;
1752 	min = (unsigned long *) table->extra1;
1753 	max = (unsigned long *) table->extra2;
1754 	vleft = table->maxlen / sizeof(unsigned long);
1755 	left = *lenp;
1756 
1757 	for (; left && vleft--; i++, min++, max++, first=0) {
1758 		if (write) {
1759 			while (left) {
1760 				char c;
1761 				if (get_user(c, s))
1762 					return -EFAULT;
1763 				if (!isspace(c))
1764 					break;
1765 				left--;
1766 				s++;
1767 			}
1768 			if (!left)
1769 				break;
1770 			neg = 0;
1771 			len = left;
1772 			if (len > TMPBUFLEN-1)
1773 				len = TMPBUFLEN-1;
1774 			if (copy_from_user(buf, s, len))
1775 				return -EFAULT;
1776 			buf[len] = 0;
1777 			p = buf;
1778 			if (*p == '-' && left > 1) {
1779 				neg = 1;
1780 				left--, p++;
1781 			}
1782 			if (*p < '0' || *p > '9')
1783 				break;
1784 			val = simple_strtoul(p, &p, 0) * convmul / convdiv ;
1785 			len = p-buf;
1786 			if ((len < left) && *p && !isspace(*p))
1787 				break;
1788 			if (neg)
1789 				val = -val;
1790 			s += len;
1791 			left -= len;
1792 
1793 			if(neg)
1794 				continue;
1795 			if ((min && val < *min) || (max && val > *max))
1796 				continue;
1797 			*i = val;
1798 		} else {
1799 			p = buf;
1800 			if (!first)
1801 				*p++ = '\t';
1802 			sprintf(p, "%lu", convdiv * (*i) / convmul);
1803 			len = strlen(buf);
1804 			if (len > left)
1805 				len = left;
1806 			if(copy_to_user(s, buf, len))
1807 				return -EFAULT;
1808 			left -= len;
1809 			s += len;
1810 		}
1811 	}
1812 
1813 	if (!write && !first && left) {
1814 		if(put_user('\n', s))
1815 			return -EFAULT;
1816 		left--, s++;
1817 	}
1818 	if (write) {
1819 		while (left) {
1820 			char c;
1821 			if (get_user(c, s++))
1822 				return -EFAULT;
1823 			if (!isspace(c))
1824 				break;
1825 			left--;
1826 		}
1827 	}
1828 	if (write && first)
1829 		return -EINVAL;
1830 	*lenp -= left;
1831 	*ppos += *lenp;
1832 	return 0;
1833 #undef TMPBUFLEN
1834 }
1835 
1836 /**
1837  * proc_doulongvec_minmax - read a vector of long integers with min/max values
1838  * @table: the sysctl table
1839  * @write: %TRUE if this is a write to the sysctl file
1840  * @filp: the file structure
1841  * @buffer: the user buffer
1842  * @lenp: the size of the user buffer
1843  * @ppos: file position
1844  *
1845  * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
1846  * values from/to the user buffer, treated as an ASCII string.
1847  *
1848  * This routine will ensure the values are within the range specified by
1849  * table->extra1 (min) and table->extra2 (max).
1850  *
1851  * Returns 0 on success.
1852  */
1853 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
1854 			   void __user *buffer, size_t *lenp, loff_t *ppos)
1855 {
1856     return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l);
1857 }
1858 
1859 /**
1860  * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
1861  * @table: the sysctl table
1862  * @write: %TRUE if this is a write to the sysctl file
1863  * @filp: the file structure
1864  * @buffer: the user buffer
1865  * @lenp: the size of the user buffer
1866  * @ppos: file position
1867  *
1868  * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
1869  * values from/to the user buffer, treated as an ASCII string. The values
1870  * are treated as milliseconds, and converted to jiffies when they are stored.
1871  *
1872  * This routine will ensure the values are within the range specified by
1873  * table->extra1 (min) and table->extra2 (max).
1874  *
1875  * Returns 0 on success.
1876  */
1877 int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
1878 				      struct file *filp,
1879 				      void __user *buffer,
1880 				      size_t *lenp, loff_t *ppos)
1881 {
1882     return do_proc_doulongvec_minmax(table, write, filp, buffer,
1883 				     lenp, ppos, HZ, 1000l);
1884 }
1885 
1886 
1887 static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp,
1888 					 int *valp,
1889 					 int write, void *data)
1890 {
1891 	if (write) {
1892 		*valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ);
1893 	} else {
1894 		int val = *valp;
1895 		unsigned long lval;
1896 		if (val < 0) {
1897 			*negp = -1;
1898 			lval = (unsigned long)-val;
1899 		} else {
1900 			*negp = 0;
1901 			lval = (unsigned long)val;
1902 		}
1903 		*lvalp = lval / HZ;
1904 	}
1905 	return 0;
1906 }
1907 
1908 static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp,
1909 						int *valp,
1910 						int write, void *data)
1911 {
1912 	if (write) {
1913 		*valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp);
1914 	} else {
1915 		int val = *valp;
1916 		unsigned long lval;
1917 		if (val < 0) {
1918 			*negp = -1;
1919 			lval = (unsigned long)-val;
1920 		} else {
1921 			*negp = 0;
1922 			lval = (unsigned long)val;
1923 		}
1924 		*lvalp = jiffies_to_clock_t(lval);
1925 	}
1926 	return 0;
1927 }
1928 
1929 static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,
1930 					    int *valp,
1931 					    int write, void *data)
1932 {
1933 	if (write) {
1934 		*valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp);
1935 	} else {
1936 		int val = *valp;
1937 		unsigned long lval;
1938 		if (val < 0) {
1939 			*negp = -1;
1940 			lval = (unsigned long)-val;
1941 		} else {
1942 			*negp = 0;
1943 			lval = (unsigned long)val;
1944 		}
1945 		*lvalp = jiffies_to_msecs(lval);
1946 	}
1947 	return 0;
1948 }
1949 
1950 /**
1951  * proc_dointvec_jiffies - read a vector of integers as seconds
1952  * @table: the sysctl table
1953  * @write: %TRUE if this is a write to the sysctl file
1954  * @filp: the file structure
1955  * @buffer: the user buffer
1956  * @lenp: the size of the user buffer
1957  * @ppos: file position
1958  *
1959  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1960  * values from/to the user buffer, treated as an ASCII string.
1961  * The values read are assumed to be in seconds, and are converted into
1962  * jiffies.
1963  *
1964  * Returns 0 on success.
1965  */
1966 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
1967 			  void __user *buffer, size_t *lenp, loff_t *ppos)
1968 {
1969     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
1970 		    	    do_proc_dointvec_jiffies_conv,NULL);
1971 }
1972 
1973 /**
1974  * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
1975  * @table: the sysctl table
1976  * @write: %TRUE if this is a write to the sysctl file
1977  * @filp: the file structure
1978  * @buffer: the user buffer
1979  * @lenp: the size of the user buffer
1980  *
1981  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1982  * values from/to the user buffer, treated as an ASCII string.
1983  * The values read are assumed to be in 1/USER_HZ seconds, and
1984  * are converted into jiffies.
1985  *
1986  * Returns 0 on success.
1987  */
1988 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
1989 				 void __user *buffer, size_t *lenp, loff_t *ppos)
1990 {
1991     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
1992 		    	    do_proc_dointvec_userhz_jiffies_conv,NULL);
1993 }
1994 
1995 /**
1996  * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds
1997  * @table: the sysctl table
1998  * @write: %TRUE if this is a write to the sysctl file
1999  * @filp: the file structure
2000  * @buffer: the user buffer
2001  * @lenp: the size of the user buffer
2002  * @ppos: file position
2003  * @ppos: the current position in the file
2004  *
2005  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2006  * values from/to the user buffer, treated as an ASCII string.
2007  * The values read are assumed to be in 1/1000 seconds, and
2008  * are converted into jiffies.
2009  *
2010  * Returns 0 on success.
2011  */
2012 int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
2013 			     void __user *buffer, size_t *lenp, loff_t *ppos)
2014 {
2015 	return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
2016 				do_proc_dointvec_ms_jiffies_conv, NULL);
2017 }
2018 
2019 #else /* CONFIG_PROC_FS */
2020 
2021 int proc_dostring(ctl_table *table, int write, struct file *filp,
2022 		  void __user *buffer, size_t *lenp, loff_t *ppos)
2023 {
2024 	return -ENOSYS;
2025 }
2026 
2027 static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
2028 			    void __user *buffer, size_t *lenp, loff_t *ppos)
2029 {
2030 	return -ENOSYS;
2031 }
2032 
2033 int proc_dointvec(ctl_table *table, int write, struct file *filp,
2034 		  void __user *buffer, size_t *lenp, loff_t *ppos)
2035 {
2036 	return -ENOSYS;
2037 }
2038 
2039 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
2040 			void __user *buffer, size_t *lenp, loff_t *ppos)
2041 {
2042 	return -ENOSYS;
2043 }
2044 
2045 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
2046 		    void __user *buffer, size_t *lenp, loff_t *ppos)
2047 {
2048 	return -ENOSYS;
2049 }
2050 
2051 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
2052 		    void __user *buffer, size_t *lenp, loff_t *ppos)
2053 {
2054 	return -ENOSYS;
2055 }
2056 
2057 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
2058 		    void __user *buffer, size_t *lenp, loff_t *ppos)
2059 {
2060 	return -ENOSYS;
2061 }
2062 
2063 int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
2064 			     void __user *buffer, size_t *lenp, loff_t *ppos)
2065 {
2066 	return -ENOSYS;
2067 }
2068 
2069 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
2070 		    void __user *buffer, size_t *lenp, loff_t *ppos)
2071 {
2072 	return -ENOSYS;
2073 }
2074 
2075 int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
2076 				      struct file *filp,
2077 				      void __user *buffer,
2078 				      size_t *lenp, loff_t *ppos)
2079 {
2080     return -ENOSYS;
2081 }
2082 
2083 
2084 #endif /* CONFIG_PROC_FS */
2085 
2086 
2087 /*
2088  * General sysctl support routines
2089  */
2090 
2091 /* The generic string strategy routine: */
2092 int sysctl_string(ctl_table *table, int __user *name, int nlen,
2093 		  void __user *oldval, size_t __user *oldlenp,
2094 		  void __user *newval, size_t newlen, void **context)
2095 {
2096 	size_t l, len;
2097 
2098 	if (!table->data || !table->maxlen)
2099 		return -ENOTDIR;
2100 
2101 	if (oldval && oldlenp) {
2102 		if (get_user(len, oldlenp))
2103 			return -EFAULT;
2104 		if (len) {
2105 			l = strlen(table->data);
2106 			if (len > l) len = l;
2107 			if (len >= table->maxlen)
2108 				len = table->maxlen;
2109 			if(copy_to_user(oldval, table->data, len))
2110 				return -EFAULT;
2111 			if(put_user(0, ((char __user *) oldval) + len))
2112 				return -EFAULT;
2113 			if(put_user(len, oldlenp))
2114 				return -EFAULT;
2115 		}
2116 	}
2117 	if (newval && newlen) {
2118 		len = newlen;
2119 		if (len > table->maxlen)
2120 			len = table->maxlen;
2121 		if(copy_from_user(table->data, newval, len))
2122 			return -EFAULT;
2123 		if (len == table->maxlen)
2124 			len--;
2125 		((char *) table->data)[len] = 0;
2126 	}
2127 	return 0;
2128 }
2129 
2130 /*
2131  * This function makes sure that all of the integers in the vector
2132  * are between the minimum and maximum values given in the arrays
2133  * table->extra1 and table->extra2, respectively.
2134  */
2135 int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
2136 		void __user *oldval, size_t __user *oldlenp,
2137 		void __user *newval, size_t newlen, void **context)
2138 {
2139 
2140 	if (newval && newlen) {
2141 		int __user *vec = (int __user *) newval;
2142 		int *min = (int *) table->extra1;
2143 		int *max = (int *) table->extra2;
2144 		size_t length;
2145 		int i;
2146 
2147 		if (newlen % sizeof(int) != 0)
2148 			return -EINVAL;
2149 
2150 		if (!table->extra1 && !table->extra2)
2151 			return 0;
2152 
2153 		if (newlen > table->maxlen)
2154 			newlen = table->maxlen;
2155 		length = newlen / sizeof(int);
2156 
2157 		for (i = 0; i < length; i++) {
2158 			int value;
2159 			if (get_user(value, vec + i))
2160 				return -EFAULT;
2161 			if (min && value < min[i])
2162 				return -EINVAL;
2163 			if (max && value > max[i])
2164 				return -EINVAL;
2165 		}
2166 	}
2167 	return 0;
2168 }
2169 
2170 /* Strategy function to convert jiffies to seconds */
2171 int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
2172 		void __user *oldval, size_t __user *oldlenp,
2173 		void __user *newval, size_t newlen, void **context)
2174 {
2175 	if (oldval) {
2176 		size_t olen;
2177 		if (oldlenp) {
2178 			if (get_user(olen, oldlenp))
2179 				return -EFAULT;
2180 			if (olen!=sizeof(int))
2181 				return -EINVAL;
2182 		}
2183 		if (put_user(*(int *)(table->data)/HZ, (int __user *)oldval) ||
2184 		    (oldlenp && put_user(sizeof(int),oldlenp)))
2185 			return -EFAULT;
2186 	}
2187 	if (newval && newlen) {
2188 		int new;
2189 		if (newlen != sizeof(int))
2190 			return -EINVAL;
2191 		if (get_user(new, (int __user *)newval))
2192 			return -EFAULT;
2193 		*(int *)(table->data) = new*HZ;
2194 	}
2195 	return 1;
2196 }
2197 
2198 /* Strategy function to convert jiffies to seconds */
2199 int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
2200 		void __user *oldval, size_t __user *oldlenp,
2201 		void __user *newval, size_t newlen, void **context)
2202 {
2203 	if (oldval) {
2204 		size_t olen;
2205 		if (oldlenp) {
2206 			if (get_user(olen, oldlenp))
2207 				return -EFAULT;
2208 			if (olen!=sizeof(int))
2209 				return -EINVAL;
2210 		}
2211 		if (put_user(jiffies_to_msecs(*(int *)(table->data)), (int __user *)oldval) ||
2212 		    (oldlenp && put_user(sizeof(int),oldlenp)))
2213 			return -EFAULT;
2214 	}
2215 	if (newval && newlen) {
2216 		int new;
2217 		if (newlen != sizeof(int))
2218 			return -EINVAL;
2219 		if (get_user(new, (int __user *)newval))
2220 			return -EFAULT;
2221 		*(int *)(table->data) = msecs_to_jiffies(new);
2222 	}
2223 	return 1;
2224 }
2225 
2226 #else /* CONFIG_SYSCTL */
2227 
2228 
2229 asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
2230 {
2231 	return -ENOSYS;
2232 }
2233 
2234 int sysctl_string(ctl_table *table, int __user *name, int nlen,
2235 		  void __user *oldval, size_t __user *oldlenp,
2236 		  void __user *newval, size_t newlen, void **context)
2237 {
2238 	return -ENOSYS;
2239 }
2240 
2241 int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
2242 		void __user *oldval, size_t __user *oldlenp,
2243 		void __user *newval, size_t newlen, void **context)
2244 {
2245 	return -ENOSYS;
2246 }
2247 
2248 int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
2249 		void __user *oldval, size_t __user *oldlenp,
2250 		void __user *newval, size_t newlen, void **context)
2251 {
2252 	return -ENOSYS;
2253 }
2254 
2255 int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
2256 		void __user *oldval, size_t __user *oldlenp,
2257 		void __user *newval, size_t newlen, void **context)
2258 {
2259 	return -ENOSYS;
2260 }
2261 
2262 int proc_dostring(ctl_table *table, int write, struct file *filp,
2263 		  void __user *buffer, size_t *lenp, loff_t *ppos)
2264 {
2265 	return -ENOSYS;
2266 }
2267 
2268 int proc_dointvec(ctl_table *table, int write, struct file *filp,
2269 		  void __user *buffer, size_t *lenp, loff_t *ppos)
2270 {
2271 	return -ENOSYS;
2272 }
2273 
2274 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
2275 			void __user *buffer, size_t *lenp, loff_t *ppos)
2276 {
2277 	return -ENOSYS;
2278 }
2279 
2280 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
2281 		    void __user *buffer, size_t *lenp, loff_t *ppos)
2282 {
2283 	return -ENOSYS;
2284 }
2285 
2286 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
2287 			  void __user *buffer, size_t *lenp, loff_t *ppos)
2288 {
2289 	return -ENOSYS;
2290 }
2291 
2292 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
2293 			  void __user *buffer, size_t *lenp, loff_t *ppos)
2294 {
2295 	return -ENOSYS;
2296 }
2297 
2298 int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
2299 			     void __user *buffer, size_t *lenp, loff_t *ppos)
2300 {
2301 	return -ENOSYS;
2302 }
2303 
2304 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
2305 		    void __user *buffer, size_t *lenp, loff_t *ppos)
2306 {
2307 	return -ENOSYS;
2308 }
2309 
2310 int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
2311 				      struct file *filp,
2312 				      void __user *buffer,
2313 				      size_t *lenp, loff_t *ppos)
2314 {
2315     return -ENOSYS;
2316 }
2317 
2318 struct ctl_table_header * register_sysctl_table(ctl_table * table,
2319 						int insert_at_head)
2320 {
2321 	return NULL;
2322 }
2323 
2324 void unregister_sysctl_table(struct ctl_table_header * table)
2325 {
2326 }
2327 
2328 #endif /* CONFIG_SYSCTL */
2329 
2330 /*
2331  * No sense putting this after each symbol definition, twice,
2332  * exception granted :-)
2333  */
2334 EXPORT_SYMBOL(proc_dointvec);
2335 EXPORT_SYMBOL(proc_dointvec_jiffies);
2336 EXPORT_SYMBOL(proc_dointvec_minmax);
2337 EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
2338 EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
2339 EXPORT_SYMBOL(proc_dostring);
2340 EXPORT_SYMBOL(proc_doulongvec_minmax);
2341 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
2342 EXPORT_SYMBOL(register_sysctl_table);
2343 EXPORT_SYMBOL(sysctl_intvec);
2344 EXPORT_SYMBOL(sysctl_jiffies);
2345 EXPORT_SYMBOL(sysctl_ms_jiffies);
2346 EXPORT_SYMBOL(sysctl_string);
2347 EXPORT_SYMBOL(unregister_sysctl_table);
2348