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