linux/kernel/sysctl.c
<<
>>
Prefs
   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/module.h>
  22#include <linux/mm.h>
  23#include <linux/swap.h>
  24#include <linux/slab.h>
  25#include <linux/sysctl.h>
  26#include <linux/signal.h>
  27#include <linux/proc_fs.h>
  28#include <linux/security.h>
  29#include <linux/ctype.h>
  30#include <linux/kmemcheck.h>
  31#include <linux/fs.h>
  32#include <linux/init.h>
  33#include <linux/kernel.h>
  34#include <linux/kobject.h>
  35#include <linux/net.h>
  36#include <linux/sysrq.h>
  37#include <linux/highuid.h>
  38#include <linux/writeback.h>
  39#include <linux/ratelimit.h>
  40#include <linux/compaction.h>
  41#include <linux/hugetlb.h>
  42#include <linux/initrd.h>
  43#include <linux/key.h>
  44#include <linux/times.h>
  45#include <linux/limits.h>
  46#include <linux/dcache.h>
  47#include <linux/dnotify.h>
  48#include <linux/syscalls.h>
  49#include <linux/vmstat.h>
  50#include <linux/nfs_fs.h>
  51#include <linux/acpi.h>
  52#include <linux/reboot.h>
  53#include <linux/ftrace.h>
  54#include <linux/perf_event.h>
  55#include <linux/kprobes.h>
  56#include <linux/pipe_fs_i.h>
  57#include <linux/oom.h>
  58
  59#include <asm/uaccess.h>
  60#include <asm/processor.h>
  61
  62#ifdef CONFIG_X86
  63#include <asm/nmi.h>
  64#include <asm/stacktrace.h>
  65#include <asm/io.h>
  66#endif
  67#ifdef CONFIG_BSD_PROCESS_ACCT
  68#include <linux/acct.h>
  69#endif
  70#ifdef CONFIG_RT_MUTEXES
  71#include <linux/rtmutex.h>
  72#endif
  73#if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_LOCK_STAT)
  74#include <linux/lockdep.h>
  75#endif
  76#ifdef CONFIG_CHR_DEV_SG
  77#include <scsi/sg.h>
  78#endif
  79
  80#ifdef CONFIG_LOCKUP_DETECTOR
  81#include <linux/nmi.h>
  82#endif
  83
  84
  85#if defined(CONFIG_SYSCTL)
  86
  87/* External variables not in a header file. */
  88extern int sysctl_overcommit_memory;
  89extern int sysctl_overcommit_ratio;
  90extern int max_threads;
  91extern int core_uses_pid;
  92extern int suid_dumpable;
  93extern char core_pattern[];
  94extern unsigned int core_pipe_limit;
  95extern int pid_max;
  96extern int min_free_kbytes;
  97extern int pid_max_min, pid_max_max;
  98extern int sysctl_drop_caches;
  99extern int percpu_pagelist_fraction;
 100extern int compat_log;
 101extern int latencytop_enabled;
 102extern int sysctl_nr_open_min, sysctl_nr_open_max;
 103#ifndef CONFIG_MMU
 104extern int sysctl_nr_trim_pages;
 105#endif
 106#ifdef CONFIG_BLOCK
 107extern int blk_iopoll_enabled;
 108#endif
 109
 110/* Constants used for minimum and  maximum */
 111#ifdef CONFIG_LOCKUP_DETECTOR
 112static int sixty = 60;
 113static int neg_one = -1;
 114#endif
 115
 116static int zero;
 117static int __maybe_unused one = 1;
 118static int __maybe_unused two = 2;
 119static unsigned long one_ul = 1;
 120static int one_hundred = 100;
 121#ifdef CONFIG_PRINTK
 122static int ten_thousand = 10000;
 123#endif
 124
 125/* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
 126static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
 127
 128/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 129static int maxolduid = 65535;
 130static int minolduid;
 131static int min_percpu_pagelist_fract = 8;
 132
 133static int ngroups_max = NGROUPS_MAX;
 134
 135#ifdef CONFIG_INOTIFY_USER
 136#include <linux/inotify.h>
 137#endif
 138#ifdef CONFIG_SPARC
 139#include <asm/system.h>
 140#endif
 141
 142#ifdef CONFIG_SPARC64
 143extern int sysctl_tsb_ratio;
 144#endif
 145
 146#ifdef __hppa__
 147extern int pwrsw_enabled;
 148extern int unaligned_enabled;
 149#endif
 150
 151#ifdef CONFIG_S390
 152#ifdef CONFIG_MATHEMU
 153extern int sysctl_ieee_emulation_warnings;
 154#endif
 155extern int sysctl_userprocess_debug;
 156extern int spin_retry;
 157#endif
 158
 159#ifdef CONFIG_IA64
 160extern int no_unaligned_warning;
 161extern int unaligned_dump_stack;
 162#endif
 163
 164#ifdef CONFIG_PROC_SYSCTL
 165static int proc_do_cad_pid(struct ctl_table *table, int write,
 166                  void __user *buffer, size_t *lenp, loff_t *ppos);
 167static int proc_taint(struct ctl_table *table, int write,
 168                               void __user *buffer, size_t *lenp, loff_t *ppos);
 169#endif
 170
 171#ifdef CONFIG_MAGIC_SYSRQ
 172static int __sysrq_enabled; /* Note: sysrq code ises it's own private copy */
 173
 174static int sysrq_sysctl_handler(ctl_table *table, int write,
 175                                void __user *buffer, size_t *lenp,
 176                                loff_t *ppos)
 177{
 178        int error;
 179
 180        error = proc_dointvec(table, write, buffer, lenp, ppos);
 181        if (error)
 182                return error;
 183
 184        if (write)
 185                sysrq_toggle_support(__sysrq_enabled);
 186
 187        return 0;
 188}
 189
 190#endif
 191
 192static struct ctl_table root_table[];
 193static struct ctl_table_root sysctl_table_root;
 194static struct ctl_table_header root_table_header = {
 195        .count = 1,
 196        .ctl_table = root_table,
 197        .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),
 198        .root = &sysctl_table_root,
 199        .set = &sysctl_table_root.default_set,
 200};
 201static struct ctl_table_root sysctl_table_root = {
 202        .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
 203        .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry),
 204};
 205
 206static struct ctl_table kern_table[];
 207static struct ctl_table vm_table[];
 208static struct ctl_table fs_table[];
 209static struct ctl_table debug_table[];
 210static struct ctl_table dev_table[];
 211extern struct ctl_table random_table[];
 212#ifdef CONFIG_EPOLL
 213extern struct ctl_table epoll_table[];
 214#endif
 215
 216#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
 217int sysctl_legacy_va_layout;
 218#endif
 219
 220/* The default sysctl tables: */
 221
 222static struct ctl_table root_table[] = {
 223        {
 224                .procname       = "kernel",
 225                .mode           = 0555,
 226                .child          = kern_table,
 227        },
 228        {
 229                .procname       = "vm",
 230                .mode           = 0555,
 231                .child          = vm_table,
 232        },
 233        {
 234                .procname       = "fs",
 235                .mode           = 0555,
 236                .child          = fs_table,
 237        },
 238        {
 239                .procname       = "debug",
 240                .mode           = 0555,
 241                .child          = debug_table,
 242        },
 243        {
 244                .procname       = "dev",
 245                .mode           = 0555,
 246                .child          = dev_table,
 247        },
 248/*
 249 * NOTE: do not add new entries to this table unless you have read
 250 * Documentation/sysctl/ctl_unnumbered.txt
 251 */
 252        { }
 253};
 254
 255#ifdef CONFIG_SCHED_DEBUG
 256static int min_sched_granularity_ns = 100000;           /* 100 usecs */
 257static int max_sched_granularity_ns = NSEC_PER_SEC;     /* 1 second */
 258static int min_wakeup_granularity_ns;                   /* 0 usecs */
 259static int max_wakeup_granularity_ns = NSEC_PER_SEC;    /* 1 second */
 260static int min_sched_tunable_scaling = SCHED_TUNABLESCALING_NONE;
 261static int max_sched_tunable_scaling = SCHED_TUNABLESCALING_END-1;
 262static int min_sched_shares_ratelimit = 100000; /* 100 usec */
 263static int max_sched_shares_ratelimit = NSEC_PER_SEC; /* 1 second */
 264#endif
 265
 266#ifdef CONFIG_COMPACTION
 267static int min_extfrag_threshold;
 268static int max_extfrag_threshold = 1000;
 269#endif
 270
 271static struct ctl_table kern_table[] = {
 272        {
 273                .procname       = "sched_child_runs_first",
 274                .data           = &sysctl_sched_child_runs_first,
 275                .maxlen         = sizeof(unsigned int),
 276                .mode           = 0644,
 277                .proc_handler   = proc_dointvec,
 278        },
 279#ifdef CONFIG_SCHED_DEBUG
 280        {
 281                .procname       = "sched_min_granularity_ns",
 282                .data           = &sysctl_sched_min_granularity,
 283                .maxlen         = sizeof(unsigned int),
 284                .mode           = 0644,
 285                .proc_handler   = sched_proc_update_handler,
 286                .extra1         = &min_sched_granularity_ns,
 287                .extra2         = &max_sched_granularity_ns,
 288        },
 289        {
 290                .procname       = "sched_latency_ns",
 291                .data           = &sysctl_sched_latency,
 292                .maxlen         = sizeof(unsigned int),
 293                .mode           = 0644,
 294                .proc_handler   = sched_proc_update_handler,
 295                .extra1         = &min_sched_granularity_ns,
 296                .extra2         = &max_sched_granularity_ns,
 297        },
 298        {
 299                .procname       = "sched_wakeup_granularity_ns",
 300                .data           = &sysctl_sched_wakeup_granularity,
 301                .maxlen         = sizeof(unsigned int),
 302                .mode           = 0644,
 303                .proc_handler   = sched_proc_update_handler,
 304                .extra1         = &min_wakeup_granularity_ns,
 305                .extra2         = &max_wakeup_granularity_ns,
 306        },
 307        {
 308                .procname       = "sched_shares_ratelimit",
 309                .data           = &sysctl_sched_shares_ratelimit,
 310                .maxlen         = sizeof(unsigned int),
 311                .mode           = 0644,
 312                .proc_handler   = sched_proc_update_handler,
 313                .extra1         = &min_sched_shares_ratelimit,
 314                .extra2         = &max_sched_shares_ratelimit,
 315        },
 316        {
 317                .procname       = "sched_tunable_scaling",
 318                .data           = &sysctl_sched_tunable_scaling,
 319                .maxlen         = sizeof(enum sched_tunable_scaling),
 320                .mode           = 0644,
 321                .proc_handler   = sched_proc_update_handler,
 322                .extra1         = &min_sched_tunable_scaling,
 323                .extra2         = &max_sched_tunable_scaling,
 324        },
 325        {
 326                .procname       = "sched_shares_thresh",
 327                .data           = &sysctl_sched_shares_thresh,
 328                .maxlen         = sizeof(unsigned int),
 329                .mode           = 0644,
 330                .proc_handler   = proc_dointvec_minmax,
 331                .extra1         = &zero,
 332        },
 333        {
 334                .procname       = "sched_migration_cost",
 335                .data           = &sysctl_sched_migration_cost,
 336                .maxlen         = sizeof(unsigned int),
 337                .mode           = 0644,
 338                .proc_handler   = proc_dointvec,
 339        },
 340        {
 341                .procname       = "sched_nr_migrate",
 342                .data           = &sysctl_sched_nr_migrate,
 343                .maxlen         = sizeof(unsigned int),
 344                .mode           = 0644,
 345                .proc_handler   = proc_dointvec,
 346        },
 347        {
 348                .procname       = "sched_time_avg",
 349                .data           = &sysctl_sched_time_avg,
 350                .maxlen         = sizeof(unsigned int),
 351                .mode           = 0644,
 352                .proc_handler   = proc_dointvec,
 353        },
 354        {
 355                .procname       = "timer_migration",
 356                .data           = &sysctl_timer_migration,
 357                .maxlen         = sizeof(unsigned int),
 358                .mode           = 0644,
 359                .proc_handler   = proc_dointvec_minmax,
 360                .extra1         = &zero,
 361                .extra2         = &one,
 362        },
 363#endif
 364        {
 365                .procname       = "sched_rt_period_us",
 366                .data           = &sysctl_sched_rt_period,
 367                .maxlen         = sizeof(unsigned int),
 368                .mode           = 0644,
 369                .proc_handler   = sched_rt_handler,
 370        },
 371        {
 372                .procname       = "sched_rt_runtime_us",
 373                .data           = &sysctl_sched_rt_runtime,
 374                .maxlen         = sizeof(int),
 375                .mode           = 0644,
 376                .proc_handler   = sched_rt_handler,
 377        },
 378        {
 379                .procname       = "sched_compat_yield",
 380                .data           = &sysctl_sched_compat_yield,
 381                .maxlen         = sizeof(unsigned int),
 382                .mode           = 0644,
 383                .proc_handler   = proc_dointvec,
 384        },
 385#ifdef CONFIG_PROVE_LOCKING
 386        {
 387                .procname       = "prove_locking",
 388                .data           = &prove_locking,
 389                .maxlen         = sizeof(int),
 390                .mode           = 0644,
 391                .proc_handler   = proc_dointvec,
 392        },
 393#endif
 394#ifdef CONFIG_LOCK_STAT
 395        {
 396                .procname       = "lock_stat",
 397                .data           = &lock_stat,
 398                .maxlen         = sizeof(int),
 399                .mode           = 0644,
 400                .proc_handler   = proc_dointvec,
 401        },
 402#endif
 403        {
 404                .procname       = "panic",
 405                .data           = &panic_timeout,
 406                .maxlen         = sizeof(int),
 407                .mode           = 0644,
 408                .proc_handler   = proc_dointvec,
 409        },
 410        {
 411                .procname       = "core_uses_pid",
 412                .data           = &core_uses_pid,
 413                .maxlen         = sizeof(int),
 414                .mode           = 0644,
 415                .proc_handler   = proc_dointvec,
 416        },
 417        {
 418                .procname       = "core_pattern",
 419                .data           = core_pattern,
 420                .maxlen         = CORENAME_MAX_SIZE,
 421                .mode           = 0644,
 422                .proc_handler   = proc_dostring,
 423        },
 424        {
 425                .procname       = "core_pipe_limit",
 426                .data           = &core_pipe_limit,
 427                .maxlen         = sizeof(unsigned int),
 428                .mode           = 0644,
 429                .proc_handler   = proc_dointvec,
 430        },
 431#ifdef CONFIG_PROC_SYSCTL
 432        {
 433                .procname       = "tainted",
 434                .maxlen         = sizeof(long),
 435                .mode           = 0644,
 436                .proc_handler   = proc_taint,
 437        },
 438#endif
 439#ifdef CONFIG_LATENCYTOP
 440        {
 441                .procname       = "latencytop",
 442                .data           = &latencytop_enabled,
 443                .maxlen         = sizeof(int),
 444                .mode           = 0644,
 445                .proc_handler   = proc_dointvec,
 446        },
 447#endif
 448#ifdef CONFIG_BLK_DEV_INITRD
 449        {
 450                .procname       = "real-root-dev",
 451                .data           = &real_root_dev,
 452                .maxlen         = sizeof(int),
 453                .mode           = 0644,
 454                .proc_handler   = proc_dointvec,
 455        },
 456#endif
 457        {
 458                .procname       = "print-fatal-signals",
 459                .data           = &print_fatal_signals,
 460                .maxlen         = sizeof(int),
 461                .mode           = 0644,
 462                .proc_handler   = proc_dointvec,
 463        },
 464#ifdef CONFIG_SPARC
 465        {
 466                .procname       = "reboot-cmd",
 467                .data           = reboot_command,
 468                .maxlen         = 256,
 469                .mode           = 0644,
 470                .proc_handler   = proc_dostring,
 471        },
 472        {
 473                .procname       = "stop-a",
 474                .data           = &stop_a_enabled,
 475                .maxlen         = sizeof (int),
 476                .mode           = 0644,
 477                .proc_handler   = proc_dointvec,
 478        },
 479        {
 480                .procname       = "scons-poweroff",
 481                .data           = &scons_pwroff,
 482                .maxlen         = sizeof (int),
 483                .mode           = 0644,
 484                .proc_handler   = proc_dointvec,
 485        },
 486#endif
 487#ifdef CONFIG_SPARC64
 488        {
 489                .procname       = "tsb-ratio",
 490                .data           = &sysctl_tsb_ratio,
 491                .maxlen         = sizeof (int),
 492                .mode           = 0644,
 493                .proc_handler   = proc_dointvec,
 494        },
 495#endif
 496#ifdef __hppa__
 497        {
 498                .procname       = "soft-power",
 499                .data           = &pwrsw_enabled,
 500                .maxlen         = sizeof (int),
 501                .mode           = 0644,
 502                .proc_handler   = proc_dointvec,
 503        },
 504        {
 505                .procname       = "unaligned-trap",
 506                .data           = &unaligned_enabled,
 507                .maxlen         = sizeof (int),
 508                .mode           = 0644,
 509                .proc_handler   = proc_dointvec,
 510        },
 511#endif
 512        {
 513                .procname       = "ctrl-alt-del",
 514                .data           = &C_A_D,
 515                .maxlen         = sizeof(int),
 516                .mode           = 0644,
 517                .proc_handler   = proc_dointvec,
 518        },
 519#ifdef CONFIG_FUNCTION_TRACER
 520        {
 521                .procname       = "ftrace_enabled",
 522                .data           = &ftrace_enabled,
 523                .maxlen         = sizeof(int),
 524                .mode           = 0644,
 525                .proc_handler   = ftrace_enable_sysctl,
 526        },
 527#endif
 528#ifdef CONFIG_STACK_TRACER
 529        {
 530                .procname       = "stack_tracer_enabled",
 531                .data           = &stack_tracer_enabled,
 532                .maxlen         = sizeof(int),
 533                .mode           = 0644,
 534                .proc_handler   = stack_trace_sysctl,
 535        },
 536#endif
 537#ifdef CONFIG_TRACING
 538        {
 539                .procname       = "ftrace_dump_on_oops",
 540                .data           = &ftrace_dump_on_oops,
 541                .maxlen         = sizeof(int),
 542                .mode           = 0644,
 543                .proc_handler   = proc_dointvec,
 544        },
 545#endif
 546#ifdef CONFIG_MODULES
 547        {
 548                .procname       = "modprobe",
 549                .data           = &modprobe_path,
 550                .maxlen         = KMOD_PATH_LEN,
 551                .mode           = 0644,
 552                .proc_handler   = proc_dostring,
 553        },
 554        {
 555                .procname       = "modules_disabled",
 556                .data           = &modules_disabled,
 557                .maxlen         = sizeof(int),
 558                .mode           = 0644,
 559                /* only handle a transition from default "0" to "1" */
 560                .proc_handler   = proc_dointvec_minmax,
 561                .extra1         = &one,
 562                .extra2         = &one,
 563        },
 564#endif
 565#ifdef CONFIG_HOTPLUG
 566        {
 567                .procname       = "hotplug",
 568                .data           = &uevent_helper,
 569                .maxlen         = UEVENT_HELPER_PATH_LEN,
 570                .mode           = 0644,
 571                .proc_handler   = proc_dostring,
 572        },
 573#endif
 574#ifdef CONFIG_CHR_DEV_SG
 575        {
 576                .procname       = "sg-big-buff",
 577                .data           = &sg_big_buff,
 578                .maxlen         = sizeof (int),
 579                .mode           = 0444,
 580                .proc_handler   = proc_dointvec,
 581        },
 582#endif
 583#ifdef CONFIG_BSD_PROCESS_ACCT
 584        {
 585                .procname       = "acct",
 586                .data           = &acct_parm,
 587                .maxlen         = 3*sizeof(int),
 588                .mode           = 0644,
 589                .proc_handler   = proc_dointvec,
 590        },
 591#endif
 592#ifdef CONFIG_MAGIC_SYSRQ
 593        {
 594                .procname       = "sysrq",
 595                .data           = &__sysrq_enabled,
 596                .maxlen         = sizeof (int),
 597                .mode           = 0644,
 598                .proc_handler   = sysrq_sysctl_handler,
 599        },
 600#endif
 601#ifdef CONFIG_PROC_SYSCTL
 602        {
 603                .procname       = "cad_pid",
 604                .data           = NULL,
 605                .maxlen         = sizeof (int),
 606                .mode           = 0600,
 607                .proc_handler   = proc_do_cad_pid,
 608        },
 609#endif
 610        {
 611                .procname       = "threads-max",
 612                .data           = &max_threads,
 613                .maxlen         = sizeof(int),
 614                .mode           = 0644,
 615                .proc_handler   = proc_dointvec,
 616        },
 617        {
 618                .procname       = "random",
 619                .mode           = 0555,
 620                .child          = random_table,
 621        },
 622        {
 623                .procname       = "overflowuid",
 624                .data           = &overflowuid,
 625                .maxlen         = sizeof(int),
 626                .mode           = 0644,
 627                .proc_handler   = proc_dointvec_minmax,
 628                .extra1         = &minolduid,
 629                .extra2         = &maxolduid,
 630        },
 631        {
 632                .procname       = "overflowgid",
 633                .data           = &overflowgid,
 634                .maxlen         = sizeof(int),
 635                .mode           = 0644,
 636                .proc_handler   = proc_dointvec_minmax,
 637                .extra1         = &minolduid,
 638                .extra2         = &maxolduid,
 639        },
 640#ifdef CONFIG_S390
 641#ifdef CONFIG_MATHEMU
 642        {
 643                .procname       = "ieee_emulation_warnings",
 644                .data           = &sysctl_ieee_emulation_warnings,
 645                .maxlen         = sizeof(int),
 646                .mode           = 0644,
 647                .proc_handler   = proc_dointvec,
 648        },
 649#endif
 650        {
 651                .procname       = "userprocess_debug",
 652                .data           = &show_unhandled_signals,
 653                .maxlen         = sizeof(int),
 654                .mode           = 0644,
 655                .proc_handler   = proc_dointvec,
 656        },
 657#endif
 658        {
 659                .procname       = "pid_max",
 660                .data           = &pid_max,
 661                .maxlen         = sizeof (int),
 662                .mode           = 0644,
 663                .proc_handler   = proc_dointvec_minmax,
 664                .extra1         = &pid_max_min,
 665                .extra2         = &pid_max_max,
 666        },
 667        {
 668                .procname       = "panic_on_oops",
 669                .data           = &panic_on_oops,
 670                .maxlen         = sizeof(int),
 671                .mode           = 0644,
 672                .proc_handler   = proc_dointvec,
 673        },
 674#if defined CONFIG_PRINTK
 675        {
 676                .procname       = "printk",
 677                .data           = &console_loglevel,
 678                .maxlen         = 4*sizeof(int),
 679                .mode           = 0644,
 680                .proc_handler   = proc_dointvec,
 681        },
 682        {
 683                .procname       = "printk_ratelimit",
 684                .data           = &printk_ratelimit_state.interval,
 685                .maxlen         = sizeof(int),
 686                .mode           = 0644,
 687                .proc_handler   = proc_dointvec_jiffies,
 688        },
 689        {
 690                .procname       = "printk_ratelimit_burst",
 691                .data           = &printk_ratelimit_state.burst,
 692                .maxlen         = sizeof(int),
 693                .mode           = 0644,
 694                .proc_handler   = proc_dointvec,
 695        },
 696        {
 697                .procname       = "printk_delay",
 698                .data           = &printk_delay_msec,
 699                .maxlen         = sizeof(int),
 700                .mode           = 0644,
 701                .proc_handler   = proc_dointvec_minmax,
 702                .extra1         = &zero,
 703                .extra2         = &ten_thousand,
 704        },
 705        {
 706                .procname       = "dmesg_restrict",
 707                .data           = &dmesg_restrict,
 708                .maxlen         = sizeof(int),
 709                .mode           = 0644,
 710                .proc_handler   = proc_dointvec_minmax,
 711                .extra1         = &zero,
 712                .extra2         = &one,
 713        },
 714#endif
 715        {
 716                .procname       = "ngroups_max",
 717                .data           = &ngroups_max,
 718                .maxlen         = sizeof (int),
 719                .mode           = 0444,
 720                .proc_handler   = proc_dointvec,
 721        },
 722#if defined(CONFIG_LOCKUP_DETECTOR)
 723        {
 724                .procname       = "watchdog",
 725                .data           = &watchdog_enabled,
 726                .maxlen         = sizeof (int),
 727                .mode           = 0644,
 728                .proc_handler   = proc_dowatchdog_enabled,
 729        },
 730        {
 731                .procname       = "watchdog_thresh",
 732                .data           = &softlockup_thresh,
 733                .maxlen         = sizeof(int),
 734                .mode           = 0644,
 735                .proc_handler   = proc_dowatchdog_thresh,
 736                .extra1         = &neg_one,
 737                .extra2         = &sixty,
 738        },
 739        {
 740                .procname       = "softlockup_panic",
 741                .data           = &softlockup_panic,
 742                .maxlen         = sizeof(int),
 743                .mode           = 0644,
 744                .proc_handler   = proc_dointvec_minmax,
 745                .extra1         = &zero,
 746                .extra2         = &one,
 747        },
 748#endif
 749#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) && !defined(CONFIG_LOCKUP_DETECTOR)
 750        {
 751                .procname       = "unknown_nmi_panic",
 752                .data           = &unknown_nmi_panic,
 753                .maxlen         = sizeof (int),
 754                .mode           = 0644,
 755                .proc_handler   = proc_dointvec,
 756        },
 757        {
 758                .procname       = "nmi_watchdog",
 759                .data           = &nmi_watchdog_enabled,
 760                .maxlen         = sizeof (int),
 761                .mode           = 0644,
 762                .proc_handler   = proc_nmi_enabled,
 763        },
 764#endif
 765#if defined(CONFIG_X86)
 766        {
 767                .procname       = "panic_on_unrecovered_nmi",
 768                .data           = &panic_on_unrecovered_nmi,
 769                .maxlen         = sizeof(int),
 770                .mode           = 0644,
 771                .proc_handler   = proc_dointvec,
 772        },
 773        {
 774                .procname       = "panic_on_io_nmi",
 775                .data           = &panic_on_io_nmi,
 776                .maxlen         = sizeof(int),
 777                .mode           = 0644,
 778                .proc_handler   = proc_dointvec,
 779        },
 780        {
 781                .procname       = "bootloader_type",
 782                .data           = &bootloader_type,
 783                .maxlen         = sizeof (int),
 784                .mode           = 0444,
 785                .proc_handler   = proc_dointvec,
 786        },
 787        {
 788                .procname       = "bootloader_version",
 789                .data           = &bootloader_version,
 790                .maxlen         = sizeof (int),
 791                .mode           = 0444,
 792                .proc_handler   = proc_dointvec,
 793        },
 794        {
 795                .procname       = "kstack_depth_to_print",
 796                .data           = &kstack_depth_to_print,
 797                .maxlen         = sizeof(int),
 798                .mode           = 0644,
 799                .proc_handler   = proc_dointvec,
 800        },
 801        {
 802                .procname       = "io_delay_type",
 803                .data           = &io_delay_type,
 804                .maxlen         = sizeof(int),
 805                .mode           = 0644,
 806                .proc_handler   = proc_dointvec,
 807        },
 808#endif
 809#if defined(CONFIG_MMU)
 810        {
 811                .procname       = "randomize_va_space",
 812                .data           = &randomize_va_space,
 813                .maxlen         = sizeof(int),
 814                .mode           = 0644,
 815                .proc_handler   = proc_dointvec,
 816        },
 817#endif
 818#if defined(CONFIG_S390) && defined(CONFIG_SMP)
 819        {
 820                .procname       = "spin_retry",
 821                .data           = &spin_retry,
 822                .maxlen         = sizeof (int),
 823                .mode           = 0644,
 824                .proc_handler   = proc_dointvec,
 825        },
 826#endif
 827#if     defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86)
 828        {
 829                .procname       = "acpi_video_flags",
 830                .data           = &acpi_realmode_flags,
 831                .maxlen         = sizeof (unsigned long),
 832                .mode           = 0644,
 833                .proc_handler   = proc_doulongvec_minmax,
 834        },
 835#endif
 836#ifdef CONFIG_IA64
 837        {
 838                .procname       = "ignore-unaligned-usertrap",
 839                .data           = &no_unaligned_warning,
 840                .maxlen         = sizeof (int),
 841                .mode           = 0644,
 842                .proc_handler   = proc_dointvec,
 843        },
 844        {
 845                .procname       = "unaligned-dump-stack",
 846                .data           = &unaligned_dump_stack,
 847                .maxlen         = sizeof (int),
 848                .mode           = 0644,
 849                .proc_handler   = proc_dointvec,
 850        },
 851#endif
 852#ifdef CONFIG_DETECT_HUNG_TASK
 853        {
 854                .procname       = "hung_task_panic",
 855                .data           = &sysctl_hung_task_panic,
 856                .maxlen         = sizeof(int),
 857                .mode           = 0644,
 858                .proc_handler   = proc_dointvec_minmax,
 859                .extra1         = &zero,
 860                .extra2         = &one,
 861        },
 862        {
 863                .procname       = "hung_task_check_count",
 864                .data           = &sysctl_hung_task_check_count,
 865                .maxlen         = sizeof(unsigned long),
 866                .mode           = 0644,
 867                .proc_handler   = proc_doulongvec_minmax,
 868        },
 869        {
 870                .procname       = "hung_task_timeout_secs",
 871                .data           = &sysctl_hung_task_timeout_secs,
 872                .maxlen         = sizeof(unsigned long),
 873                .mode           = 0644,
 874                .proc_handler   = proc_dohung_task_timeout_secs,
 875        },
 876        {
 877                .procname       = "hung_task_warnings",
 878                .data           = &sysctl_hung_task_warnings,
 879                .maxlen         = sizeof(unsigned long),
 880                .mode           = 0644,
 881                .proc_handler   = proc_doulongvec_minmax,
 882        },
 883#endif
 884#ifdef CONFIG_COMPAT
 885        {
 886                .procname       = "compat-log",
 887                .data           = &compat_log,
 888                .maxlen         = sizeof (int),
 889                .mode           = 0644,
 890                .proc_handler   = proc_dointvec,
 891        },
 892#endif
 893#ifdef CONFIG_RT_MUTEXES
 894        {
 895                .procname       = "max_lock_depth",
 896                .data           = &max_lock_depth,
 897                .maxlen         = sizeof(int),
 898                .mode           = 0644,
 899                .proc_handler   = proc_dointvec,
 900        },
 901#endif
 902        {
 903                .procname       = "poweroff_cmd",
 904                .data           = &poweroff_cmd,
 905                .maxlen         = POWEROFF_CMD_PATH_LEN,
 906                .mode           = 0644,
 907                .proc_handler   = proc_dostring,
 908        },
 909#ifdef CONFIG_KEYS
 910        {
 911                .procname       = "keys",
 912                .mode           = 0555,
 913                .child          = key_sysctls,
 914        },
 915#endif
 916#ifdef CONFIG_RCU_TORTURE_TEST
 917        {
 918                .procname       = "rcutorture_runnable",
 919                .data           = &rcutorture_runnable,
 920                .maxlen         = sizeof(int),
 921                .mode           = 0644,
 922                .proc_handler   = proc_dointvec,
 923        },
 924#endif
 925#ifdef CONFIG_PERF_EVENTS
 926        {
 927                .procname       = "perf_event_paranoid",
 928                .data           = &sysctl_perf_event_paranoid,
 929                .maxlen         = sizeof(sysctl_perf_event_paranoid),
 930                .mode           = 0644,
 931                .proc_handler   = proc_dointvec,
 932        },
 933        {
 934                .procname       = "perf_event_mlock_kb",
 935                .data           = &sysctl_perf_event_mlock,
 936                .maxlen         = sizeof(sysctl_perf_event_mlock),
 937                .mode           = 0644,
 938                .proc_handler   = proc_dointvec,
 939        },
 940        {
 941                .procname       = "perf_event_max_sample_rate",
 942                .data           = &sysctl_perf_event_sample_rate,
 943                .maxlen         = sizeof(sysctl_perf_event_sample_rate),
 944                .mode           = 0644,
 945                .proc_handler   = proc_dointvec,
 946        },
 947#endif
 948#ifdef CONFIG_KMEMCHECK
 949        {
 950                .procname       = "kmemcheck",
 951                .data           = &kmemcheck_enabled,
 952                .maxlen         = sizeof(int),
 953                .mode           = 0644,
 954                .proc_handler   = proc_dointvec,
 955        },
 956#endif
 957#ifdef CONFIG_BLOCK
 958        {
 959                .procname       = "blk_iopoll",
 960                .data           = &blk_iopoll_enabled,
 961                .maxlen         = sizeof(int),
 962                .mode           = 0644,
 963                .proc_handler   = proc_dointvec,
 964        },
 965#endif
 966/*
 967 * NOTE: do not add new entries to this table unless you have read
 968 * Documentation/sysctl/ctl_unnumbered.txt
 969 */
 970        { }
 971};
 972
 973static struct ctl_table vm_table[] = {
 974        {
 975                .procname       = "overcommit_memory",
 976                .data           = &sysctl_overcommit_memory,
 977                .maxlen         = sizeof(sysctl_overcommit_memory),
 978                .mode           = 0644,
 979                .proc_handler   = proc_dointvec,
 980        },
 981        {
 982                .procname       = "panic_on_oom",
 983                .data           = &sysctl_panic_on_oom,
 984                .maxlen         = sizeof(sysctl_panic_on_oom),
 985                .mode           = 0644,
 986                .proc_handler   = proc_dointvec,
 987        },
 988        {
 989                .procname       = "oom_kill_allocating_task",
 990                .data           = &sysctl_oom_kill_allocating_task,
 991                .maxlen         = sizeof(sysctl_oom_kill_allocating_task),
 992                .mode           = 0644,
 993                .proc_handler   = proc_dointvec,
 994        },
 995        {
 996                .procname       = "oom_dump_tasks",
 997                .data           = &sysctl_oom_dump_tasks,
 998                .maxlen         = sizeof(sysctl_oom_dump_tasks),
 999                .mode           = 0644,
1000                .proc_handler   = proc_dointvec,
1001        },
1002        {
1003                .procname       = "overcommit_ratio",
1004                .data           = &sysctl_overcommit_ratio,
1005                .maxlen         = sizeof(sysctl_overcommit_ratio),
1006                .mode           = 0644,
1007                .proc_handler   = proc_dointvec,
1008        },
1009        {
1010                .procname       = "page-cluster", 
1011                .data           = &page_cluster,
1012                .maxlen         = sizeof(int),
1013                .mode           = 0644,
1014                .proc_handler   = proc_dointvec,
1015        },
1016        {
1017                .procname       = "dirty_background_ratio",
1018                .data           = &dirty_background_ratio,
1019                .maxlen         = sizeof(dirty_background_ratio),
1020                .mode           = 0644,
1021                .proc_handler   = dirty_background_ratio_handler,
1022                .extra1         = &zero,
1023                .extra2         = &one_hundred,
1024        },
1025        {
1026                .procname       = "dirty_background_bytes",
1027                .data           = &dirty_background_bytes,
1028                .maxlen         = sizeof(dirty_background_bytes),
1029                .mode           = 0644,
1030                .proc_handler   = dirty_background_bytes_handler,
1031                .extra1         = &one_ul,
1032        },
1033        {
1034                .procname       = "dirty_ratio",
1035                .data           = &vm_dirty_ratio,
1036                .maxlen         = sizeof(vm_dirty_ratio),
1037                .mode           = 0644,
1038                .proc_handler   = dirty_ratio_handler,
1039                .extra1         = &zero,
1040                .extra2         = &one_hundred,
1041        },
1042        {
1043                .procname       = "dirty_bytes",
1044                .data           = &vm_dirty_bytes,
1045                .maxlen         = sizeof(vm_dirty_bytes),
1046                .mode           = 0644,
1047                .proc_handler   = dirty_bytes_handler,
1048                .extra1         = &dirty_bytes_min,
1049        },
1050        {
1051                .procname       = "dirty_writeback_centisecs",
1052                .data           = &dirty_writeback_interval,
1053                .maxlen         = sizeof(dirty_writeback_interval),
1054                .mode           = 0644,
1055                .proc_handler   = dirty_writeback_centisecs_handler,
1056        },
1057        {
1058                .procname       = "dirty_expire_centisecs",
1059                .data           = &dirty_expire_interval,
1060                .maxlen         = sizeof(dirty_expire_interval),
1061                .mode           = 0644,
1062                .proc_handler   = proc_dointvec,
1063        },
1064        {
1065                .procname       = "nr_pdflush_threads",
1066                .data           = &nr_pdflush_threads,
1067                .maxlen         = sizeof nr_pdflush_threads,
1068                .mode           = 0444 /* read-only*/,
1069                .proc_handler   = proc_dointvec,
1070        },
1071        {
1072                .procname       = "swappiness",
1073                .data           = &vm_swappiness,
1074                .maxlen         = sizeof(vm_swappiness),
1075                .mode           = 0644,
1076                .proc_handler   = proc_dointvec_minmax,
1077                .extra1         = &zero,
1078                .extra2         = &one_hundred,
1079        },
1080#ifdef CONFIG_HUGETLB_PAGE
1081        {
1082                .procname       = "nr_hugepages",
1083                .data           = NULL,
1084                .maxlen         = sizeof(unsigned long),
1085                .mode           = 0644,
1086                .proc_handler   = hugetlb_sysctl_handler,
1087                .extra1         = (void *)&hugetlb_zero,
1088                .extra2         = (void *)&hugetlb_infinity,
1089        },
1090#ifdef CONFIG_NUMA
1091        {
1092                .procname       = "nr_hugepages_mempolicy",
1093                .data           = NULL,
1094                .maxlen         = sizeof(unsigned long),
1095                .mode           = 0644,
1096                .proc_handler   = &hugetlb_mempolicy_sysctl_handler,
1097                .extra1         = (void *)&hugetlb_zero,
1098                .extra2         = (void *)&hugetlb_infinity,
1099        },
1100#endif
1101         {
1102                .procname       = "hugetlb_shm_group",
1103                .data           = &sysctl_hugetlb_shm_group,
1104                .maxlen         = sizeof(gid_t),
1105                .mode           = 0644,
1106                .proc_handler   = proc_dointvec,
1107         },
1108         {
1109                .procname       = "hugepages_treat_as_movable",
1110                .data           = &hugepages_treat_as_movable,
1111                .maxlen         = sizeof(int),
1112                .mode           = 0644,
1113                .proc_handler   = hugetlb_treat_movable_handler,
1114        },
1115        {
1116                .procname       = "nr_overcommit_hugepages",
1117                .data           = NULL,
1118                .maxlen         = sizeof(unsigned long),
1119                .mode           = 0644,
1120                .proc_handler   = hugetlb_overcommit_handler,
1121                .extra1         = (void *)&hugetlb_zero,
1122                .extra2         = (void *)&hugetlb_infinity,
1123        },
1124#endif
1125        {
1126                .procname       = "lowmem_reserve_ratio",
1127                .data           = &sysctl_lowmem_reserve_ratio,
1128                .maxlen         = sizeof(sysctl_lowmem_reserve_ratio),
1129                .mode           = 0644,
1130                .proc_handler   = lowmem_reserve_ratio_sysctl_handler,
1131        },
1132        {
1133                .procname       = "drop_caches",
1134                .data           = &sysctl_drop_caches,
1135                .maxlen         = sizeof(int),
1136                .mode           = 0644,
1137                .proc_handler   = drop_caches_sysctl_handler,
1138        },
1139#ifdef CONFIG_COMPACTION
1140        {
1141                .procname       = "compact_memory",
1142                .data           = &sysctl_compact_memory,
1143                .maxlen         = sizeof(int),
1144                .mode           = 0200,
1145                .proc_handler   = sysctl_compaction_handler,
1146        },
1147        {
1148                .procname       = "extfrag_threshold",
1149                .data           = &sysctl_extfrag_threshold,
1150                .maxlen         = sizeof(int),
1151                .mode           = 0644,
1152                .proc_handler   = sysctl_extfrag_handler,
1153                .extra1         = &min_extfrag_threshold,
1154                .extra2         = &max_extfrag_threshold,
1155        },
1156
1157#endif /* CONFIG_COMPACTION */
1158        {
1159                .procname       = "min_free_kbytes",
1160                .data           = &min_free_kbytes,
1161                .maxlen         = sizeof(min_free_kbytes),
1162                .mode           = 0644,
1163                .proc_handler   = min_free_kbytes_sysctl_handler,
1164                .extra1         = &zero,
1165        },
1166        {
1167                .procname       = "percpu_pagelist_fraction",
1168                .data           = &percpu_pagelist_fraction,
1169                .maxlen         = sizeof(percpu_pagelist_fraction),
1170                .mode           = 0644,
1171                .proc_handler   = percpu_pagelist_fraction_sysctl_handler,
1172                .extra1         = &min_percpu_pagelist_fract,
1173        },
1174#ifdef CONFIG_MMU
1175        {
1176                .procname       = "max_map_count",
1177                .data           = &sysctl_max_map_count,
1178                .maxlen         = sizeof(sysctl_max_map_count),
1179                .mode           = 0644,
1180                .proc_handler   = proc_dointvec_minmax,
1181                .extra1         = &zero,
1182        },
1183#else
1184        {
1185                .procname       = "nr_trim_pages",
1186                .data           = &sysctl_nr_trim_pages,
1187                .maxlen         = sizeof(sysctl_nr_trim_pages),
1188                .mode           = 0644,
1189                .proc_handler   = proc_dointvec_minmax,
1190                .extra1         = &zero,
1191        },
1192#endif
1193        {
1194                .procname       = "laptop_mode",
1195                .data           = &laptop_mode,
1196                .maxlen         = sizeof(laptop_mode),
1197                .mode           = 0644,
1198                .proc_handler   = proc_dointvec_jiffies,
1199        },
1200        {
1201                .procname       = "block_dump",
1202                .data           = &block_dump,
1203                .maxlen         = sizeof(block_dump),
1204                .mode           = 0644,
1205                .proc_handler   = proc_dointvec,
1206                .extra1         = &zero,
1207        },
1208        {
1209                .procname       = "vfs_cache_pressure",
1210                .data           = &sysctl_vfs_cache_pressure,
1211                .maxlen         = sizeof(sysctl_vfs_cache_pressure),
1212                .mode           = 0644,
1213                .proc_handler   = proc_dointvec,
1214                .extra1         = &zero,
1215        },
1216#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
1217        {
1218                .procname       = "legacy_va_layout",
1219                .data           = &sysctl_legacy_va_layout,
1220                .maxlen         = sizeof(sysctl_legacy_va_layout),
1221                .mode           = 0644,
1222                .proc_handler   = proc_dointvec,
1223                .extra1         = &zero,
1224        },
1225#endif
1226#ifdef CONFIG_NUMA
1227        {
1228                .procname       = "zone_reclaim_mode",
1229                .data           = &zone_reclaim_mode,
1230                .maxlen         = sizeof(zone_reclaim_mode),
1231                .mode           = 0644,
1232                .proc_handler   = proc_dointvec,
1233                .extra1         = &zero,
1234        },
1235        {
1236                .procname       = "min_unmapped_ratio",
1237                .data           = &sysctl_min_unmapped_ratio,
1238                .maxlen         = sizeof(sysctl_min_unmapped_ratio),
1239                .mode           = 0644,
1240                .proc_handler   = sysctl_min_unmapped_ratio_sysctl_handler,
1241                .extra1         = &zero,
1242                .extra2         = &one_hundred,
1243        },
1244        {
1245                .procname       = "min_slab_ratio",
1246                .data           = &sysctl_min_slab_ratio,
1247                .maxlen         = sizeof(sysctl_min_slab_ratio),
1248                .mode           = 0644,
1249                .proc_handler   = sysctl_min_slab_ratio_sysctl_handler,
1250                .extra1         = &zero,
1251                .extra2         = &one_hundred,
1252        },
1253#endif
1254#ifdef CONFIG_SMP
1255        {
1256                .procname       = "stat_interval",
1257                .data           = &sysctl_stat_interval,
1258                .maxlen         = sizeof(sysctl_stat_interval),
1259                .mode           = 0644,
1260                .proc_handler   = proc_dointvec_jiffies,
1261        },
1262#endif
1263#ifdef CONFIG_MMU
1264        {
1265                .procname       = "mmap_min_addr",
1266                .data           = &dac_mmap_min_addr,
1267                .maxlen         = sizeof(unsigned long),
1268                .mode           = 0644,
1269                .proc_handler   = mmap_min_addr_handler,
1270        },
1271#endif
1272#ifdef CONFIG_NUMA
1273        {
1274                .procname       = "numa_zonelist_order",
1275                .data           = &numa_zonelist_order,
1276                .maxlen         = NUMA_ZONELIST_ORDER_LEN,
1277                .mode           = 0644,
1278                .proc_handler   = numa_zonelist_order_handler,
1279        },
1280#endif
1281#if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \
1282   (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
1283        {
1284                .procname       = "vdso_enabled",
1285                .data           = &vdso_enabled,
1286                .maxlen         = sizeof(vdso_enabled),
1287                .mode           = 0644,
1288                .proc_handler   = proc_dointvec,
1289                .extra1         = &zero,
1290        },
1291#endif
1292#ifdef CONFIG_HIGHMEM
1293        {
1294                .procname       = "highmem_is_dirtyable",
1295                .data           = &vm_highmem_is_dirtyable,
1296                .maxlen         = sizeof(vm_highmem_is_dirtyable),
1297                .mode           = 0644,
1298                .proc_handler   = proc_dointvec_minmax,
1299                .extra1         = &zero,
1300                .extra2         = &one,
1301        },
1302#endif
1303        {
1304                .procname       = "scan_unevictable_pages",
1305                .data           = &scan_unevictable_pages,
1306                .maxlen         = sizeof(scan_unevictable_pages),
1307                .mode           = 0644,
1308                .proc_handler   = scan_unevictable_handler,
1309        },
1310#ifdef CONFIG_MEMORY_FAILURE
1311        {
1312                .procname       = "memory_failure_early_kill",
1313                .data           = &sysctl_memory_failure_early_kill,
1314                .maxlen         = sizeof(sysctl_memory_failure_early_kill),
1315                .mode           = 0644,
1316                .proc_handler   = proc_dointvec_minmax,
1317                .extra1         = &zero,
1318                .extra2         = &one,
1319        },
1320        {
1321                .procname       = "memory_failure_recovery",
1322                .data           = &sysctl_memory_failure_recovery,
1323                .maxlen         = sizeof(sysctl_memory_failure_recovery),
1324                .mode           = 0644,
1325                .proc_handler   = proc_dointvec_minmax,
1326                .extra1         = &zero,
1327                .extra2         = &one,
1328        },
1329#endif
1330
1331/*
1332 * NOTE: do not add new entries to this table unless you have read
1333 * Documentation/sysctl/ctl_unnumbered.txt
1334 */
1335        { }
1336};
1337
1338#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
1339static struct ctl_table binfmt_misc_table[] = {
1340        { }
1341};
1342#endif
1343
1344static struct ctl_table fs_table[] = {
1345        {
1346                .procname       = "inode-nr",
1347                .data           = &inodes_stat,
1348                .maxlen         = 2*sizeof(int),
1349                .mode           = 0444,
1350                .proc_handler   = proc_nr_inodes,
1351        },
1352        {
1353                .procname       = "inode-state",
1354                .data           = &inodes_stat,
1355                .maxlen         = 7*sizeof(int),
1356                .mode           = 0444,
1357                .proc_handler   = proc_nr_inodes,
1358        },
1359        {
1360                .procname       = "file-nr",
1361                .data           = &files_stat,
1362                .maxlen         = sizeof(files_stat),
1363                .mode           = 0444,
1364                .proc_handler   = proc_nr_files,
1365        },
1366        {
1367                .procname       = "file-max",
1368                .data           = &files_stat.max_files,
1369                .maxlen         = sizeof(files_stat.max_files),
1370                .mode           = 0644,
1371                .proc_handler   = proc_doulongvec_minmax,
1372        },
1373        {
1374                .procname       = "nr_open",
1375                .data           = &sysctl_nr_open,
1376                .maxlen         = sizeof(int),
1377                .mode           = 0644,
1378                .proc_handler   = proc_dointvec_minmax,
1379                .extra1         = &sysctl_nr_open_min,
1380                .extra2         = &sysctl_nr_open_max,
1381        },
1382        {
1383                .procname       = "dentry-state",
1384                .data           = &dentry_stat,
1385                .maxlen         = 6*sizeof(int),
1386                .mode           = 0444,
1387                .proc_handler   = proc_nr_dentry,
1388        },
1389        {
1390                .procname       = "overflowuid",
1391                .data           = &fs_overflowuid,
1392                .maxlen         = sizeof(int),
1393                .mode           = 0644,
1394                .proc_handler   = proc_dointvec_minmax,
1395                .extra1         = &minolduid,
1396                .extra2         = &maxolduid,
1397        },
1398        {
1399                .procname       = "overflowgid",
1400                .data           = &fs_overflowgid,
1401                .maxlen         = sizeof(int),
1402                .mode           = 0644,
1403                .proc_handler   = proc_dointvec_minmax,
1404                .extra1         = &minolduid,
1405                .extra2         = &maxolduid,
1406        },
1407#ifdef CONFIG_FILE_LOCKING
1408        {
1409                .procname       = "leases-enable",
1410                .data           = &leases_enable,
1411                .maxlen         = sizeof(int),
1412                .mode           = 0644,
1413                .proc_handler   = proc_dointvec,
1414        },
1415#endif
1416#ifdef CONFIG_DNOTIFY
1417        {
1418                .procname       = "dir-notify-enable",
1419                .data           = &dir_notify_enable,
1420                .maxlen         = sizeof(int),
1421                .mode           = 0644,
1422                .proc_handler   = proc_dointvec,
1423        },
1424#endif
1425#ifdef CONFIG_MMU
1426#ifdef CONFIG_FILE_LOCKING
1427        {
1428                .procname       = "lease-break-time",
1429                .data           = &lease_break_time,
1430                .maxlen         = sizeof(int),
1431                .mode           = 0644,
1432                .proc_handler   = proc_dointvec,
1433        },
1434#endif
1435#ifdef CONFIG_AIO
1436        {
1437                .procname       = "aio-nr",
1438                .data           = &aio_nr,
1439                .maxlen         = sizeof(aio_nr),
1440                .mode           = 0444,
1441                .proc_handler   = proc_doulongvec_minmax,
1442        },
1443        {
1444                .procname       = "aio-max-nr",
1445                .data           = &aio_max_nr,
1446                .maxlen         = sizeof(aio_max_nr),
1447                .mode           = 0644,
1448                .proc_handler   = proc_doulongvec_minmax,
1449        },
1450#endif /* CONFIG_AIO */
1451#ifdef CONFIG_INOTIFY_USER
1452        {
1453                .procname       = "inotify",
1454                .mode           = 0555,
1455                .child          = inotify_table,
1456        },
1457#endif  
1458#ifdef CONFIG_EPOLL
1459        {
1460                .procname       = "epoll",
1461                .mode           = 0555,
1462                .child          = epoll_table,
1463        },
1464#endif
1465#endif
1466        {
1467                .procname       = "suid_dumpable",
1468                .data           = &suid_dumpable,
1469                .maxlen         = sizeof(int),
1470                .mode           = 0644,
1471                .proc_handler   = proc_dointvec_minmax,
1472                .extra1         = &zero,
1473                .extra2         = &two,
1474        },
1475#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
1476        {
1477                .procname       = "binfmt_misc",
1478                .mode           = 0555,
1479                .child          = binfmt_misc_table,
1480        },
1481#endif
1482        {
1483                .procname       = "pipe-max-size",
1484                .data           = &pipe_max_size,
1485                .maxlen         = sizeof(int),
1486                .mode           = 0644,
1487                .proc_handler   = &pipe_proc_fn,
1488                .extra1         = &pipe_min_size,
1489        },
1490/*
1491 * NOTE: do not add new entries to this table unless you have read
1492 * Documentation/sysctl/ctl_unnumbered.txt
1493 */
1494        { }
1495};
1496
1497static struct ctl_table debug_table[] = {
1498#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \
1499    defined(CONFIG_S390)
1500        {
1501                .procname       = "exception-trace",
1502                .data           = &show_unhandled_signals,
1503                .maxlen         = sizeof(int),
1504                .mode           = 0644,
1505                .proc_handler   = proc_dointvec
1506        },
1507#endif
1508#if defined(CONFIG_OPTPROBES)
1509        {
1510                .procname       = "kprobes-optimization",
1511                .data           = &sysctl_kprobes_optimization,
1512                .maxlen         = sizeof(int),
1513                .mode           = 0644,
1514                .proc_handler   = proc_kprobes_optimization_handler,
1515                .extra1         = &zero,
1516                .extra2         = &one,
1517        },
1518#endif
1519        { }
1520};
1521
1522static struct ctl_table dev_table[] = {
1523        { }
1524};
1525
1526static DEFINE_SPINLOCK(sysctl_lock);
1527
1528/* called under sysctl_lock */
1529static int use_table(struct ctl_table_header *p)
1530{
1531        if (unlikely(p->unregistering))
1532                return 0;
1533        p->used++;
1534        return 1;
1535}
1536
1537/* called under sysctl_lock */
1538static void unuse_table(struct ctl_table_header *p)
1539{
1540        if (!--p->used)
1541                if (unlikely(p->unregistering))
1542                        complete(p->unregistering);
1543}
1544
1545/* called under sysctl_lock, will reacquire if has to wait */
1546static void start_unregistering(struct ctl_table_header *p)
1547{
1548        /*
1549         * if p->used is 0, nobody will ever touch that entry again;
1550         * we'll eliminate all paths to it before dropping sysctl_lock
1551         */
1552        if (unlikely(p->used)) {
1553                struct completion wait;
1554                init_completion(&wait);
1555                p->unregistering = &wait;
1556                spin_unlock(&sysctl_lock);
1557                wait_for_completion(&wait);
1558                spin_lock(&sysctl_lock);
1559        } else {
1560                /* anything non-NULL; we'll never dereference it */
1561                p->unregistering = ERR_PTR(-EINVAL);
1562        }
1563        /*
1564         * do not remove from the list until nobody holds it; walking the
1565         * list in do_sysctl() relies on that.
1566         */
1567        list_del_init(&p->ctl_entry);
1568}
1569
1570void sysctl_head_get(struct ctl_table_header *head)
1571{
1572        spin_lock(&sysctl_lock);
1573        head->count++;
1574        spin_unlock(&sysctl_lock);
1575}
1576
1577void sysctl_head_put(struct ctl_table_header *head)
1578{
1579        spin_lock(&sysctl_lock);
1580        if (!--head->count)
1581                kfree(head);
1582        spin_unlock(&sysctl_lock);
1583}
1584
1585struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
1586{
1587        if (!head)
1588                BUG();
1589        spin_lock(&sysctl_lock);
1590        if (!use_table(head))
1591                head = ERR_PTR(-ENOENT);
1592        spin_unlock(&sysctl_lock);
1593        return head;
1594}
1595
1596void sysctl_head_finish(struct ctl_table_header *head)
1597{
1598        if (!head)
1599                return;
1600        spin_lock(&sysctl_lock);
1601        unuse_table(head);
1602        spin_unlock(&sysctl_lock);
1603}
1604
1605static struct ctl_table_set *
1606lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces)
1607{
1608        struct ctl_table_set *set = &root->default_set;
1609        if (root->lookup)
1610                set = root->lookup(root, namespaces);
1611        return set;
1612}
1613
1614static struct list_head *
1615lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
1616{
1617        struct ctl_table_set *set = lookup_header_set(root, namespaces);
1618        return &set->list;
1619}
1620
1621struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
1622                                            struct ctl_table_header *prev)
1623{
1624        struct ctl_table_root *root;
1625        struct list_head *header_list;
1626        struct ctl_table_header *head;
1627        struct list_head *tmp;
1628
1629        spin_lock(&sysctl_lock);
1630        if (prev) {
1631                head = prev;
1632                tmp = &prev->ctl_entry;
1633                unuse_table(prev);
1634                goto next;
1635        }
1636        tmp = &root_table_header.ctl_entry;
1637        for (;;) {
1638                head = list_entry(tmp, struct ctl_table_header, ctl_entry);
1639
1640                if (!use_table(head))
1641                        goto next;
1642                spin_unlock(&sysctl_lock);
1643                return head;
1644        next:
1645                root = head->root;
1646                tmp = tmp->next;
1647                header_list = lookup_header_list(root, namespaces);
1648                if (tmp != header_list)
1649                        continue;
1650
1651                do {
1652                        root = list_entry(root->root_list.next,
1653                                        struct ctl_table_root, root_list);
1654                        if (root == &sysctl_table_root)
1655                                goto out;
1656                        header_list = lookup_header_list(root, namespaces);
1657                } while (list_empty(header_list));
1658                tmp = header_list->next;
1659        }
1660out:
1661        spin_unlock(&sysctl_lock);
1662        return NULL;
1663}
1664
1665struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
1666{
1667        return __sysctl_head_next(current->nsproxy, prev);
1668}
1669
1670void register_sysctl_root(struct ctl_table_root *root)
1671{
1672        spin_lock(&sysctl_lock);
1673        list_add_tail(&root->root_list, &sysctl_table_root.root_list);
1674        spin_unlock(&sysctl_lock);
1675}
1676
1677/*
1678 * sysctl_perm does NOT grant the superuser all rights automatically, because
1679 * some sysctl variables are readonly even to root.
1680 */
1681
1682static int test_perm(int mode, int op)
1683{
1684        if (!current_euid())
1685                mode >>= 6;
1686        else if (in_egroup_p(0))
1687                mode >>= 3;
1688        if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
1689                return 0;
1690        return -EACCES;
1691}
1692
1693int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
1694{
1695        int error;
1696        int mode;
1697
1698        error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
1699        if (error)
1700                return error;
1701
1702        if (root->permissions)
1703                mode = root->permissions(root, current->nsproxy, table);
1704        else
1705                mode = table->mode;
1706
1707        return test_perm(mode, op);
1708}
1709
1710static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
1711{
1712        for (; table->procname; table++) {
1713                table->parent = parent;
1714                if (table->child)
1715                        sysctl_set_parent(table, table->child);
1716        }
1717}
1718
1719static __init int sysctl_init(void)
1720{
1721        sysctl_set_parent(NULL, root_table);
1722#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
1723        sysctl_check_table(current->nsproxy, root_table);
1724#endif
1725        return 0;
1726}
1727
1728core_initcall(sysctl_init);
1729
1730static struct ctl_table *is_branch_in(struct ctl_table *branch,
1731                                      struct ctl_table *table)
1732{
1733        struct ctl_table *p;
1734        const char *s = branch->procname;
1735
1736        /* branch should have named subdirectory as its first element */
1737        if (!s || !branch->child)
1738                return NULL;
1739
1740        /* ... and nothing else */
1741        if (branch[1].procname)
1742                return NULL;
1743
1744        /* table should contain subdirectory with the same name */
1745        for (p = table; p->procname; p++) {
1746                if (!p->child)
1747                        continue;
1748                if (p->procname && strcmp(p->procname, s) == 0)
1749                        return p;
1750        }
1751        return NULL;
1752}
1753
1754/* see if attaching q to p would be an improvement */
1755static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)
1756{
1757        struct ctl_table *to = p->ctl_table, *by = q->ctl_table;
1758        struct ctl_table *next;
1759        int is_better = 0;
1760        int not_in_parent = !p->attached_by;
1761
1762        while ((next = is_branch_in(by, to)) != NULL) {
1763                if (by == q->attached_by)
1764                        is_better = 1;
1765                if (to == p->attached_by)
1766                        not_in_parent = 1;
1767                by = by->child;
1768                to = next->child;
1769        }
1770
1771        if (is_better && not_in_parent) {
1772                q->attached_by = by;
1773                q->attached_to = to;
1774                q->parent = p;
1775        }
1776}
1777
1778/**
1779 * __register_sysctl_paths - register a sysctl hierarchy
1780 * @root: List of sysctl headers to register on
1781 * @namespaces: Data to compute which lists of sysctl entries are visible
1782 * @path: The path to the directory the sysctl table is in.
1783 * @table: the top-level table structure
1784 *
1785 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
1786 * array. A completely 0 filled entry terminates the table.
1787 *
1788 * The members of the &struct ctl_table structure are used as follows:
1789 *
1790 * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
1791 *            enter a sysctl file
1792 *
1793 * data - a pointer to data for use by proc_handler
1794 *
1795 * maxlen - the maximum size in bytes of the data
1796 *
1797 * mode - the file permissions for the /proc/sys file, and for sysctl(2)
1798 *
1799 * child - a pointer to the child sysctl table if this entry is a directory, or
1800 *         %NULL.
1801 *
1802 * proc_handler - the text handler routine (described below)
1803 *
1804 * de - for internal use by the sysctl routines
1805 *
1806 * extra1, extra2 - extra pointers usable by the proc handler routines
1807 *
1808 * Leaf nodes in the sysctl tree will be represented by a single file
1809 * under /proc; non-leaf nodes will be represented by directories.
1810 *
1811 * sysctl(2) can automatically manage read and write requests through
1812 * the sysctl table.  The data and maxlen fields of the ctl_table
1813 * struct enable minimal validation of the values being written to be
1814 * performed, and the mode field allows minimal authentication.
1815 *
1816 * There must be a proc_handler routine for any terminal nodes
1817 * mirrored under /proc/sys (non-terminals are handled by a built-in
1818 * directory handler).  Several default handlers are available to
1819 * cover common cases -
1820 *
1821 * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
1822 * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(), 
1823 * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax()
1824 *
1825 * It is the handler's job to read the input buffer from user memory
1826 * and process it. The handler should return 0 on success.
1827 *
1828 * This routine returns %NULL on a failure to register, and a pointer
1829 * to the table header on success.
1830 */
1831struct ctl_table_header *__register_sysctl_paths(
1832        struct ctl_table_root *root,
1833        struct nsproxy *namespaces,
1834        const struct ctl_path *path, struct ctl_table *table)
1835{
1836        struct ctl_table_header *header;
1837        struct ctl_table *new, **prevp;
1838        unsigned int n, npath;
1839        struct ctl_table_set *set;
1840
1841        /* Count the path components */
1842        for (npath = 0; path[npath].procname; ++npath)
1843                ;
1844
1845        /*
1846         * For each path component, allocate a 2-element ctl_table array.
1847         * The first array element will be filled with the sysctl entry
1848         * for this, the second will be the sentinel (procname == 0).
1849         *
1850         * We allocate everything in one go so that we don't have to
1851         * worry about freeing additional memory in unregister_sysctl_table.
1852         */
1853        header = kzalloc(sizeof(struct ctl_table_header) +
1854                         (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
1855        if (!header)
1856                return NULL;
1857
1858        new = (struct ctl_table *) (header + 1);
1859
1860        /* Now connect the dots */
1861        prevp = &header->ctl_table;
1862        for (n = 0; n < npath; ++n, ++path) {
1863                /* Copy the procname */
1864                new->procname = path->procname;
1865                new->mode     = 0555;
1866
1867                *prevp = new;
1868                prevp = &new->child;
1869
1870                new += 2;
1871        }
1872        *prevp = table;
1873        header->ctl_table_arg = table;
1874
1875        INIT_LIST_HEAD(&header->ctl_entry);
1876        header->used = 0;
1877        header->unregistering = NULL;
1878        header->root = root;
1879        sysctl_set_parent(NULL, header->ctl_table);
1880        header->count = 1;
1881#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
1882        if (sysctl_check_table(namespaces, header->ctl_table)) {
1883                kfree(header);
1884                return NULL;
1885        }
1886#endif
1887        spin_lock(&sysctl_lock);
1888        header->set = lookup_header_set(root, namespaces);
1889        header->attached_by = header->ctl_table;
1890        header->attached_to = root_table;
1891        header->parent = &root_table_header;
1892        for (set = header->set; set; set = set->parent) {
1893                struct ctl_table_header *p;
1894                list_for_each_entry(p, &set->list, ctl_entry) {
1895                        if (p->unregistering)
1896                                continue;
1897                        try_attach(p, header);
1898                }
1899        }
1900        header->parent->count++;
1901        list_add_tail(&header->ctl_entry, &header->set->list);
1902        spin_unlock(&sysctl_lock);
1903
1904        return header;
1905}
1906
1907/**
1908 * register_sysctl_table_path - register a sysctl table hierarchy
1909 * @path: The path to the directory the sysctl table is in.
1910 * @table: the top-level table structure
1911 *
1912 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
1913 * array. A completely 0 filled entry terminates the table.
1914 *
1915 * See __register_sysctl_paths for more details.
1916 */
1917struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
1918                                                struct ctl_table *table)
1919{
1920        return __register_sysctl_paths(&sysctl_table_root, current->nsproxy,
1921                                        path, table);
1922}
1923
1924/**
1925 * register_sysctl_table - register a sysctl table hierarchy
1926 * @table: the top-level table structure
1927 *
1928 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
1929 * array. A completely 0 filled entry terminates the table.
1930 *
1931 * See register_sysctl_paths for more details.
1932 */
1933struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
1934{
1935        static const struct ctl_path null_path[] = { {} };
1936
1937        return register_sysctl_paths(null_path, table);
1938}
1939
1940/**
1941 * unregister_sysctl_table - unregister a sysctl table hierarchy
1942 * @header: the header returned from register_sysctl_table
1943 *
1944 * Unregisters the sysctl table and all children. proc entries may not
1945 * actually be removed until they are no longer used by anyone.
1946 */
1947void unregister_sysctl_table(struct ctl_table_header * header)
1948{
1949        might_sleep();
1950
1951        if (header == NULL)
1952                return;
1953
1954        spin_lock(&sysctl_lock);
1955        start_unregistering(header);
1956        if (!--header->parent->count) {
1957                WARN_ON(1);
1958                kfree(header->parent);
1959        }
1960        if (!--header->count)
1961                kfree(header);
1962        spin_unlock(&sysctl_lock);
1963}
1964
1965int sysctl_is_seen(struct ctl_table_header *p)
1966{
1967        struct ctl_table_set *set = p->set;
1968        int res;
1969        spin_lock(&sysctl_lock);
1970        if (p->unregistering)
1971                res = 0;
1972        else if (!set->is_seen)
1973                res = 1;
1974        else
1975                res = set->is_seen(set);
1976        spin_unlock(&sysctl_lock);
1977        return res;
1978}
1979
1980void setup_sysctl_set(struct ctl_table_set *p,
1981        struct ctl_table_set *parent,
1982        int (*is_seen)(struct ctl_table_set *))
1983{
1984        INIT_LIST_HEAD(&p->list);
1985        p->parent = parent ? parent : &sysctl_table_root.default_set;
1986        p->is_seen = is_seen;
1987}
1988
1989#else /* !CONFIG_SYSCTL */
1990struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
1991{
1992        return NULL;
1993}
1994
1995struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
1996                                                    struct ctl_table *table)
1997{
1998        return NULL;
1999}
2000
2001void unregister_sysctl_table(struct ctl_table_header * table)
2002{
2003}
2004
2005void setup_sysctl_set(struct ctl_table_set *p,
2006        struct ctl_table_set *parent,
2007        int (*is_seen)(struct ctl_table_set *))
2008{
2009}
2010
2011void sysctl_head_put(struct ctl_table_header *head)
2012{
2013}
2014
2015#endif /* CONFIG_SYSCTL */
2016
2017/*
2018 * /proc/sys support
2019 */
2020
2021#ifdef CONFIG_PROC_SYSCTL
2022
2023static int _proc_do_string(void* data, int maxlen, int write,
2024                           void __user *buffer,
2025                           size_t *lenp, loff_t *ppos)
2026{
2027        size_t len;
2028        char __user *p;
2029        char c;
2030
2031        if (!data || !maxlen || !*lenp) {
2032                *lenp = 0;
2033                return 0;
2034        }
2035
2036        if (write) {
2037                len = 0;
2038                p = buffer;
2039                while (len < *lenp) {
2040                        if (get_user(c, p++))
2041                                return -EFAULT;
2042                        if (c == 0 || c == '\n')
2043                                break;
2044                        len++;
2045                }
2046                if (len >= maxlen)
2047                        len = maxlen-1;
2048                if(copy_from_user(data, buffer, len))
2049                        return -EFAULT;
2050                ((char *) data)[len] = 0;
2051                *ppos += *lenp;
2052        } else {
2053                len = strlen(data);
2054                if (len > maxlen)
2055                        len = maxlen;
2056
2057                if (*ppos > len) {
2058                        *lenp = 0;
2059                        return 0;
2060                }
2061
2062                data += *ppos;
2063                len  -= *ppos;
2064
2065                if (len > *lenp)
2066                        len = *lenp;
2067                if (len)
2068                        if(copy_to_user(buffer, data, len))
2069                                return -EFAULT;
2070                if (len < *lenp) {
2071                        if(put_user('\n', ((char __user *) buffer) + len))
2072                                return -EFAULT;
2073                        len++;
2074                }
2075                *lenp = len;
2076                *ppos += len;
2077        }
2078        return 0;
2079}
2080
2081/**
2082 * proc_dostring - read a string sysctl
2083 * @table: the sysctl table
2084 * @write: %TRUE if this is a write to the sysctl file
2085 * @buffer: the user buffer
2086 * @lenp: the size of the user buffer
2087 * @ppos: file position
2088 *
2089 * Reads/writes a string from/to the user buffer. If the kernel
2090 * buffer provided is not large enough to hold the string, the
2091 * string is truncated. The copied string is %NULL-terminated.
2092 * If the string is being read by the user process, it is copied
2093 * and a newline '\n' is added. It is truncated if the buffer is
2094 * not large enough.
2095 *
2096 * Returns 0 on success.
2097 */
2098int proc_dostring(struct ctl_table *table, int write,
2099                  void __user *buffer, size_t *lenp, loff_t *ppos)
2100{
2101        return _proc_do_string(table->data, table->maxlen, write,
2102                               buffer, lenp, ppos);
2103}
2104
2105static size_t proc_skip_spaces(char **buf)
2106{
2107        size_t ret;
2108        char *tmp = skip_spaces(*buf);
2109        ret = tmp - *buf;
2110        *buf = tmp;
2111        return ret;
2112}
2113
2114static void proc_skip_char(char **buf, size_t *size, const char v)
2115{
2116        while (*size) {
2117                if (**buf != v)
2118                        break;
2119                (*size)--;
2120                (*buf)++;
2121        }
2122}
2123
2124#define TMPBUFLEN 22
2125/**
2126 * proc_get_long - reads an ASCII formatted integer from a user buffer
2127 *
2128 * @buf: a kernel buffer
2129 * @size: size of the kernel buffer
2130 * @val: this is where the number will be stored
2131 * @neg: set to %TRUE if number is negative
2132 * @perm_tr: a vector which contains the allowed trailers
2133 * @perm_tr_len: size of the perm_tr vector
2134 * @tr: pointer to store the trailer character
2135 *
2136 * In case of success %0 is returned and @buf and @size are updated with
2137 * the amount of bytes read. If @tr is non-NULL and a trailing
2138 * character exists (size is non-zero after returning from this
2139 * function), @tr is updated with the trailing character.
2140 */
2141static int proc_get_long(char **buf, size_t *size,
2142                          unsigned long *val, bool *neg,
2143                          const char *perm_tr, unsigned perm_tr_len, char *tr)
2144{
2145        int len;
2146        char *p, tmp[TMPBUFLEN];
2147
2148        if (!*size)
2149                return -EINVAL;
2150
2151        len = *size;
2152        if (len > TMPBUFLEN - 1)
2153                len = TMPBUFLEN - 1;
2154
2155        memcpy(tmp, *buf, len);
2156
2157        tmp[len] = 0;
2158        p = tmp;
2159        if (*p == '-' && *size > 1) {
2160                *neg = true;
2161                p++;
2162        } else
2163                *neg = false;
2164        if (!isdigit(*p))
2165                return -EINVAL;
2166
2167        *val = simple_strtoul(p, &p, 0);
2168
2169        len = p - tmp;
2170
2171        /* We don't know if the next char is whitespace thus we may accept
2172         * invalid integers (e.g. 1234...a) or two integers instead of one
2173         * (e.g. 123...1). So lets not allow such large numbers. */
2174        if (len == TMPBUFLEN - 1)
2175                return -EINVAL;
2176
2177        if (len < *size && perm_tr_len && !memchr(perm_tr, *p, perm_tr_len))
2178                return -EINVAL;
2179
2180        if (tr && (len < *size))
2181                *tr = *p;
2182
2183        *buf += len;
2184        *size -= len;
2185
2186        return 0;
2187}
2188
2189/**
2190 * proc_put_long - converts an integer to a decimal ASCII formatted string
2191 *
2192 * @buf: the user buffer
2193 * @size: the size of the user buffer
2194 * @val: the integer to be converted
2195 * @neg: sign of the number, %TRUE for negative
2196 *
2197 * In case of success %0 is returned and @buf and @size are updated with
2198 * the amount of bytes written.
2199 */
2200static int proc_put_long(void __user **buf, size_t *size, unsigned long val,
2201                          bool neg)
2202{
2203        int len;
2204        char tmp[TMPBUFLEN], *p = tmp;
2205
2206        sprintf(p, "%s%lu", neg ? "-" : "", val);
2207        len = strlen(tmp);
2208        if (len > *size)
2209                len = *size;
2210        if (copy_to_user(*buf, tmp, len))
2211                return -EFAULT;
2212        *size -= len;
2213        *buf += len;
2214        return 0;
2215}
2216#undef TMPBUFLEN
2217
2218static int proc_put_char(void __user **buf, size_t *size, char c)
2219{
2220        if (*size) {
2221                char __user **buffer = (char __user **)buf;
2222                if (put_user(c, *buffer))
2223                        return -EFAULT;
2224                (*size)--, (*buffer)++;
2225                *buf = *buffer;
2226        }
2227        return 0;
2228}
2229
2230static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp,
2231                                 int *valp,
2232                                 int write, void *data)
2233{
2234        if (write) {
2235                *valp = *negp ? -*lvalp : *lvalp;
2236        } else {
2237                int val = *valp;
2238                if (val < 0) {
2239                        *negp = true;
2240                        *lvalp = (unsigned long)-val;
2241                } else {
2242                        *negp = false;
2243                        *lvalp = (unsigned long)val;
2244                }
2245        }
2246        return 0;
2247}
2248
2249static const char proc_wspace_sep[] = { ' ', '\t', '\n' };
2250
2251static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
2252                  int write, void __user *buffer,
2253                  size_t *lenp, loff_t *ppos,
2254                  int (*conv)(bool *negp, unsigned long *lvalp, int *valp,
2255                              int write, void *data),
2256                  void *data)
2257{
2258        int *i, vleft, first = 1, err = 0;
2259        unsigned long page = 0;
2260        size_t left;
2261        char *kbuf;
2262        
2263        if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {
2264                *lenp = 0;
2265                return 0;
2266        }
2267        
2268        i = (int *) tbl_data;
2269        vleft = table->maxlen / sizeof(*i);
2270        left = *lenp;
2271
2272        if (!conv)
2273                conv = do_proc_dointvec_conv;
2274
2275        if (write) {
2276                if (left > PAGE_SIZE - 1)
2277                        left = PAGE_SIZE - 1;
2278                page = __get_free_page(GFP_TEMPORARY);
2279                kbuf = (char *) page;
2280                if (!kbuf)
2281                        return -ENOMEM;
2282                if (copy_from_user(kbuf, buffer, left)) {
2283                        err = -EFAULT;
2284                        goto free;
2285                }
2286                kbuf[left] = 0;
2287        }
2288
2289        for (; left && vleft--; i++, first=0) {
2290                unsigned long lval;
2291                bool neg;
2292
2293                if (write) {
2294                        left -= proc_skip_spaces(&kbuf);
2295
2296                        if (!left)
2297                                break;
2298                        err = proc_get_long(&kbuf, &left, &lval, &neg,
2299                                             proc_wspace_sep,
2300                                             sizeof(proc_wspace_sep), NULL);
2301                        if (err)
2302                                break;
2303                        if (conv(&neg, &lval, i, 1, data)) {
2304                                err = -EINVAL;
2305                                break;
2306                        }
2307                } else {
2308                        if (conv(&neg, &lval, i, 0, data)) {
2309                                err = -EINVAL;
2310                                break;
2311                        }
2312                        if (!first)
2313                                err = proc_put_char(&buffer, &left, '\t');
2314                        if (err)
2315                                break;
2316                        err = proc_put_long(&buffer, &left, lval, neg);
2317                        if (err)
2318                                break;
2319                }
2320        }
2321
2322        if (!write && !first && left && !err)
2323                err = proc_put_char(&buffer, &left, '\n');
2324        if (write && !err && left)
2325                left -= proc_skip_spaces(&kbuf);
2326free:
2327        if (write) {
2328                free_page(page);
2329                if (first)
2330                        return err ? : -EINVAL;
2331        }
2332        *lenp -= left;
2333        *ppos += *lenp;
2334        return err;
2335}
2336
2337static int do_proc_dointvec(struct ctl_table *table, int write,
2338                  void __user *buffer, size_t *lenp, loff_t *ppos,
2339                  int (*conv)(bool *negp, unsigned long *lvalp, int *valp,
2340                              int write, void *data),
2341                  void *data)
2342{
2343        return __do_proc_dointvec(table->data, table, write,
2344                        buffer, lenp, ppos, conv, data);
2345}
2346
2347/**
2348 * proc_dointvec - read a vector of integers
2349 * @table: the sysctl table
2350 * @write: %TRUE if this is a write to the sysctl file
2351 * @buffer: the user buffer
2352 * @lenp: the size of the user buffer
2353 * @ppos: file position
2354 *
2355 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2356 * values from/to the user buffer, treated as an ASCII string. 
2357 *
2358 * Returns 0 on success.
2359 */
2360int proc_dointvec(struct ctl_table *table, int write,
2361                     void __user *buffer, size_t *lenp, loff_t *ppos)
2362{
2363    return do_proc_dointvec(table,write,buffer,lenp,ppos,
2364                            NULL,NULL);
2365}
2366
2367/*
2368 * Taint values can only be increased
2369 * This means we can safely use a temporary.
2370 */
2371static int proc_taint(struct ctl_table *table, int write,
2372                               void __user *buffer, size_t *lenp, loff_t *ppos)
2373{
2374        struct ctl_table t;
2375        unsigned long tmptaint = get_taint();
2376        int err;
2377
2378        if (write && !capable(CAP_SYS_ADMIN))
2379                return -EPERM;
2380
2381        t = *table;
2382        t.data = &tmptaint;
2383        err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos);
2384        if (err < 0)
2385                return err;
2386
2387        if (write) {
2388                /*
2389                 * Poor man's atomic or. Not worth adding a primitive
2390                 * to everyone's atomic.h for this
2391                 */
2392                int i;
2393                for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
2394                        if ((tmptaint >> i) & 1)
2395                                add_taint(i);
2396                }
2397        }
2398
2399        return err;
2400}
2401
2402struct do_proc_dointvec_minmax_conv_param {
2403        int *min;
2404        int *max;
2405};
2406
2407static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp,
2408                                        int *valp,
2409                                        int write, void *data)
2410{
2411        struct do_proc_dointvec_minmax_conv_param *param = data;
2412        if (write) {
2413                int val = *negp ? -*lvalp : *lvalp;
2414                if ((param->min && *param->min > val) ||
2415                    (param->max && *param->max < val))
2416                        return -EINVAL;
2417                *valp = val;
2418        } else {
2419                int val = *valp;
2420                if (val < 0) {
2421                        *negp = true;
2422                        *lvalp = (unsigned long)-val;
2423                } else {
2424                        *negp = false;
2425                        *lvalp = (unsigned long)val;
2426                }
2427        }
2428        return 0;
2429}
2430
2431/**
2432 * proc_dointvec_minmax - read a vector of integers with min/max values
2433 * @table: the sysctl table
2434 * @write: %TRUE if this is a write to the sysctl file
2435 * @buffer: the user buffer
2436 * @lenp: the size of the user buffer
2437 * @ppos: file position
2438 *
2439 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2440 * values from/to the user buffer, treated as an ASCII string.
2441 *
2442 * This routine will ensure the values are within the range specified by
2443 * table->extra1 (min) and table->extra2 (max).
2444 *
2445 * Returns 0 on success.
2446 */
2447int proc_dointvec_minmax(struct ctl_table *table, int write,
2448                  void __user *buffer, size_t *lenp, loff_t *ppos)
2449{
2450        struct do_proc_dointvec_minmax_conv_param param = {
2451                .min = (int *) table->extra1,
2452                .max = (int *) table->extra2,
2453        };
2454        return do_proc_dointvec(table, write, buffer, lenp, ppos,
2455                                do_proc_dointvec_minmax_conv, &param);
2456}
2457
2458static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
2459                                     void __user *buffer,
2460                                     size_t *lenp, loff_t *ppos,
2461                                     unsigned long convmul,
2462                                     unsigned long convdiv)
2463{
2464        unsigned long *i, *min, *max;
2465        int vleft, first = 1, err = 0;
2466        unsigned long page = 0;
2467        size_t left;
2468        char *kbuf;
2469
2470        if (!data || !table->maxlen || !*lenp || (*ppos && !write)) {
2471                *lenp = 0;
2472                return 0;
2473        }
2474
2475        i = (unsigned long *) data;
2476        min = (unsigned long *) table->extra1;
2477        max = (unsigned long *) table->extra2;
2478        vleft = table->maxlen / sizeof(unsigned long);
2479        left = *lenp;
2480
2481        if (write) {
2482                if (left > PAGE_SIZE - 1)
2483                        left = PAGE_SIZE - 1;
2484                page = __get_free_page(GFP_TEMPORARY);
2485                kbuf = (char *) page;
2486                if (!kbuf)
2487                        return -ENOMEM;
2488                if (copy_from_user(kbuf, buffer, left)) {
2489                        err = -EFAULT;
2490                        goto free;
2491                }
2492                kbuf[left] = 0;
2493        }
2494
2495        for (; left && vleft--; i++, first = 0) {
2496                unsigned long val;
2497
2498                if (write) {
2499                        bool neg;
2500
2501                        left -= proc_skip_spaces(&kbuf);
2502
2503                        err = proc_get_long(&kbuf, &left, &val, &neg,
2504                                             proc_wspace_sep,
2505                                             sizeof(proc_wspace_sep), NULL);
2506                        if (err)
2507                                break;
2508                        if (neg)
2509                                continue;
2510                        if ((min && val < *min) || (max && val > *max))
2511                                continue;
2512                        *i = val;
2513                } else {
2514                        val = convdiv * (*i) / convmul;
2515                        if (!first)
2516                                err = proc_put_char(&buffer, &left, '\t');
2517                        err = proc_put_long(&buffer, &left, val, false);
2518                        if (err)
2519                                break;
2520                }
2521        }
2522
2523        if (!write && !first && left && !err)
2524                err = proc_put_char(&buffer, &left, '\n');
2525        if (write && !err)
2526                left -= proc_skip_spaces(&kbuf);
2527free:
2528        if (write) {
2529                free_page(page);
2530                if (first)
2531                        return err ? : -EINVAL;
2532        }
2533        *lenp -= left;
2534        *ppos += *lenp;
2535        return err;
2536}
2537
2538static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
2539                                     void __user *buffer,
2540                                     size_t *lenp, loff_t *ppos,
2541                                     unsigned long convmul,
2542                                     unsigned long convdiv)
2543{
2544        return __do_proc_doulongvec_minmax(table->data, table, write,
2545                        buffer, lenp, ppos, convmul, convdiv);
2546}
2547
2548/**
2549 * proc_doulongvec_minmax - read a vector of long integers with min/max values
2550 * @table: the sysctl table
2551 * @write: %TRUE if this is a write to the sysctl file
2552 * @buffer: the user buffer
2553 * @lenp: the size of the user buffer
2554 * @ppos: file position
2555 *
2556 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
2557 * values from/to the user buffer, treated as an ASCII string.
2558 *
2559 * This routine will ensure the values are within the range specified by
2560 * table->extra1 (min) and table->extra2 (max).
2561 *
2562 * Returns 0 on success.
2563 */
2564int proc_doulongvec_minmax(struct ctl_table *table, int write,
2565                           void __user *buffer, size_t *lenp, loff_t *ppos)
2566{
2567    return do_proc_doulongvec_minmax(table, write, buffer, lenp, ppos, 1l, 1l);
2568}
2569
2570/**
2571 * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
2572 * @table: the sysctl table
2573 * @write: %TRUE if this is a write to the sysctl file
2574 * @buffer: the user buffer
2575 * @lenp: the size of the user buffer
2576 * @ppos: file position
2577 *
2578 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
2579 * values from/to the user buffer, treated as an ASCII string. The values
2580 * are treated as milliseconds, and converted to jiffies when they are stored.
2581 *
2582 * This routine will ensure the values are within the range specified by
2583 * table->extra1 (min) and table->extra2 (max).
2584 *
2585 * Returns 0 on success.
2586 */
2587int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
2588                                      void __user *buffer,
2589                                      size_t *lenp, loff_t *ppos)
2590{
2591    return do_proc_doulongvec_minmax(table, write, buffer,
2592                                     lenp, ppos, HZ, 1000l);
2593}
2594
2595
2596static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *lvalp,
2597                                         int *valp,
2598                                         int write, void *data)
2599{
2600        if (write) {
2601                if (*lvalp > LONG_MAX / HZ)
2602                        return 1;
2603                *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ);
2604        } else {
2605                int val = *valp;
2606                unsigned long lval;
2607                if (val < 0) {
2608                        *negp = true;
2609                        lval = (unsigned long)-val;
2610                } else {
2611                        *negp = false;
2612                        lval = (unsigned long)val;
2613                }
2614                *lvalp = lval / HZ;
2615        }
2616        return 0;
2617}
2618
2619static int do_proc_dointvec_userhz_jiffies_conv(bool *negp, unsigned long *lvalp,
2620                                                int *valp,
2621                                                int write, void *data)
2622{
2623        if (write) {
2624                if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ)
2625                        return 1;
2626                *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp);
2627        } else {
2628                int val = *valp;
2629                unsigned long lval;
2630                if (val < 0) {
2631                        *negp = true;
2632                        lval = (unsigned long)-val;
2633                } else {
2634                        *negp = false;
2635                        lval = (unsigned long)val;
2636                }
2637                *lvalp = jiffies_to_clock_t(lval);
2638        }
2639        return 0;
2640}
2641
2642static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *lvalp,
2643                                            int *valp,
2644                                            int write, void *data)
2645{
2646        if (write) {
2647                *valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp);
2648        } else {
2649                int val = *valp;
2650                unsigned long lval;
2651                if (val < 0) {
2652                        *negp = true;
2653                        lval = (unsigned long)-val;
2654                } else {
2655                        *negp = false;
2656                        lval = (unsigned long)val;
2657                }
2658                *lvalp = jiffies_to_msecs(lval);
2659        }
2660        return 0;
2661}
2662
2663/**
2664 * proc_dointvec_jiffies - read a vector of integers as seconds
2665 * @table: the sysctl table
2666 * @write: %TRUE if this is a write to the sysctl file
2667 * @buffer: the user buffer
2668 * @lenp: the size of the user buffer
2669 * @ppos: file position
2670 *
2671 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2672 * values from/to the user buffer, treated as an ASCII string. 
2673 * The values read are assumed to be in seconds, and are converted into
2674 * jiffies.
2675 *
2676 * Returns 0 on success.
2677 */
2678int proc_dointvec_jiffies(struct ctl_table *table, int write,
2679                          void __user *buffer, size_t *lenp, loff_t *ppos)
2680{
2681    return do_proc_dointvec(table,write,buffer,lenp,ppos,
2682                            do_proc_dointvec_jiffies_conv,NULL);
2683}
2684
2685/**
2686 * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
2687 * @table: the sysctl table
2688 * @write: %TRUE if this is a write to the sysctl file
2689 * @buffer: the user buffer
2690 * @lenp: the size of the user buffer
2691 * @ppos: pointer to the file position
2692 *
2693 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2694 * values from/to the user buffer, treated as an ASCII string. 
2695 * The values read are assumed to be in 1/USER_HZ seconds, and 
2696 * are converted into jiffies.
2697 *
2698 * Returns 0 on success.
2699 */
2700int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write,
2701                                 void __user *buffer, size_t *lenp, loff_t *ppos)
2702{
2703    return do_proc_dointvec(table,write,buffer,lenp,ppos,
2704                            do_proc_dointvec_userhz_jiffies_conv,NULL);
2705}
2706
2707/**
2708 * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds
2709 * @table: the sysctl table
2710 * @write: %TRUE if this is a write to the sysctl file
2711 * @buffer: the user buffer
2712 * @lenp: the size of the user buffer
2713 * @ppos: file position
2714 * @ppos: the current position in the file
2715 *
2716 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2717 * values from/to the user buffer, treated as an ASCII string. 
2718 * The values read are assumed to be in 1/1000 seconds, and 
2719 * are converted into jiffies.
2720 *
2721 * Returns 0 on success.
2722 */
2723int proc_dointvec_ms_jiffies(struct ctl_table *table, int write,
2724                             void __user *buffer, size_t *lenp, loff_t *ppos)
2725{
2726        return do_proc_dointvec(table, write, buffer, lenp, ppos,
2727                                do_proc_dointvec_ms_jiffies_conv, NULL);
2728}
2729
2730static int proc_do_cad_pid(struct ctl_table *table, int write,
2731                           void __user *buffer, size_t *lenp, loff_t *ppos)
2732{
2733        struct pid *new_pid;
2734        pid_t tmp;
2735        int r;
2736
2737        tmp = pid_vnr(cad_pid);
2738
2739        r = __do_proc_dointvec(&tmp, table, write, buffer,
2740                               lenp, ppos, NULL, NULL);
2741        if (r || !write)
2742                return r;
2743
2744        new_pid = find_get_pid(tmp);
2745        if (!new_pid)
2746                return -ESRCH;
2747
2748        put_pid(xchg(&cad_pid, new_pid));
2749        return 0;
2750}
2751
2752/**
2753 * proc_do_large_bitmap - read/write from/to a large bitmap
2754 * @table: the sysctl table
2755 * @write: %TRUE if this is a write to the sysctl file
2756 * @buffer: the user buffer
2757 * @lenp: the size of the user buffer
2758 * @ppos: file position
2759 *
2760 * The bitmap is stored at table->data and the bitmap length (in bits)
2761 * in table->maxlen.
2762 *
2763 * We use a range comma separated format (e.g. 1,3-4,10-10) so that
2764 * large bitmaps may be represented in a compact manner. Writing into
2765 * the file will clear the bitmap then update it with the given input.
2766 *
2767 * Returns 0 on success.
2768 */
2769int proc_do_large_bitmap(struct ctl_table *table, int write,
2770                         void __user *buffer, size_t *lenp, loff_t *ppos)
2771{
2772        int err = 0;
2773        bool first = 1;
2774        size_t left = *lenp;
2775        unsigned long bitmap_len = table->maxlen;
2776        unsigned long *bitmap = (unsigned long *) table->data;
2777        unsigned long *tmp_bitmap = NULL;
2778        char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c;
2779
2780        if (!bitmap_len || !left || (*ppos && !write)) {
2781                *lenp = 0;
2782                return 0;
2783        }
2784
2785        if (write) {
2786                unsigned long page = 0;
2787                char *kbuf;
2788
2789                if (left > PAGE_SIZE - 1)
2790                        left = PAGE_SIZE - 1;
2791
2792                page = __get_free_page(GFP_TEMPORARY);
2793                kbuf = (char *) page;
2794                if (!kbuf)
2795                        return -ENOMEM;
2796                if (copy_from_user(kbuf, buffer, left)) {
2797                        free_page(page);
2798                        return -EFAULT;
2799                }
2800                kbuf[left] = 0;
2801
2802                tmp_bitmap = kzalloc(BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long),
2803                                     GFP_KERNEL);
2804                if (!tmp_bitmap) {
2805                        free_page(page);
2806                        return -ENOMEM;
2807                }
2808                proc_skip_char(&kbuf, &left, '\n');
2809                while (!err && left) {
2810                        unsigned long val_a, val_b;
2811                        bool neg;
2812
2813                        err = proc_get_long(&kbuf, &left, &val_a, &neg, tr_a,
2814                                             sizeof(tr_a), &c);
2815                        if (err)
2816                                break;
2817                        if (val_a >= bitmap_len || neg) {
2818                                err = -EINVAL;
2819                                break;
2820                        }
2821
2822                        val_b = val_a;
2823                        if (left) {
2824                                kbuf++;
2825                                left--;
2826                        }
2827
2828                        if (c == '-') {
2829                                err = proc_get_long(&kbuf, &left, &val_b,
2830                                                     &neg, tr_b, sizeof(tr_b),
2831                                                     &c);
2832                                if (err)
2833                                        break;
2834                                if (val_b >= bitmap_len || neg ||
2835                                    val_a > val_b) {
2836                                        err = -EINVAL;
2837                                        break;
2838                                }
2839                                if (left) {
2840                                        kbuf++;
2841                                        left--;
2842                                }
2843                        }
2844
2845                        while (val_a <= val_b)
2846                                set_bit(val_a++, tmp_bitmap);
2847
2848                        first = 0;
2849                        proc_skip_char(&kbuf, &left, '\n');
2850                }
2851                free_page(page);
2852        } else {
2853                unsigned long bit_a, bit_b = 0;
2854
2855                while (left) {
2856                        bit_a = find_next_bit(bitmap, bitmap_len, bit_b);
2857                        if (bit_a >= bitmap_len)
2858                                break;
2859                        bit_b = find_next_zero_bit(bitmap, bitmap_len,
2860                                                   bit_a + 1) - 1;
2861
2862                        if (!first) {
2863                                err = proc_put_char(&buffer, &left, ',');
2864                                if (err)
2865                                        break;
2866                        }
2867                        err = proc_put_long(&buffer, &left, bit_a, false);
2868                        if (err)
2869                                break;
2870                        if (bit_a != bit_b) {
2871                                err = proc_put_char(&buffer, &left, '-');
2872                                if (err)
2873                                        break;
2874                                err = proc_put_long(&buffer, &left, bit_b, false);
2875                                if (err)
2876                                        break;
2877                        }
2878
2879                        first = 0; bit_b++;
2880                }
2881                if (!err)
2882                        err = proc_put_char(&buffer, &left, '\n');
2883        }
2884
2885        if (!err) {
2886                if (write) {
2887                        if (*ppos)
2888                                bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len);
2889                        else
2890                                memcpy(bitmap, tmp_bitmap,
2891                                        BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long));
2892                }
2893                kfree(tmp_bitmap);
2894                *lenp -= left;
2895                *ppos += *lenp;
2896                return 0;
2897        } else {
2898                kfree(tmp_bitmap);
2899                return err;
2900        }
2901}
2902
2903#else /* CONFIG_PROC_FS */
2904
2905int proc_dostring(struct ctl_table *table, int write,
2906                  void __user *buffer, size_t *lenp, loff_t *ppos)
2907{
2908        return -ENOSYS;
2909}
2910
2911int proc_dointvec(struct ctl_table *table, int write,
2912                  void __user *buffer, size_t *lenp, loff_t *ppos)
2913{
2914        return -ENOSYS;
2915}
2916
2917int proc_dointvec_minmax(struct ctl_table *table, int write,
2918                    void __user *buffer, size_t *lenp, loff_t *ppos)
2919{
2920        return -ENOSYS;
2921}
2922
2923int proc_dointvec_jiffies(struct ctl_table *table, int write,
2924                    void __user *buffer, size_t *lenp, loff_t *ppos)
2925{
2926        return -ENOSYS;
2927}
2928
2929int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write,
2930                    void __user *buffer, size_t *lenp, loff_t *ppos)
2931{
2932        return -ENOSYS;
2933}
2934
2935int proc_dointvec_ms_jiffies(struct ctl_table *table, int write,
2936                             void __user *buffer, size_t *lenp, loff_t *ppos)
2937{
2938        return -ENOSYS;
2939}
2940
2941int proc_doulongvec_minmax(struct ctl_table *table, int write,
2942                    void __user *buffer, size_t *lenp, loff_t *ppos)
2943{
2944        return -ENOSYS;
2945}
2946
2947int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
2948                                      void __user *buffer,
2949                                      size_t *lenp, loff_t *ppos)
2950{
2951    return -ENOSYS;
2952}
2953
2954
2955#endif /* CONFIG_PROC_FS */
2956
2957/*
2958 * No sense putting this after each symbol definition, twice,
2959 * exception granted :-)
2960 */
2961EXPORT_SYMBOL(proc_dointvec);
2962EXPORT_SYMBOL(proc_dointvec_jiffies);
2963EXPORT_SYMBOL(proc_dointvec_minmax);
2964EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
2965EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
2966EXPORT_SYMBOL(proc_dostring);
2967EXPORT_SYMBOL(proc_doulongvec_minmax);
2968EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
2969EXPORT_SYMBOL(register_sysctl_table);
2970EXPORT_SYMBOL(register_sysctl_paths);
2971EXPORT_SYMBOL(unregister_sysctl_table);
2972
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.