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