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, ¶m); 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