diff options
Diffstat (limited to 'kernel/sysctl.c')
| -rw-r--r-- | kernel/sysctl.c | 1857 | 
1 files changed, 819 insertions, 1038 deletions
| diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 62e4ff9968b..ae5cbb1e3ce 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -23,12 +23,11 @@  #include <linux/swap.h>  #include <linux/slab.h>  #include <linux/sysctl.h> +#include <linux/signal.h>  #include <linux/proc_fs.h>  #include <linux/security.h>  #include <linux/ctype.h> -#include <linux/utsname.h>  #include <linux/kmemcheck.h> -#include <linux/smp_lock.h>  #include <linux/fs.h>  #include <linux/init.h>  #include <linux/kernel.h> @@ -37,20 +36,25 @@  #include <linux/sysrq.h>  #include <linux/highuid.h>  #include <linux/writeback.h> +#include <linux/ratelimit.h> +#include <linux/compaction.h>  #include <linux/hugetlb.h>  #include <linux/initrd.h>  #include <linux/key.h>  #include <linux/times.h>  #include <linux/limits.h>  #include <linux/dcache.h> +#include <linux/dnotify.h>  #include <linux/syscalls.h>  #include <linux/vmstat.h>  #include <linux/nfs_fs.h>  #include <linux/acpi.h>  #include <linux/reboot.h>  #include <linux/ftrace.h> -#include <linux/slow-work.h> -#include <linux/perf_counter.h> +#include <linux/perf_event.h> +#include <linux/kprobes.h> +#include <linux/pipe_fs_i.h> +#include <linux/oom.h>  #include <asm/uaccess.h>  #include <asm/processor.h> @@ -60,23 +64,34 @@  #include <asm/stacktrace.h>  #include <asm/io.h>  #endif +#ifdef CONFIG_BSD_PROCESS_ACCT +#include <linux/acct.h> +#endif +#ifdef CONFIG_RT_MUTEXES +#include <linux/rtmutex.h> +#endif +#if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_LOCK_STAT) +#include <linux/lockdep.h> +#endif +#ifdef CONFIG_CHR_DEV_SG +#include <scsi/sg.h> +#endif + +#ifdef CONFIG_LOCKUP_DETECTOR +#include <linux/nmi.h> +#endif -static int deprecated_sysctl_warning(struct __sysctl_args *args);  #if defined(CONFIG_SYSCTL)  /* External variables not in a header file. */ -extern int C_A_D; -extern int print_fatal_signals;  extern int sysctl_overcommit_memory;  extern int sysctl_overcommit_ratio; -extern int sysctl_panic_on_oom; -extern int sysctl_oom_kill_allocating_task; -extern int sysctl_oom_dump_tasks;  extern int max_threads;  extern int core_uses_pid;  extern int suid_dumpable;  extern char core_pattern[]; +extern unsigned int core_pipe_limit;  extern int pid_max;  extern int min_free_kbytes;  extern int pid_max_min, pid_max_max; @@ -88,12 +103,12 @@ extern int sysctl_nr_open_min, sysctl_nr_open_max;  #ifndef CONFIG_MMU  extern int sysctl_nr_trim_pages;  #endif -#ifdef CONFIG_RCU_TORTURE_TEST -extern int rcutorture_runnable; -#endif /* #ifdef CONFIG_RCU_TORTURE_TEST */ +#ifdef CONFIG_BLOCK +extern int blk_iopoll_enabled; +#endif  /* Constants used for minimum and  maximum */ -#ifdef CONFIG_DETECT_SOFTLOCKUP +#ifdef CONFIG_LOCKUP_DETECTOR  static int sixty = 60;  static int neg_one = -1;  #endif @@ -103,6 +118,9 @@ static int __maybe_unused one = 1;  static int __maybe_unused two = 2;  static unsigned long one_ul = 1;  static int one_hundred = 100; +#ifdef CONFIG_PRINTK +static int ten_thousand = 10000; +#endif  /* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */  static unsigned long dirty_bytes_min = 2 * PAGE_SIZE; @@ -114,14 +132,9 @@ static int min_percpu_pagelist_fract = 8;  static int ngroups_max = NGROUPS_MAX; -#ifdef CONFIG_MODULES -extern char modprobe_path[]; -extern int modules_disabled; -#endif -#ifdef CONFIG_CHR_DEV_SG -extern int sg_big_buff; +#ifdef CONFIG_INOTIFY_USER +#include <linux/inotify.h>  #endif -  #ifdef CONFIG_SPARC  #include <asm/system.h>  #endif @@ -143,26 +156,39 @@ extern int sysctl_userprocess_debug;  extern int spin_retry;  #endif -#ifdef CONFIG_BSD_PROCESS_ACCT -extern int acct_parm[]; -#endif -  #ifdef CONFIG_IA64  extern int no_unaligned_warning;  extern int unaligned_dump_stack;  #endif -#ifdef CONFIG_RT_MUTEXES -extern int max_lock_depth; -#endif -  #ifdef CONFIG_PROC_SYSCTL -static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, +static int proc_do_cad_pid(struct ctl_table *table, int write,  		  void __user *buffer, size_t *lenp, loff_t *ppos); -static int proc_taint(struct ctl_table *table, int write, struct file *filp, +static int proc_taint(struct ctl_table *table, int write,  			       void __user *buffer, size_t *lenp, loff_t *ppos);  #endif +#ifdef CONFIG_MAGIC_SYSRQ +static int __sysrq_enabled; /* Note: sysrq code ises it's own private copy */ + +static int sysrq_sysctl_handler(ctl_table *table, int write, +				void __user *buffer, size_t *lenp, +				loff_t *ppos) +{ +	int error; + +	error = proc_dointvec(table, write, buffer, lenp, ppos); +	if (error) +		return error; + +	if (write) +		sysrq_toggle_support(__sysrq_enabled); + +	return 0; +} + +#endif +  static struct ctl_table root_table[];  static struct ctl_table_root sysctl_table_root;  static struct ctl_table_header root_table_header = { @@ -183,9 +209,6 @@ static struct ctl_table fs_table[];  static struct ctl_table debug_table[];  static struct ctl_table dev_table[];  extern struct ctl_table random_table[]; -#ifdef CONFIG_INOTIFY_USER -extern struct ctl_table inotify_table[]; -#endif  #ifdef CONFIG_EPOLL  extern struct ctl_table epoll_table[];  #endif @@ -194,38 +217,30 @@ extern struct ctl_table epoll_table[];  int sysctl_legacy_va_layout;  #endif -extern int prove_locking; -extern int lock_stat; -  /* The default sysctl tables: */  static struct ctl_table root_table[] = {  	{ -		.ctl_name	= CTL_KERN,  		.procname	= "kernel",  		.mode		= 0555,  		.child		= kern_table,  	},  	{ -		.ctl_name	= CTL_VM,  		.procname	= "vm",  		.mode		= 0555,  		.child		= vm_table,  	},  	{ -		.ctl_name	= CTL_FS,  		.procname	= "fs",  		.mode		= 0555,  		.child		= fs_table,  	},  	{ -		.ctl_name	= CTL_DEBUG,  		.procname	= "debug",  		.mode		= 0555,  		.child		= debug_table,  	},  	{ -		.ctl_name	= CTL_DEV,  		.procname	= "dev",  		.mode		= 0555,  		.child		= dev_table, @@ -234,7 +249,7 @@ static struct ctl_table root_table[] = {   * NOTE: do not add new entries to this table unless you have read   * Documentation/sysctl/ctl_unnumbered.txt   */ -	{ .ctl_name = 0 } +	{ }  };  #ifdef CONFIG_SCHED_DEBUG @@ -242,177 +257,182 @@ static int min_sched_granularity_ns = 100000;		/* 100 usecs */  static int max_sched_granularity_ns = NSEC_PER_SEC;	/* 1 second */  static int min_wakeup_granularity_ns;			/* 0 usecs */  static int max_wakeup_granularity_ns = NSEC_PER_SEC;	/* 1 second */ +static int min_sched_tunable_scaling = SCHED_TUNABLESCALING_NONE; +static int max_sched_tunable_scaling = SCHED_TUNABLESCALING_END-1; +#endif + +#ifdef CONFIG_COMPACTION +static int min_extfrag_threshold; +static int max_extfrag_threshold = 1000;  #endif  static struct ctl_table kern_table[] = { +	{ +		.procname	= "sched_child_runs_first", +		.data		= &sysctl_sched_child_runs_first, +		.maxlen		= sizeof(unsigned int), +		.mode		= 0644, +		.proc_handler	= proc_dointvec, +	},  #ifdef CONFIG_SCHED_DEBUG  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "sched_min_granularity_ns",  		.data		= &sysctl_sched_min_granularity,  		.maxlen		= sizeof(unsigned int),  		.mode		= 0644, -		.proc_handler	= &sched_nr_latency_handler, -		.strategy	= &sysctl_intvec, +		.proc_handler	= sched_proc_update_handler,  		.extra1		= &min_sched_granularity_ns,  		.extra2		= &max_sched_granularity_ns,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "sched_latency_ns",  		.data		= &sysctl_sched_latency,  		.maxlen		= sizeof(unsigned int),  		.mode		= 0644, -		.proc_handler	= &sched_nr_latency_handler, -		.strategy	= &sysctl_intvec, +		.proc_handler	= sched_proc_update_handler,  		.extra1		= &min_sched_granularity_ns,  		.extra2		= &max_sched_granularity_ns,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "sched_wakeup_granularity_ns",  		.data		= &sysctl_sched_wakeup_granularity,  		.maxlen		= sizeof(unsigned int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= sched_proc_update_handler,  		.extra1		= &min_wakeup_granularity_ns,  		.extra2		= &max_wakeup_granularity_ns,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "sched_shares_ratelimit", -		.data		= &sysctl_sched_shares_ratelimit, -		.maxlen		= sizeof(unsigned int), +		.procname	= "sched_tunable_scaling", +		.data		= &sysctl_sched_tunable_scaling, +		.maxlen		= sizeof(enum sched_tunable_scaling),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= sched_proc_update_handler, +		.extra1		= &min_sched_tunable_scaling, +		.extra2		= &max_sched_tunable_scaling,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "sched_shares_thresh", -		.data		= &sysctl_sched_shares_thresh, -		.maxlen		= sizeof(unsigned int), -		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, -		.extra1		= &zero, -	}, -	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "sched_child_runs_first", -		.data		= &sysctl_sched_child_runs_first, +		.procname	= "sched_migration_cost", +		.data		= &sysctl_sched_migration_cost,  		.maxlen		= sizeof(unsigned int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "sched_features", -		.data		= &sysctl_sched_features, +		.procname	= "sched_nr_migrate", +		.data		= &sysctl_sched_nr_migrate,  		.maxlen		= sizeof(unsigned int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "sched_migration_cost", -		.data		= &sysctl_sched_migration_cost, +		.procname	= "sched_time_avg", +		.data		= &sysctl_sched_time_avg,  		.maxlen		= sizeof(unsigned int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "sched_nr_migrate", -		.data		= &sysctl_sched_nr_migrate, +		.procname	= "sched_shares_window", +		.data		= &sysctl_sched_shares_window,  		.maxlen		= sizeof(unsigned int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "timer_migration",  		.data		= &sysctl_timer_migration,  		.maxlen		= sizeof(unsigned int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &one,  	},  #endif  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "sched_rt_period_us",  		.data		= &sysctl_sched_rt_period,  		.maxlen		= sizeof(unsigned int),  		.mode		= 0644, -		.proc_handler	= &sched_rt_handler, +		.proc_handler	= sched_rt_handler,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "sched_rt_runtime_us",  		.data		= &sysctl_sched_rt_runtime,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &sched_rt_handler, +		.proc_handler	= sched_rt_handler,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "sched_compat_yield",  		.data		= &sysctl_sched_compat_yield,  		.maxlen		= sizeof(unsigned int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec, +	}, +#ifdef CONFIG_SCHED_AUTOGROUP +	{ +		.procname	= "sched_autogroup_enabled", +		.data		= &sysctl_sched_autogroup_enabled, +		.maxlen		= sizeof(unsigned int), +		.mode		= 0644, +		.proc_handler	= proc_dointvec, +		.extra1		= &zero, +		.extra2		= &one,  	}, +#endif  #ifdef CONFIG_PROVE_LOCKING  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "prove_locking",  		.data		= &prove_locking,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_LOCK_STAT  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "lock_stat",  		.data		= &lock_stat,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  	{ -		.ctl_name	= KERN_PANIC,  		.procname	= "panic",  		.data		= &panic_timeout,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= KERN_CORE_USES_PID,  		.procname	= "core_uses_pid",  		.data		= &core_uses_pid,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= KERN_CORE_PATTERN,  		.procname	= "core_pattern",  		.data		= core_pattern,  		.maxlen		= CORENAME_MAX_SIZE,  		.mode		= 0644, -		.proc_handler	= &proc_dostring, -		.strategy	= &sysctl_string, +		.proc_handler	= proc_dostring, +	}, +	{ +		.procname	= "core_pipe_limit", +		.data		= &core_pipe_limit, +		.maxlen		= sizeof(unsigned int), +		.mode		= 0644, +		.proc_handler	= proc_dointvec,  	},  #ifdef CONFIG_PROC_SYSCTL  	{  		.procname	= "tainted",  		.maxlen 	= sizeof(long),  		.mode		= 0644, -		.proc_handler	= &proc_taint, +		.proc_handler	= proc_taint,  	},  #endif  #ifdef CONFIG_LATENCYTOP @@ -421,181 +441,160 @@ static struct ctl_table kern_table[] = {  		.data		= &latencytop_enabled,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_BLK_DEV_INITRD  	{ -		.ctl_name	= KERN_REALROOTDEV,  		.procname	= "real-root-dev",  		.data		= &real_root_dev,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "print-fatal-signals",  		.data		= &print_fatal_signals,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #ifdef CONFIG_SPARC  	{ -		.ctl_name	= KERN_SPARC_REBOOT,  		.procname	= "reboot-cmd",  		.data		= reboot_command,  		.maxlen		= 256,  		.mode		= 0644, -		.proc_handler	= &proc_dostring, -		.strategy	= &sysctl_string, +		.proc_handler	= proc_dostring,  	},  	{ -		.ctl_name	= KERN_SPARC_STOP_A,  		.procname	= "stop-a",  		.data		= &stop_a_enabled,  		.maxlen		= sizeof (int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= KERN_SPARC_SCONS_PWROFF,  		.procname	= "scons-poweroff",  		.data		= &scons_pwroff,  		.maxlen		= sizeof (int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_SPARC64  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "tsb-ratio",  		.data		= &sysctl_tsb_ratio,  		.maxlen		= sizeof (int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef __hppa__  	{ -		.ctl_name	= KERN_HPPA_PWRSW,  		.procname	= "soft-power",  		.data		= &pwrsw_enabled,  		.maxlen		= sizeof (int),  	 	.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= KERN_HPPA_UNALIGNED,  		.procname	= "unaligned-trap",  		.data		= &unaligned_enabled,  		.maxlen		= sizeof (int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  	{ -		.ctl_name	= KERN_CTLALTDEL,  		.procname	= "ctrl-alt-del",  		.data		= &C_A_D,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #ifdef CONFIG_FUNCTION_TRACER  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "ftrace_enabled",  		.data		= &ftrace_enabled,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &ftrace_enable_sysctl, +		.proc_handler	= ftrace_enable_sysctl,  	},  #endif  #ifdef CONFIG_STACK_TRACER  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "stack_tracer_enabled",  		.data		= &stack_tracer_enabled,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &stack_trace_sysctl, +		.proc_handler	= stack_trace_sysctl,  	},  #endif  #ifdef CONFIG_TRACING  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "ftrace_dump_on_oops",  		.data		= &ftrace_dump_on_oops,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_MODULES  	{ -		.ctl_name	= KERN_MODPROBE,  		.procname	= "modprobe",  		.data		= &modprobe_path,  		.maxlen		= KMOD_PATH_LEN,  		.mode		= 0644, -		.proc_handler	= &proc_dostring, -		.strategy	= &sysctl_string, +		.proc_handler	= proc_dostring,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "modules_disabled",  		.data		= &modules_disabled,  		.maxlen		= sizeof(int),  		.mode		= 0644,  		/* only handle a transition from default "0" to "1" */ -		.proc_handler	= &proc_dointvec_minmax, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &one,  		.extra2		= &one,  	},  #endif -#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) +#ifdef CONFIG_HOTPLUG  	{ -		.ctl_name	= KERN_HOTPLUG,  		.procname	= "hotplug",  		.data		= &uevent_helper,  		.maxlen		= UEVENT_HELPER_PATH_LEN,  		.mode		= 0644, -		.proc_handler	= &proc_dostring, -		.strategy	= &sysctl_string, +		.proc_handler	= proc_dostring,  	},  #endif  #ifdef CONFIG_CHR_DEV_SG  	{ -		.ctl_name	= KERN_SG_BIG_BUFF,  		.procname	= "sg-big-buff",  		.data		= &sg_big_buff,  		.maxlen		= sizeof (int),  		.mode		= 0444, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_BSD_PROCESS_ACCT  	{ -		.ctl_name	= KERN_ACCT,  		.procname	= "acct",  		.data		= &acct_parm,  		.maxlen		= 3*sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_MAGIC_SYSRQ  	{ -		.ctl_name	= KERN_SYSRQ,  		.procname	= "sysrq",  		.data		= &__sysrq_enabled,  		.maxlen		= sizeof (int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= sysrq_sysctl_handler,  	},  #endif  #ifdef CONFIG_PROC_SYSCTL @@ -604,196 +603,224 @@ static struct ctl_table kern_table[] = {  		.data		= NULL,  		.maxlen		= sizeof (int),  		.mode		= 0600, -		.proc_handler	= &proc_do_cad_pid, +		.proc_handler	= proc_do_cad_pid,  	},  #endif  	{ -		.ctl_name	= KERN_MAX_THREADS,  		.procname	= "threads-max",  		.data		= &max_threads,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= KERN_RANDOM,  		.procname	= "random",  		.mode		= 0555,  		.child		= random_table,  	},  	{ -		.ctl_name	= KERN_OVERFLOWUID,  		.procname	= "overflowuid",  		.data		= &overflowuid,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &minolduid,  		.extra2		= &maxolduid,  	},  	{ -		.ctl_name	= KERN_OVERFLOWGID,  		.procname	= "overflowgid",  		.data		= &overflowgid,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &minolduid,  		.extra2		= &maxolduid,  	},  #ifdef CONFIG_S390  #ifdef CONFIG_MATHEMU  	{ -		.ctl_name	= KERN_IEEE_EMULATION_WARNINGS,  		.procname	= "ieee_emulation_warnings",  		.data		= &sysctl_ieee_emulation_warnings,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  	{ -		.ctl_name	= KERN_S390_USER_DEBUG_LOGGING,  		.procname	= "userprocess_debug", -		.data		= &sysctl_userprocess_debug, +		.data		= &show_unhandled_signals,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  	{ -		.ctl_name	= KERN_PIDMAX,  		.procname	= "pid_max",  		.data		= &pid_max,  		.maxlen		= sizeof (int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= sysctl_intvec, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &pid_max_min,  		.extra2		= &pid_max_max,  	},  	{ -		.ctl_name	= KERN_PANIC_ON_OOPS,  		.procname	= "panic_on_oops",  		.data		= &panic_on_oops,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #if defined CONFIG_PRINTK  	{ -		.ctl_name	= KERN_PRINTK,  		.procname	= "printk",  		.data		= &console_loglevel,  		.maxlen		= 4*sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= KERN_PRINTK_RATELIMIT,  		.procname	= "printk_ratelimit",  		.data		= &printk_ratelimit_state.interval,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_jiffies, -		.strategy	= &sysctl_jiffies, +		.proc_handler	= proc_dointvec_jiffies,  	},  	{ -		.ctl_name	= KERN_PRINTK_RATELIMIT_BURST,  		.procname	= "printk_ratelimit_burst",  		.data		= &printk_ratelimit_state.burst,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec, +	}, +	{ +		.procname	= "printk_delay", +		.data		= &printk_delay_msec, +		.maxlen		= sizeof(int), +		.mode		= 0644, +		.proc_handler	= proc_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &ten_thousand, +	}, +	{ +		.procname	= "dmesg_restrict", +		.data		= &dmesg_restrict, +		.maxlen		= sizeof(int), +		.mode		= 0644, +		.proc_handler	= proc_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &one,  	},  #endif  	{ -		.ctl_name	= KERN_NGROUPS_MAX,  		.procname	= "ngroups_max",  		.data		= &ngroups_max,  		.maxlen		= sizeof (int),  		.mode		= 0444, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	}, -#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) +#if defined(CONFIG_LOCKUP_DETECTOR)  	{ -		.ctl_name       = KERN_UNKNOWN_NMI_PANIC, -		.procname       = "unknown_nmi_panic", -		.data           = &unknown_nmi_panic, +		.procname       = "watchdog", +		.data           = &watchdog_enabled,  		.maxlen         = sizeof (int),  		.mode           = 0644, -		.proc_handler   = &proc_dointvec, +		.proc_handler   = proc_dowatchdog_enabled, +	}, +	{ +		.procname	= "watchdog_thresh", +		.data		= &softlockup_thresh, +		.maxlen		= sizeof(int), +		.mode		= 0644, +		.proc_handler	= proc_dowatchdog_thresh, +		.extra1		= &neg_one, +		.extra2		= &sixty, +	}, +	{ +		.procname	= "softlockup_panic", +		.data		= &softlockup_panic, +		.maxlen		= sizeof(int), +		.mode		= 0644, +		.proc_handler	= proc_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &one,  	},  	{  		.procname       = "nmi_watchdog", -		.data           = &nmi_watchdog_enabled, +		.data           = &watchdog_enabled,  		.maxlen         = sizeof (int),  		.mode           = 0644, -		.proc_handler   = &proc_nmi_enabled, +		.proc_handler   = proc_dowatchdog_enabled, +	}, +#endif +#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) +	{ +		.procname       = "unknown_nmi_panic", +		.data           = &unknown_nmi_panic, +		.maxlen         = sizeof (int), +		.mode           = 0644, +		.proc_handler   = proc_dointvec,  	},  #endif  #if defined(CONFIG_X86)  	{ -		.ctl_name	= KERN_PANIC_ON_NMI,  		.procname	= "panic_on_unrecovered_nmi",  		.data		= &panic_on_unrecovered_nmi,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec, +	}, +	{ +		.procname	= "panic_on_io_nmi", +		.data		= &panic_on_io_nmi, +		.maxlen		= sizeof(int), +		.mode		= 0644, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= KERN_BOOTLOADER_TYPE,  		.procname	= "bootloader_type",  		.data		= &bootloader_type,  		.maxlen		= sizeof (int),  		.mode		= 0444, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "bootloader_version",  		.data		= &bootloader_version,  		.maxlen		= sizeof (int),  		.mode		= 0444, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "kstack_depth_to_print",  		.data		= &kstack_depth_to_print,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "io_delay_type",  		.data		= &io_delay_type,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #if defined(CONFIG_MMU)  	{ -		.ctl_name	= KERN_RANDOMIZE,  		.procname	= "randomize_va_space",  		.data		= &randomize_va_space,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #if defined(CONFIG_S390) && defined(CONFIG_SMP)  	{ -		.ctl_name	= KERN_SPIN_RETRY,  		.procname	= "spin_retry",  		.data		= &spin_retry,  		.maxlen		= sizeof (int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #if	defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86) @@ -802,123 +829,84 @@ static struct ctl_table kern_table[] = {  		.data		= &acpi_realmode_flags,  		.maxlen		= sizeof (unsigned long),  		.mode		= 0644, -		.proc_handler	= &proc_doulongvec_minmax, +		.proc_handler	= proc_doulongvec_minmax,  	},  #endif  #ifdef CONFIG_IA64  	{ -		.ctl_name	= KERN_IA64_UNALIGNED,  		.procname	= "ignore-unaligned-usertrap",  		.data		= &no_unaligned_warning,  		.maxlen		= sizeof (int),  	 	.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "unaligned-dump-stack",  		.data		= &unaligned_dump_stack,  		.maxlen		= sizeof (int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, -	}, -#endif -#ifdef CONFIG_DETECT_SOFTLOCKUP -	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "softlockup_panic", -		.data		= &softlockup_panic, -		.maxlen		= sizeof(int), -		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, -		.extra1		= &zero, -		.extra2		= &one, -	}, -	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "softlockup_thresh", -		.data		= &softlockup_thresh, -		.maxlen		= sizeof(int), -		.mode		= 0644, -		.proc_handler	= &proc_dosoftlockup_thresh, -		.strategy	= &sysctl_intvec, -		.extra1		= &neg_one, -		.extra2		= &sixty, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_DETECT_HUNG_TASK  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "hung_task_panic",  		.data		= &sysctl_hung_task_panic,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &zero,  		.extra2		= &one,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "hung_task_check_count",  		.data		= &sysctl_hung_task_check_count,  		.maxlen		= sizeof(unsigned long),  		.mode		= 0644, -		.proc_handler	= &proc_doulongvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_doulongvec_minmax,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "hung_task_timeout_secs",  		.data		= &sysctl_hung_task_timeout_secs,  		.maxlen		= sizeof(unsigned long),  		.mode		= 0644, -		.proc_handler	= &proc_dohung_task_timeout_secs, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dohung_task_timeout_secs,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "hung_task_warnings",  		.data		= &sysctl_hung_task_warnings,  		.maxlen		= sizeof(unsigned long),  		.mode		= 0644, -		.proc_handler	= &proc_doulongvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_doulongvec_minmax,  	},  #endif  #ifdef CONFIG_COMPAT  	{ -		.ctl_name	= KERN_COMPAT_LOG,  		.procname	= "compat-log",  		.data		= &compat_log,  		.maxlen		= sizeof (int),  	 	.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_RT_MUTEXES  	{ -		.ctl_name	= KERN_MAX_LOCK_DEPTH,  		.procname	= "max_lock_depth",  		.data		= &max_lock_depth,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "poweroff_cmd",  		.data		= &poweroff_cmd,  		.maxlen		= POWEROFF_CMD_PATH_LEN,  		.mode		= 0644, -		.proc_handler	= &proc_dostring, -		.strategy	= &sysctl_string, +		.proc_handler	= proc_dostring,  	},  #ifdef CONFIG_KEYS  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "keys",  		.mode		= 0555,  		.child		= key_sysctls, @@ -926,155 +914,136 @@ static struct ctl_table kern_table[] = {  #endif  #ifdef CONFIG_RCU_TORTURE_TEST  	{ -		.ctl_name       = CTL_UNNUMBERED,  		.procname       = "rcutorture_runnable",  		.data           = &rcutorture_runnable,  		.maxlen         = sizeof(int),  		.mode           = 0644, -		.proc_handler   = &proc_dointvec, -	}, -#endif -#ifdef CONFIG_SLOW_WORK -	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "slow-work", -		.mode		= 0555, -		.child		= slow_work_sysctls, +		.proc_handler	= proc_dointvec,  	},  #endif -#ifdef CONFIG_PERF_COUNTERS +#ifdef CONFIG_PERF_EVENTS  	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "perf_counter_paranoid", -		.data		= &sysctl_perf_counter_paranoid, -		.maxlen		= sizeof(sysctl_perf_counter_paranoid), +		.procname	= "perf_event_paranoid", +		.data		= &sysctl_perf_event_paranoid, +		.maxlen		= sizeof(sysctl_perf_event_paranoid),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "perf_counter_mlock_kb", -		.data		= &sysctl_perf_counter_mlock, -		.maxlen		= sizeof(sysctl_perf_counter_mlock), +		.procname	= "perf_event_mlock_kb", +		.data		= &sysctl_perf_event_mlock, +		.maxlen		= sizeof(sysctl_perf_event_mlock),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED, -		.procname	= "perf_counter_max_sample_rate", -		.data		= &sysctl_perf_counter_sample_rate, -		.maxlen		= sizeof(sysctl_perf_counter_sample_rate), +		.procname	= "perf_event_max_sample_rate", +		.data		= &sysctl_perf_event_sample_rate, +		.maxlen		= sizeof(sysctl_perf_event_sample_rate),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_KMEMCHECK  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "kmemcheck",  		.data		= &kmemcheck_enabled,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec, +	}, +#endif +#ifdef CONFIG_BLOCK +	{ +		.procname	= "blk_iopoll", +		.data		= &blk_iopoll_enabled, +		.maxlen		= sizeof(int), +		.mode		= 0644, +		.proc_handler	= proc_dointvec,  	},  #endif -  /*   * NOTE: do not add new entries to this table unless you have read   * Documentation/sysctl/ctl_unnumbered.txt   */ -	{ .ctl_name = 0 } +	{ }  };  static struct ctl_table vm_table[] = {  	{ -		.ctl_name	= VM_OVERCOMMIT_MEMORY,  		.procname	= "overcommit_memory",  		.data		= &sysctl_overcommit_memory,  		.maxlen		= sizeof(sysctl_overcommit_memory),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= VM_PANIC_ON_OOM,  		.procname	= "panic_on_oom",  		.data		= &sysctl_panic_on_oom,  		.maxlen		= sizeof(sysctl_panic_on_oom),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "oom_kill_allocating_task",  		.data		= &sysctl_oom_kill_allocating_task,  		.maxlen		= sizeof(sysctl_oom_kill_allocating_task),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "oom_dump_tasks",  		.data		= &sysctl_oom_dump_tasks,  		.maxlen		= sizeof(sysctl_oom_dump_tasks),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= VM_OVERCOMMIT_RATIO,  		.procname	= "overcommit_ratio",  		.data		= &sysctl_overcommit_ratio,  		.maxlen		= sizeof(sysctl_overcommit_ratio),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= VM_PAGE_CLUSTER,  		.procname	= "page-cluster",   		.data		= &page_cluster,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= VM_DIRTY_BACKGROUND,  		.procname	= "dirty_background_ratio",  		.data		= &dirty_background_ratio,  		.maxlen		= sizeof(dirty_background_ratio),  		.mode		= 0644, -		.proc_handler	= &dirty_background_ratio_handler, -		.strategy	= &sysctl_intvec, +		.proc_handler	= dirty_background_ratio_handler,  		.extra1		= &zero,  		.extra2		= &one_hundred,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "dirty_background_bytes",  		.data		= &dirty_background_bytes,  		.maxlen		= sizeof(dirty_background_bytes),  		.mode		= 0644, -		.proc_handler	= &dirty_background_bytes_handler, -		.strategy	= &sysctl_intvec, +		.proc_handler	= dirty_background_bytes_handler,  		.extra1		= &one_ul,  	},  	{ -		.ctl_name	= VM_DIRTY_RATIO,  		.procname	= "dirty_ratio",  		.data		= &vm_dirty_ratio,  		.maxlen		= sizeof(vm_dirty_ratio),  		.mode		= 0644, -		.proc_handler	= &dirty_ratio_handler, -		.strategy	= &sysctl_intvec, +		.proc_handler	= dirty_ratio_handler,  		.extra1		= &zero,  		.extra2		= &one_hundred,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "dirty_bytes",  		.data		= &vm_dirty_bytes,  		.maxlen		= sizeof(vm_dirty_bytes),  		.mode		= 0644, -		.proc_handler	= &dirty_bytes_handler, -		.strategy	= &sysctl_intvec, +		.proc_handler	= dirty_bytes_handler,  		.extra1		= &dirty_bytes_min,  	},  	{ @@ -1082,383 +1051,384 @@ static struct ctl_table vm_table[] = {  		.data		= &dirty_writeback_interval,  		.maxlen		= sizeof(dirty_writeback_interval),  		.mode		= 0644, -		.proc_handler	= &dirty_writeback_centisecs_handler, +		.proc_handler	= dirty_writeback_centisecs_handler,  	},  	{  		.procname	= "dirty_expire_centisecs",  		.data		= &dirty_expire_interval,  		.maxlen		= sizeof(dirty_expire_interval),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= VM_NR_PDFLUSH_THREADS,  		.procname	= "nr_pdflush_threads",  		.data		= &nr_pdflush_threads,  		.maxlen		= sizeof nr_pdflush_threads,  		.mode		= 0444 /* read-only*/, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  	{ -		.ctl_name	= VM_SWAPPINESS,  		.procname	= "swappiness",  		.data		= &vm_swappiness,  		.maxlen		= sizeof(vm_swappiness),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &zero,  		.extra2		= &one_hundred,  	},  #ifdef CONFIG_HUGETLB_PAGE -	 { +	{  		.procname	= "nr_hugepages",  		.data		= NULL,  		.maxlen		= sizeof(unsigned long),  		.mode		= 0644, -		.proc_handler	= &hugetlb_sysctl_handler, +		.proc_handler	= hugetlb_sysctl_handler,  		.extra1		= (void *)&hugetlb_zero,  		.extra2		= (void *)&hugetlb_infinity, -	 }, +	}, +#ifdef CONFIG_NUMA +	{ +		.procname       = "nr_hugepages_mempolicy", +		.data           = NULL, +		.maxlen         = sizeof(unsigned long), +		.mode           = 0644, +		.proc_handler   = &hugetlb_mempolicy_sysctl_handler, +		.extra1		= (void *)&hugetlb_zero, +		.extra2		= (void *)&hugetlb_infinity, +	}, +#endif  	 { -		.ctl_name	= VM_HUGETLB_GROUP,  		.procname	= "hugetlb_shm_group",  		.data		= &sysctl_hugetlb_shm_group,  		.maxlen		= sizeof(gid_t),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	 },  	 { -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "hugepages_treat_as_movable",  		.data		= &hugepages_treat_as_movable,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &hugetlb_treat_movable_handler, +		.proc_handler	= hugetlb_treat_movable_handler,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "nr_overcommit_hugepages",  		.data		= NULL,  		.maxlen		= sizeof(unsigned long),  		.mode		= 0644, -		.proc_handler	= &hugetlb_overcommit_handler, +		.proc_handler	= hugetlb_overcommit_handler,  		.extra1		= (void *)&hugetlb_zero,  		.extra2		= (void *)&hugetlb_infinity,  	},  #endif  	{ -		.ctl_name	= VM_LOWMEM_RESERVE_RATIO,  		.procname	= "lowmem_reserve_ratio",  		.data		= &sysctl_lowmem_reserve_ratio,  		.maxlen		= sizeof(sysctl_lowmem_reserve_ratio),  		.mode		= 0644, -		.proc_handler	= &lowmem_reserve_ratio_sysctl_handler, -		.strategy	= &sysctl_intvec, +		.proc_handler	= lowmem_reserve_ratio_sysctl_handler,  	},  	{ -		.ctl_name	= VM_DROP_PAGECACHE,  		.procname	= "drop_caches",  		.data		= &sysctl_drop_caches,  		.maxlen		= sizeof(int),  		.mode		= 0644,  		.proc_handler	= drop_caches_sysctl_handler, -		.strategy	= &sysctl_intvec, +	}, +#ifdef CONFIG_COMPACTION +	{ +		.procname	= "compact_memory", +		.data		= &sysctl_compact_memory, +		.maxlen		= sizeof(int), +		.mode		= 0200, +		.proc_handler	= sysctl_compaction_handler,  	},  	{ -		.ctl_name	= VM_MIN_FREE_KBYTES, +		.procname	= "extfrag_threshold", +		.data		= &sysctl_extfrag_threshold, +		.maxlen		= sizeof(int), +		.mode		= 0644, +		.proc_handler	= sysctl_extfrag_handler, +		.extra1		= &min_extfrag_threshold, +		.extra2		= &max_extfrag_threshold, +	}, + +#endif /* CONFIG_COMPACTION */ +	{  		.procname	= "min_free_kbytes",  		.data		= &min_free_kbytes,  		.maxlen		= sizeof(min_free_kbytes),  		.mode		= 0644, -		.proc_handler	= &min_free_kbytes_sysctl_handler, -		.strategy	= &sysctl_intvec, +		.proc_handler	= min_free_kbytes_sysctl_handler,  		.extra1		= &zero,  	},  	{ -		.ctl_name	= VM_PERCPU_PAGELIST_FRACTION,  		.procname	= "percpu_pagelist_fraction",  		.data		= &percpu_pagelist_fraction,  		.maxlen		= sizeof(percpu_pagelist_fraction),  		.mode		= 0644, -		.proc_handler	= &percpu_pagelist_fraction_sysctl_handler, -		.strategy	= &sysctl_intvec, +		.proc_handler	= percpu_pagelist_fraction_sysctl_handler,  		.extra1		= &min_percpu_pagelist_fract,  	},  #ifdef CONFIG_MMU  	{ -		.ctl_name	= VM_MAX_MAP_COUNT,  		.procname	= "max_map_count",  		.data		= &sysctl_max_map_count,  		.maxlen		= sizeof(sysctl_max_map_count),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec +		.proc_handler	= proc_dointvec_minmax, +		.extra1		= &zero,  	},  #else  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "nr_trim_pages",  		.data		= &sysctl_nr_trim_pages,  		.maxlen		= sizeof(sysctl_nr_trim_pages),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &zero,  	},  #endif  	{ -		.ctl_name	= VM_LAPTOP_MODE,  		.procname	= "laptop_mode",  		.data		= &laptop_mode,  		.maxlen		= sizeof(laptop_mode),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_jiffies, -		.strategy	= &sysctl_jiffies, +		.proc_handler	= proc_dointvec_jiffies,  	},  	{ -		.ctl_name	= VM_BLOCK_DUMP,  		.procname	= "block_dump",  		.data		= &block_dump,  		.maxlen		= sizeof(block_dump),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec,  		.extra1		= &zero,  	},  	{ -		.ctl_name	= VM_VFS_CACHE_PRESSURE,  		.procname	= "vfs_cache_pressure",  		.data		= &sysctl_vfs_cache_pressure,  		.maxlen		= sizeof(sysctl_vfs_cache_pressure),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec,  		.extra1		= &zero,  	},  #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT  	{ -		.ctl_name	= VM_LEGACY_VA_LAYOUT,  		.procname	= "legacy_va_layout",  		.data		= &sysctl_legacy_va_layout,  		.maxlen		= sizeof(sysctl_legacy_va_layout),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec,  		.extra1		= &zero,  	},  #endif  #ifdef CONFIG_NUMA  	{ -		.ctl_name	= VM_ZONE_RECLAIM_MODE,  		.procname	= "zone_reclaim_mode",  		.data		= &zone_reclaim_mode,  		.maxlen		= sizeof(zone_reclaim_mode),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec,  		.extra1		= &zero,  	},  	{ -		.ctl_name	= VM_MIN_UNMAPPED,  		.procname	= "min_unmapped_ratio",  		.data		= &sysctl_min_unmapped_ratio,  		.maxlen		= sizeof(sysctl_min_unmapped_ratio),  		.mode		= 0644, -		.proc_handler	= &sysctl_min_unmapped_ratio_sysctl_handler, -		.strategy	= &sysctl_intvec, +		.proc_handler	= sysctl_min_unmapped_ratio_sysctl_handler,  		.extra1		= &zero,  		.extra2		= &one_hundred,  	},  	{ -		.ctl_name	= VM_MIN_SLAB,  		.procname	= "min_slab_ratio",  		.data		= &sysctl_min_slab_ratio,  		.maxlen		= sizeof(sysctl_min_slab_ratio),  		.mode		= 0644, -		.proc_handler	= &sysctl_min_slab_ratio_sysctl_handler, -		.strategy	= &sysctl_intvec, +		.proc_handler	= sysctl_min_slab_ratio_sysctl_handler,  		.extra1		= &zero,  		.extra2		= &one_hundred,  	},  #endif  #ifdef CONFIG_SMP  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "stat_interval",  		.data		= &sysctl_stat_interval,  		.maxlen		= sizeof(sysctl_stat_interval),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_jiffies, -		.strategy	= &sysctl_jiffies, +		.proc_handler	= proc_dointvec_jiffies,  	},  #endif +#ifdef CONFIG_MMU  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "mmap_min_addr", -		.data		= &mmap_min_addr, -		.maxlen         = sizeof(unsigned long), +		.data		= &dac_mmap_min_addr, +		.maxlen		= sizeof(unsigned long),  		.mode		= 0644, -		.proc_handler	= &proc_doulongvec_minmax, +		.proc_handler	= mmap_min_addr_handler,  	}, +#endif  #ifdef CONFIG_NUMA  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "numa_zonelist_order",  		.data		= &numa_zonelist_order,  		.maxlen		= NUMA_ZONELIST_ORDER_LEN,  		.mode		= 0644, -		.proc_handler	= &numa_zonelist_order_handler, -		.strategy	= &sysctl_string, +		.proc_handler	= numa_zonelist_order_handler,  	},  #endif  #if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \     (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))  	{ -		.ctl_name	= VM_VDSO_ENABLED,  		.procname	= "vdso_enabled",  		.data		= &vdso_enabled,  		.maxlen		= sizeof(vdso_enabled),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec,  		.extra1		= &zero,  	},  #endif  #ifdef CONFIG_HIGHMEM  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "highmem_is_dirtyable",  		.data		= &vm_highmem_is_dirtyable,  		.maxlen		= sizeof(vm_highmem_is_dirtyable),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &zero,  		.extra2		= &one,  	},  #endif  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "scan_unevictable_pages",  		.data		= &scan_unevictable_pages,  		.maxlen		= sizeof(scan_unevictable_pages),  		.mode		= 0644, -		.proc_handler	= &scan_unevictable_handler, +		.proc_handler	= scan_unevictable_handler,  	}, +#ifdef CONFIG_MEMORY_FAILURE +	{ +		.procname	= "memory_failure_early_kill", +		.data		= &sysctl_memory_failure_early_kill, +		.maxlen		= sizeof(sysctl_memory_failure_early_kill), +		.mode		= 0644, +		.proc_handler	= proc_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &one, +	}, +	{ +		.procname	= "memory_failure_recovery", +		.data		= &sysctl_memory_failure_recovery, +		.maxlen		= sizeof(sysctl_memory_failure_recovery), +		.mode		= 0644, +		.proc_handler	= proc_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &one, +	}, +#endif +  /*   * NOTE: do not add new entries to this table unless you have read   * Documentation/sysctl/ctl_unnumbered.txt   */ -	{ .ctl_name = 0 } +	{ }  };  #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)  static struct ctl_table binfmt_misc_table[] = { -	{ .ctl_name = 0 } +	{ }  };  #endif  static struct ctl_table fs_table[] = {  	{ -		.ctl_name	= FS_NRINODE,  		.procname	= "inode-nr",  		.data		= &inodes_stat,  		.maxlen		= 2*sizeof(int),  		.mode		= 0444, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_nr_inodes,  	},  	{ -		.ctl_name	= FS_STATINODE,  		.procname	= "inode-state",  		.data		= &inodes_stat,  		.maxlen		= 7*sizeof(int),  		.mode		= 0444, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_nr_inodes,  	},  	{  		.procname	= "file-nr",  		.data		= &files_stat, -		.maxlen		= 3*sizeof(int), +		.maxlen		= sizeof(files_stat),  		.mode		= 0444, -		.proc_handler	= &proc_nr_files, +		.proc_handler	= proc_nr_files,  	},  	{ -		.ctl_name	= FS_MAXFILE,  		.procname	= "file-max",  		.data		= &files_stat.max_files, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(files_stat.max_files),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_doulongvec_minmax,  	},  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "nr_open",  		.data		= &sysctl_nr_open,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &sysctl_nr_open_min,  		.extra2		= &sysctl_nr_open_max,  	},  	{ -		.ctl_name	= FS_DENTRY,  		.procname	= "dentry-state",  		.data		= &dentry_stat,  		.maxlen		= 6*sizeof(int),  		.mode		= 0444, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_nr_dentry,  	},  	{ -		.ctl_name	= FS_OVERFLOWUID,  		.procname	= "overflowuid",  		.data		= &fs_overflowuid,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &minolduid,  		.extra2		= &maxolduid,  	},  	{ -		.ctl_name	= FS_OVERFLOWGID,  		.procname	= "overflowgid",  		.data		= &fs_overflowgid,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &minolduid,  		.extra2		= &maxolduid,  	},  #ifdef CONFIG_FILE_LOCKING  	{ -		.ctl_name	= FS_LEASES,  		.procname	= "leases-enable",  		.data		= &leases_enable,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_DNOTIFY  	{ -		.ctl_name	= FS_DIR_NOTIFY,  		.procname	= "dir-notify-enable",  		.data		= &dir_notify_enable,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_MMU  #ifdef CONFIG_FILE_LOCKING  	{ -		.ctl_name	= FS_LEASE_TIME,  		.procname	= "lease-break-time",  		.data		= &lease_break_time,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec, +		.proc_handler	= proc_dointvec,  	},  #endif  #ifdef CONFIG_AIO @@ -1467,19 +1437,18 @@ static struct ctl_table fs_table[] = {  		.data		= &aio_nr,  		.maxlen		= sizeof(aio_nr),  		.mode		= 0444, -		.proc_handler	= &proc_doulongvec_minmax, +		.proc_handler	= proc_doulongvec_minmax,  	},  	{  		.procname	= "aio-max-nr",  		.data		= &aio_max_nr,  		.maxlen		= sizeof(aio_max_nr),  		.mode		= 0644, -		.proc_handler	= &proc_doulongvec_minmax, +		.proc_handler	= proc_doulongvec_minmax,  	},  #endif /* CONFIG_AIO */  #ifdef CONFIG_INOTIFY_USER  	{ -		.ctl_name	= FS_INOTIFY,  		.procname	= "inotify",  		.mode		= 0555,  		.child		= inotify_table, @@ -1494,35 +1463,40 @@ static struct ctl_table fs_table[] = {  #endif  #endif  	{ -		.ctl_name	= KERN_SETUID_DUMPABLE,  		.procname	= "suid_dumpable",  		.data		= &suid_dumpable,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= &proc_dointvec_minmax, -		.strategy	= &sysctl_intvec, +		.proc_handler	= proc_dointvec_minmax,  		.extra1		= &zero,  		.extra2		= &two,  	},  #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "binfmt_misc",  		.mode		= 0555,  		.child		= binfmt_misc_table,  	},  #endif +	{ +		.procname	= "pipe-max-size", +		.data		= &pipe_max_size, +		.maxlen		= sizeof(int), +		.mode		= 0644, +		.proc_handler	= &pipe_proc_fn, +		.extra1		= &pipe_min_size, +	},  /*   * NOTE: do not add new entries to this table unless you have read   * Documentation/sysctl/ctl_unnumbered.txt   */ -	{ .ctl_name = 0 } +	{ }  };  static struct ctl_table debug_table[] = { -#if defined(CONFIG_X86) || defined(CONFIG_PPC) +#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \ +    defined(CONFIG_S390)  	{ -		.ctl_name	= CTL_UNNUMBERED,  		.procname	= "exception-trace",  		.data		= &show_unhandled_signals,  		.maxlen		= sizeof(int), @@ -1530,11 +1504,22 @@ static struct ctl_table debug_table[] = {  		.proc_handler	= proc_dointvec  	},  #endif -	{ .ctl_name = 0 } +#if defined(CONFIG_OPTPROBES) +	{ +		.procname	= "kprobes-optimization", +		.data		= &sysctl_kprobes_optimization, +		.maxlen		= sizeof(int), +		.mode		= 0644, +		.proc_handler	= proc_kprobes_optimization_handler, +		.extra1		= &zero, +		.extra2		= &one, +	}, +#endif +	{ }  };  static struct ctl_table dev_table[] = { -	{ .ctl_name = 0 } +	{ }  };  static DEFINE_SPINLOCK(sysctl_lock); @@ -1688,122 +1673,6 @@ void register_sysctl_root(struct ctl_table_root *root)  	spin_unlock(&sysctl_lock);  } -#ifdef CONFIG_SYSCTL_SYSCALL -/* Perform the actual read/write of a sysctl table entry. */ -static int do_sysctl_strategy(struct ctl_table_root *root, -			struct ctl_table *table, -			void __user *oldval, size_t __user *oldlenp, -			void __user *newval, size_t newlen) -{ -	int op = 0, rc; - -	if (oldval) -		op |= MAY_READ; -	if (newval) -		op |= MAY_WRITE; -	if (sysctl_perm(root, table, op)) -		return -EPERM; - -	if (table->strategy) { -		rc = table->strategy(table, oldval, oldlenp, newval, newlen); -		if (rc < 0) -			return rc; -		if (rc > 0) -			return 0; -	} - -	/* If there is no strategy routine, or if the strategy returns -	 * zero, proceed with automatic r/w */ -	if (table->data && table->maxlen) { -		rc = sysctl_data(table, oldval, oldlenp, newval, newlen); -		if (rc < 0) -			return rc; -	} -	return 0; -} - -static int parse_table(int __user *name, int nlen, -		       void __user *oldval, size_t __user *oldlenp, -		       void __user *newval, size_t newlen, -		       struct ctl_table_root *root, -		       struct ctl_table *table) -{ -	int n; -repeat: -	if (!nlen) -		return -ENOTDIR; -	if (get_user(n, name)) -		return -EFAULT; -	for ( ; table->ctl_name || table->procname; table++) { -		if (!table->ctl_name) -			continue; -		if (n == table->ctl_name) { -			int error; -			if (table->child) { -				if (sysctl_perm(root, table, MAY_EXEC)) -					return -EPERM; -				name++; -				nlen--; -				table = table->child; -				goto repeat; -			} -			error = do_sysctl_strategy(root, table, -						   oldval, oldlenp, -						   newval, newlen); -			return error; -		} -	} -	return -ENOTDIR; -} - -int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, -	       void __user *newval, size_t newlen) -{ -	struct ctl_table_header *head; -	int error = -ENOTDIR; - -	if (nlen <= 0 || nlen >= CTL_MAXNAME) -		return -ENOTDIR; -	if (oldval) { -		int old_len; -		if (!oldlenp || get_user(old_len, oldlenp)) -			return -EFAULT; -	} - -	for (head = sysctl_head_next(NULL); head; -			head = sysctl_head_next(head)) { -		error = parse_table(name, nlen, oldval, oldlenp,  -					newval, newlen, -					head->root, head->ctl_table); -		if (error != -ENOTDIR) { -			sysctl_head_finish(head); -			break; -		} -	} -	return error; -} - -SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args) -{ -	struct __sysctl_args tmp; -	int error; - -	if (copy_from_user(&tmp, args, sizeof(tmp))) -		return -EFAULT; - -	error = deprecated_sysctl_warning(&tmp); -	if (error) -		goto out; - -	lock_kernel(); -	error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp, -			  tmp.newval, tmp.newlen); -	unlock_kernel(); -out: -	return error; -} -#endif /* CONFIG_SYSCTL_SYSCALL */ -  /*   * sysctl_perm does NOT grant the superuser all rights automatically, because   * some sysctl variables are readonly even to root. @@ -1839,7 +1708,7 @@ int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)  static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)  { -	for (; table->ctl_name || table->procname; table++) { +	for (; table->procname; table++) {  		table->parent = parent;  		if (table->child)  			sysctl_set_parent(table, table->child); @@ -1850,10 +1719,7 @@ static __init int sysctl_init(void)  {  	sysctl_set_parent(NULL, root_table);  #ifdef CONFIG_SYSCTL_SYSCALL_CHECK -	{ -		int err; -		err = sysctl_check_table(current->nsproxy, root_table); -	} +	sysctl_check_table(current->nsproxy, root_table);  #endif  	return 0;  } @@ -1871,11 +1737,11 @@ static struct ctl_table *is_branch_in(struct ctl_table *branch,  		return NULL;  	/* ... and nothing else */ -	if (branch[1].procname || branch[1].ctl_name) +	if (branch[1].procname)  		return NULL;  	/* table should contain subdirectory with the same name */ -	for (p = table; p->procname || p->ctl_name; p++) { +	for (p = table; p->procname; p++) {  		if (!p->child)  			continue;  		if (p->procname && strcmp(p->procname, s) == 0) @@ -1920,9 +1786,6 @@ static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)   *   * The members of the &struct ctl_table structure are used as follows:   * - * ctl_name - This is the numeric sysctl value used by sysctl(2). The number - *            must be unique within that level of sysctl - *   * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not   *            enter a sysctl file   * @@ -1937,8 +1800,6 @@ static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)   *   * proc_handler - the text handler routine (described below)   * - * strategy - the strategy routine (described below) - *   * de - for internal use by the sysctl routines   *   * extra1, extra2 - extra pointers usable by the proc handler routines @@ -1951,19 +1812,6 @@ static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)   * struct enable minimal validation of the values being written to be   * performed, and the mode field allows minimal authentication.   * - * More sophisticated management can be enabled by the provision of a - * strategy routine with the table entry.  This will be called before - * any automatic read or write of the data is performed. - * - * The strategy routine may return - * - * < 0 - Error occurred (error is passed to user process) - * - * 0   - OK - proceed with automatic read or write. - * - * > 0 - OK - read or write has been done by the strategy routine, so - *       return immediately. - *   * There must be a proc_handler routine for any terminal nodes   * mirrored under /proc/sys (non-terminals are handled by a built-in   * directory handler).  Several default handlers are available to @@ -1990,13 +1838,13 @@ struct ctl_table_header *__register_sysctl_paths(  	struct ctl_table_set *set;  	/* Count the path components */ -	for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath) +	for (npath = 0; path[npath].procname; ++npath)  		;  	/*  	 * For each path component, allocate a 2-element ctl_table array.  	 * The first array element will be filled with the sysctl entry -	 * for this, the second will be the sentinel (ctl_name == 0). +	 * for this, the second will be the sentinel (procname == 0).  	 *  	 * We allocate everything in one go so that we don't have to  	 * worry about freeing additional memory in unregister_sysctl_table. @@ -2013,7 +1861,6 @@ struct ctl_table_header *__register_sysctl_paths(  	for (n = 0; n < npath; ++n, ++path) {  		/* Copy the procname */  		new->procname = path->procname; -		new->ctl_name = path->ctl_name;  		new->mode     = 0555;  		*prevp = new; @@ -2173,7 +2020,7 @@ void sysctl_head_put(struct ctl_table_header *head)  #ifdef CONFIG_PROC_SYSCTL  static int _proc_do_string(void* data, int maxlen, int write, -			   struct file *filp, void __user *buffer, +			   void __user *buffer,  			   size_t *lenp, loff_t *ppos)  {  	size_t len; @@ -2234,7 +2081,6 @@ static int _proc_do_string(void* data, int maxlen, int write,   * proc_dostring - read a string sysctl   * @table: the sysctl table   * @write: %TRUE if this is a write to the sysctl file - * @filp: the file structure   * @buffer: the user buffer   * @lenp: the size of the user buffer   * @ppos: file position @@ -2248,15 +2094,139 @@ static int _proc_do_string(void* data, int maxlen, int write,   *   * Returns 0 on success.   */ -int proc_dostring(struct ctl_table *table, int write, struct file *filp, +int proc_dostring(struct ctl_table *table, int write,  		  void __user *buffer, size_t *lenp, loff_t *ppos)  { -	return _proc_do_string(table->data, table->maxlen, write, filp, +	return _proc_do_string(table->data, table->maxlen, write,  			       buffer, lenp, ppos);  } +static size_t proc_skip_spaces(char **buf) +{ +	size_t ret; +	char *tmp = skip_spaces(*buf); +	ret = tmp - *buf; +	*buf = tmp; +	return ret; +} + +static void proc_skip_char(char **buf, size_t *size, const char v) +{ +	while (*size) { +		if (**buf != v) +			break; +		(*size)--; +		(*buf)++; +	} +} + +#define TMPBUFLEN 22 +/** + * proc_get_long - reads an ASCII formatted integer from a user buffer + * + * @buf: a kernel buffer + * @size: size of the kernel buffer + * @val: this is where the number will be stored + * @neg: set to %TRUE if number is negative + * @perm_tr: a vector which contains the allowed trailers + * @perm_tr_len: size of the perm_tr vector + * @tr: pointer to store the trailer character + * + * In case of success %0 is returned and @buf and @size are updated with + * the amount of bytes read. If @tr is non-NULL and a trailing + * character exists (size is non-zero after returning from this + * function), @tr is updated with the trailing character. + */ +static int proc_get_long(char **buf, size_t *size, +			  unsigned long *val, bool *neg, +			  const char *perm_tr, unsigned perm_tr_len, char *tr) +{ +	int len; +	char *p, tmp[TMPBUFLEN]; + +	if (!*size) +		return -EINVAL; + +	len = *size; +	if (len > TMPBUFLEN - 1) +		len = TMPBUFLEN - 1; + +	memcpy(tmp, *buf, len); + +	tmp[len] = 0; +	p = tmp; +	if (*p == '-' && *size > 1) { +		*neg = true; +		p++; +	} else +		*neg = false; +	if (!isdigit(*p)) +		return -EINVAL; + +	*val = simple_strtoul(p, &p, 0); + +	len = p - tmp; + +	/* We don't know if the next char is whitespace thus we may accept +	 * invalid integers (e.g. 1234...a) or two integers instead of one +	 * (e.g. 123...1). So lets not allow such large numbers. */ +	if (len == TMPBUFLEN - 1) +		return -EINVAL; + +	if (len < *size && perm_tr_len && !memchr(perm_tr, *p, perm_tr_len)) +		return -EINVAL; + +	if (tr && (len < *size)) +		*tr = *p; + +	*buf += len; +	*size -= len; + +	return 0; +} + +/** + * proc_put_long - converts an integer to a decimal ASCII formatted string + * + * @buf: the user buffer + * @size: the size of the user buffer + * @val: the integer to be converted + * @neg: sign of the number, %TRUE for negative + * + * In case of success %0 is returned and @buf and @size are updated with + * the amount of bytes written. + */ +static int proc_put_long(void __user **buf, size_t *size, unsigned long val, +			  bool neg) +{ +	int len; +	char tmp[TMPBUFLEN], *p = tmp; + +	sprintf(p, "%s%lu", neg ? "-" : "", val); +	len = strlen(tmp); +	if (len > *size) +		len = *size; +	if (copy_to_user(*buf, tmp, len)) +		return -EFAULT; +	*size -= len; +	*buf += len; +	return 0; +} +#undef TMPBUFLEN + +static int proc_put_char(void __user **buf, size_t *size, char c) +{ +	if (*size) { +		char __user **buffer = (char __user **)buf; +		if (put_user(c, *buffer)) +			return -EFAULT; +		(*size)--, (*buffer)++; +		*buf = *buffer; +	} +	return 0; +} -static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, +static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp,  				 int *valp,  				 int write, void *data)  { @@ -2265,33 +2235,31 @@ static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,  	} else {  		int val = *valp;  		if (val < 0) { -			*negp = -1; +			*negp = true;  			*lvalp = (unsigned long)-val;  		} else { -			*negp = 0; +			*negp = false;  			*lvalp = (unsigned long)val;  		}  	}  	return 0;  } +static const char proc_wspace_sep[] = { ' ', '\t', '\n' }; +  static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, -		  int write, struct file *filp, void __user *buffer, +		  int write, void __user *buffer,  		  size_t *lenp, loff_t *ppos, -		  int (*conv)(int *negp, unsigned long *lvalp, int *valp, +		  int (*conv)(bool *negp, unsigned long *lvalp, int *valp,  			      int write, void *data),  		  void *data)  { -#define TMPBUFLEN 21 -	int *i, vleft, first = 1, neg; -	unsigned long lval; -	size_t left, len; +	int *i, vleft, first = 1, err = 0; +	unsigned long page = 0; +	size_t left; +	char *kbuf; -	char buf[TMPBUFLEN], *p; -	char __user *s = buffer; -	 -	if (!tbl_data || !table->maxlen || !*lenp || -	    (*ppos && !write)) { +	if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {  		*lenp = 0;  		return 0;  	} @@ -2303,93 +2271,75 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,  	if (!conv)  		conv = do_proc_dointvec_conv; +	if (write) { +		if (left > PAGE_SIZE - 1) +			left = PAGE_SIZE - 1; +		page = __get_free_page(GFP_TEMPORARY); +		kbuf = (char *) page; +		if (!kbuf) +			return -ENOMEM; +		if (copy_from_user(kbuf, buffer, left)) { +			err = -EFAULT; +			goto free; +		} +		kbuf[left] = 0; +	} +  	for (; left && vleft--; i++, first=0) { +		unsigned long lval; +		bool neg; +  		if (write) { -			while (left) { -				char c; -				if (get_user(c, s)) -					return -EFAULT; -				if (!isspace(c)) -					break; -				left--; -				s++; -			} +			left -= proc_skip_spaces(&kbuf); +  			if (!left)  				break; -			neg = 0; -			len = left; -			if (len > sizeof(buf) - 1) -				len = sizeof(buf) - 1; -			if (copy_from_user(buf, s, len)) -				return -EFAULT; -			buf[len] = 0; -			p = buf; -			if (*p == '-' && left > 1) { -				neg = 1; -				p++; -			} -			if (*p < '0' || *p > '9') +			err = proc_get_long(&kbuf, &left, &lval, &neg, +					     proc_wspace_sep, +					     sizeof(proc_wspace_sep), NULL); +			if (err)  				break; - -			lval = simple_strtoul(p, &p, 0); - -			len = p-buf; -			if ((len < left) && *p && !isspace(*p)) -				break; -			s += len; -			left -= len; - -			if (conv(&neg, &lval, i, 1, data)) +			if (conv(&neg, &lval, i, 1, data)) { +				err = -EINVAL;  				break; +			}  		} else { -			p = buf; +			if (conv(&neg, &lval, i, 0, data)) { +				err = -EINVAL; +				break; +			}  			if (!first) -				*p++ = '\t'; -	 -			if (conv(&neg, &lval, i, 0, data)) +				err = proc_put_char(&buffer, &left, '\t'); +			if (err) +				break; +			err = proc_put_long(&buffer, &left, lval, neg); +			if (err)  				break; - -			sprintf(p, "%s%lu", neg ? "-" : "", lval); -			len = strlen(buf); -			if (len > left) -				len = left; -			if(copy_to_user(s, buf, len)) -				return -EFAULT; -			left -= len; -			s += len;  		}  	} -	if (!write && !first && left) { -		if(put_user('\n', s)) -			return -EFAULT; -		left--, s++; -	} +	if (!write && !first && left && !err) +		err = proc_put_char(&buffer, &left, '\n'); +	if (write && !err && left) +		left -= proc_skip_spaces(&kbuf); +free:  	if (write) { -		while (left) { -			char c; -			if (get_user(c, s++)) -				return -EFAULT; -			if (!isspace(c)) -				break; -			left--; -		} +		free_page(page); +		if (first) +			return err ? : -EINVAL;  	} -	if (write && first) -		return -EINVAL;  	*lenp -= left;  	*ppos += *lenp; -	return 0; -#undef TMPBUFLEN +	return err;  } -static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp, +static int do_proc_dointvec(struct ctl_table *table, int write,  		  void __user *buffer, size_t *lenp, loff_t *ppos, -		  int (*conv)(int *negp, unsigned long *lvalp, int *valp, +		  int (*conv)(bool *negp, unsigned long *lvalp, int *valp,  			      int write, void *data),  		  void *data)  { -	return __do_proc_dointvec(table->data, table, write, filp, +	return __do_proc_dointvec(table->data, table, write,  			buffer, lenp, ppos, conv, data);  } @@ -2397,7 +2347,6 @@ static int do_proc_dointvec(struct ctl_table *table, int write, struct file *fil   * proc_dointvec - read a vector of integers   * @table: the sysctl table   * @write: %TRUE if this is a write to the sysctl file - * @filp: the file structure   * @buffer: the user buffer   * @lenp: the size of the user buffer   * @ppos: file position @@ -2407,10 +2356,10 @@ static int do_proc_dointvec(struct ctl_table *table, int write, struct file *fil   *   * Returns 0 on success.   */ -int proc_dointvec(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec(struct ctl_table *table, int write,  		     void __user *buffer, size_t *lenp, loff_t *ppos)  { -    return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, +    return do_proc_dointvec(table,write,buffer,lenp,ppos,  		    	    NULL,NULL);  } @@ -2418,7 +2367,7 @@ int proc_dointvec(struct ctl_table *table, int write, struct file *filp,   * Taint values can only be increased   * This means we can safely use a temporary.   */ -static int proc_taint(struct ctl_table *table, int write, struct file *filp, +static int proc_taint(struct ctl_table *table, int write,  			       void __user *buffer, size_t *lenp, loff_t *ppos)  {  	struct ctl_table t; @@ -2430,7 +2379,7 @@ static int proc_taint(struct ctl_table *table, int write, struct file *filp,  	t = *table;  	t.data = &tmptaint; -	err = proc_doulongvec_minmax(&t, write, filp, buffer, lenp, ppos); +	err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos);  	if (err < 0)  		return err; @@ -2454,8 +2403,8 @@ struct do_proc_dointvec_minmax_conv_param {  	int *max;  }; -static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,  -					int *valp,  +static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp, +					int *valp,  					int write, void *data)  {  	struct do_proc_dointvec_minmax_conv_param *param = data; @@ -2468,10 +2417,10 @@ static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,  	} else {  		int val = *valp;  		if (val < 0) { -			*negp = -1; +			*negp = true;  			*lvalp = (unsigned long)-val;  		} else { -			*negp = 0; +			*negp = false;  			*lvalp = (unsigned long)val;  		}  	} @@ -2482,7 +2431,6 @@ static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,   * proc_dointvec_minmax - read a vector of integers with min/max values   * @table: the sysctl table   * @write: %TRUE if this is a write to the sysctl file - * @filp: the file structure   * @buffer: the user buffer   * @lenp: the size of the user buffer   * @ppos: file position @@ -2495,138 +2443,111 @@ static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,   *   * Returns 0 on success.   */ -int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_minmax(struct ctl_table *table, int write,  		  void __user *buffer, size_t *lenp, loff_t *ppos)  {  	struct do_proc_dointvec_minmax_conv_param param = {  		.min = (int *) table->extra1,  		.max = (int *) table->extra2,  	}; -	return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, +	return do_proc_dointvec(table, write, buffer, lenp, ppos,  				do_proc_dointvec_minmax_conv, ¶m);  }  static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, -				     struct file *filp,  				     void __user *buffer,  				     size_t *lenp, loff_t *ppos,  				     unsigned long convmul,  				     unsigned long convdiv)  { -#define TMPBUFLEN 21 -	unsigned long *i, *min, *max, val; -	int vleft, first=1, neg; -	size_t len, left; -	char buf[TMPBUFLEN], *p; -	char __user *s = buffer; -	 -	if (!data || !table->maxlen || !*lenp || -	    (*ppos && !write)) { +	unsigned long *i, *min, *max; +	int vleft, first = 1, err = 0; +	unsigned long page = 0; +	size_t left; +	char *kbuf; + +	if (!data || !table->maxlen || !*lenp || (*ppos && !write)) {  		*lenp = 0;  		return 0;  	} -	 +  	i = (unsigned long *) data;  	min = (unsigned long *) table->extra1;  	max = (unsigned long *) table->extra2;  	vleft = table->maxlen / sizeof(unsigned long);  	left = *lenp; -	 -	for (; left && vleft--; i++, min++, max++, first=0) { + +	if (write) { +		if (left > PAGE_SIZE - 1) +			left = PAGE_SIZE - 1; +		page = __get_free_page(GFP_TEMPORARY); +		kbuf = (char *) page; +		if (!kbuf) +			return -ENOMEM; +		if (copy_from_user(kbuf, buffer, left)) { +			err = -EFAULT; +			goto free; +		} +		kbuf[left] = 0; +	} + +	for (; left && vleft--; i++, first = 0) { +		unsigned long val; +  		if (write) { -			while (left) { -				char c; -				if (get_user(c, s)) -					return -EFAULT; -				if (!isspace(c)) -					break; -				left--; -				s++; -			} -			if (!left) -				break; -			neg = 0; -			len = left; -			if (len > TMPBUFLEN-1) -				len = TMPBUFLEN-1; -			if (copy_from_user(buf, s, len)) -				return -EFAULT; -			buf[len] = 0; -			p = buf; -			if (*p == '-' && left > 1) { -				neg = 1; -				p++; -			} -			if (*p < '0' || *p > '9') -				break; -			val = simple_strtoul(p, &p, 0) * convmul / convdiv ; -			len = p-buf; -			if ((len < left) && *p && !isspace(*p)) +			bool neg; + +			left -= proc_skip_spaces(&kbuf); + +			err = proc_get_long(&kbuf, &left, &val, &neg, +					     proc_wspace_sep, +					     sizeof(proc_wspace_sep), NULL); +			if (err)  				break;  			if (neg) -				val = -val; -			s += len; -			left -= len; - -			if(neg)  				continue;  			if ((min && val < *min) || (max && val > *max))  				continue;  			*i = val;  		} else { -			p = buf; +			val = convdiv * (*i) / convmul;  			if (!first) -				*p++ = '\t'; -			sprintf(p, "%lu", convdiv * (*i) / convmul); -			len = strlen(buf); -			if (len > left) -				len = left; -			if(copy_to_user(s, buf, len)) -				return -EFAULT; -			left -= len; -			s += len; +				err = proc_put_char(&buffer, &left, '\t'); +			err = proc_put_long(&buffer, &left, val, false); +			if (err) +				break;  		}  	} -	if (!write && !first && left) { -		if(put_user('\n', s)) -			return -EFAULT; -		left--, s++; -	} +	if (!write && !first && left && !err) +		err = proc_put_char(&buffer, &left, '\n'); +	if (write && !err) +		left -= proc_skip_spaces(&kbuf); +free:  	if (write) { -		while (left) { -			char c; -			if (get_user(c, s++)) -				return -EFAULT; -			if (!isspace(c)) -				break; -			left--; -		} +		free_page(page); +		if (first) +			return err ? : -EINVAL;  	} -	if (write && first) -		return -EINVAL;  	*lenp -= left;  	*ppos += *lenp; -	return 0; -#undef TMPBUFLEN +	return err;  }  static int do_proc_doulongvec_minmax(struct ctl_table *table, int write, -				     struct file *filp,  				     void __user *buffer,  				     size_t *lenp, loff_t *ppos,  				     unsigned long convmul,  				     unsigned long convdiv)  {  	return __do_proc_doulongvec_minmax(table->data, table, write, -			filp, buffer, lenp, ppos, convmul, convdiv); +			buffer, lenp, ppos, convmul, convdiv);  }  /**   * proc_doulongvec_minmax - read a vector of long integers with min/max values   * @table: the sysctl table   * @write: %TRUE if this is a write to the sysctl file - * @filp: the file structure   * @buffer: the user buffer   * @lenp: the size of the user buffer   * @ppos: file position @@ -2639,17 +2560,16 @@ static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,   *   * Returns 0 on success.   */ -int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, +int proc_doulongvec_minmax(struct ctl_table *table, int write,  			   void __user *buffer, size_t *lenp, loff_t *ppos)  { -    return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l); +    return do_proc_doulongvec_minmax(table, write, buffer, lenp, ppos, 1l, 1l);  }  /**   * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values   * @table: the sysctl table   * @write: %TRUE if this is a write to the sysctl file - * @filp: the file structure   * @buffer: the user buffer   * @lenp: the size of the user buffer   * @ppos: file position @@ -2664,16 +2584,15 @@ int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp   * Returns 0 on success.   */  int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, -				      struct file *filp,  				      void __user *buffer,  				      size_t *lenp, loff_t *ppos)  { -    return do_proc_doulongvec_minmax(table, write, filp, buffer, +    return do_proc_doulongvec_minmax(table, write, buffer,  				     lenp, ppos, HZ, 1000l);  } -static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp, +static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *lvalp,  					 int *valp,  					 int write, void *data)  { @@ -2685,10 +2604,10 @@ static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp,  		int val = *valp;  		unsigned long lval;  		if (val < 0) { -			*negp = -1; +			*negp = true;  			lval = (unsigned long)-val;  		} else { -			*negp = 0; +			*negp = false;  			lval = (unsigned long)val;  		}  		*lvalp = lval / HZ; @@ -2696,7 +2615,7 @@ static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp,  	return 0;  } -static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp, +static int do_proc_dointvec_userhz_jiffies_conv(bool *negp, unsigned long *lvalp,  						int *valp,  						int write, void *data)  { @@ -2708,10 +2627,10 @@ static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp,  		int val = *valp;  		unsigned long lval;  		if (val < 0) { -			*negp = -1; +			*negp = true;  			lval = (unsigned long)-val;  		} else { -			*negp = 0; +			*negp = false;  			lval = (unsigned long)val;  		}  		*lvalp = jiffies_to_clock_t(lval); @@ -2719,7 +2638,7 @@ static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp,  	return 0;  } -static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp, +static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *lvalp,  					    int *valp,  					    int write, void *data)  { @@ -2729,10 +2648,10 @@ static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,  		int val = *valp;  		unsigned long lval;  		if (val < 0) { -			*negp = -1; +			*negp = true;  			lval = (unsigned long)-val;  		} else { -			*negp = 0; +			*negp = false;  			lval = (unsigned long)val;  		}  		*lvalp = jiffies_to_msecs(lval); @@ -2744,7 +2663,6 @@ static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,   * proc_dointvec_jiffies - read a vector of integers as seconds   * @table: the sysctl table   * @write: %TRUE if this is a write to the sysctl file - * @filp: the file structure   * @buffer: the user buffer   * @lenp: the size of the user buffer   * @ppos: file position @@ -2756,10 +2674,10 @@ static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,   *   * Returns 0 on success.   */ -int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_jiffies(struct ctl_table *table, int write,  			  void __user *buffer, size_t *lenp, loff_t *ppos)  { -    return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, +    return do_proc_dointvec(table,write,buffer,lenp,ppos,  		    	    do_proc_dointvec_jiffies_conv,NULL);  } @@ -2767,7 +2685,6 @@ int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,   * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds   * @table: the sysctl table   * @write: %TRUE if this is a write to the sysctl file - * @filp: the file structure   * @buffer: the user buffer   * @lenp: the size of the user buffer   * @ppos: pointer to the file position @@ -2779,10 +2696,10 @@ int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,   *   * Returns 0 on success.   */ -int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write,  				 void __user *buffer, size_t *lenp, loff_t *ppos)  { -    return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, +    return do_proc_dointvec(table,write,buffer,lenp,ppos,  		    	    do_proc_dointvec_userhz_jiffies_conv,NULL);  } @@ -2790,7 +2707,6 @@ int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file   * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds   * @table: the sysctl table   * @write: %TRUE if this is a write to the sysctl file - * @filp: the file structure   * @buffer: the user buffer   * @lenp: the size of the user buffer   * @ppos: file position @@ -2803,14 +2719,14 @@ int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file   *   * Returns 0 on success.   */ -int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_ms_jiffies(struct ctl_table *table, int write,  			     void __user *buffer, size_t *lenp, loff_t *ppos)  { -	return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, +	return do_proc_dointvec(table, write, buffer, lenp, ppos,  				do_proc_dointvec_ms_jiffies_conv, NULL);  } -static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, +static int proc_do_cad_pid(struct ctl_table *table, int write,  			   void __user *buffer, size_t *lenp, loff_t *ppos)  {  	struct pid *new_pid; @@ -2819,7 +2735,7 @@ static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp  	tmp = pid_vnr(cad_pid); -	r = __do_proc_dointvec(&tmp, table, write, filp, buffer, +	r = __do_proc_dointvec(&tmp, table, write, buffer,  			       lenp, ppos, NULL, NULL);  	if (r || !write)  		return r; @@ -2832,340 +2748,210 @@ static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp  	return 0;  } -#else /* CONFIG_PROC_FS */ - -int proc_dostring(struct ctl_table *table, int write, struct file *filp, -		  void __user *buffer, size_t *lenp, loff_t *ppos) -{ -	return -ENOSYS; -} - -int proc_dointvec(struct ctl_table *table, int write, struct file *filp, -		  void __user *buffer, size_t *lenp, loff_t *ppos) -{ -	return -ENOSYS; -} - -int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, -		    void __user *buffer, size_t *lenp, loff_t *ppos) -{ -	return -ENOSYS; -} - -int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, -		    void __user *buffer, size_t *lenp, loff_t *ppos) -{ -	return -ENOSYS; -} - -int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, -		    void __user *buffer, size_t *lenp, loff_t *ppos) -{ -	return -ENOSYS; -} - -int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, -			     void __user *buffer, size_t *lenp, loff_t *ppos) -{ -	return -ENOSYS; -} - -int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, -		    void __user *buffer, size_t *lenp, loff_t *ppos) -{ -	return -ENOSYS; -} - -int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, -				      struct file *filp, -				      void __user *buffer, -				      size_t *lenp, loff_t *ppos) -{ -    return -ENOSYS; -} - - -#endif /* CONFIG_PROC_FS */ - - -#ifdef CONFIG_SYSCTL_SYSCALL -/* - * General sysctl support routines  +/** + * proc_do_large_bitmap - read/write from/to a large bitmap + * @table: the sysctl table + * @write: %TRUE if this is a write to the sysctl file + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: file position + * + * The bitmap is stored at table->data and the bitmap length (in bits) + * in table->maxlen. + * + * We use a range comma separated format (e.g. 1,3-4,10-10) so that + * large bitmaps may be represented in a compact manner. Writing into + * the file will clear the bitmap then update it with the given input. + * + * Returns 0 on success.   */ - -/* The generic sysctl data routine (used if no strategy routine supplied) */ -int sysctl_data(struct ctl_table *table, -		void __user *oldval, size_t __user *oldlenp, -		void __user *newval, size_t newlen) -{ -	size_t len; - -	/* Get out of I don't have a variable */ -	if (!table->data || !table->maxlen) -		return -ENOTDIR; - -	if (oldval && oldlenp) { -		if (get_user(len, oldlenp)) -			return -EFAULT; -		if (len) { -			if (len > table->maxlen) -				len = table->maxlen; -			if (copy_to_user(oldval, table->data, len)) -				return -EFAULT; -			if (put_user(len, oldlenp)) -				return -EFAULT; -		} -	} - -	if (newval && newlen) { -		if (newlen > table->maxlen) -			newlen = table->maxlen; - -		if (copy_from_user(table->data, newval, newlen)) -			return -EFAULT; +int proc_do_large_bitmap(struct ctl_table *table, int write, +			 void __user *buffer, size_t *lenp, loff_t *ppos) +{ +	int err = 0; +	bool first = 1; +	size_t left = *lenp; +	unsigned long bitmap_len = table->maxlen; +	unsigned long *bitmap = (unsigned long *) table->data; +	unsigned long *tmp_bitmap = NULL; +	char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c; + +	if (!bitmap_len || !left || (*ppos && !write)) { +		*lenp = 0; +		return 0;  	} -	return 1; -} -/* The generic string strategy routine: */ -int sysctl_string(struct ctl_table *table, -		  void __user *oldval, size_t __user *oldlenp, -		  void __user *newval, size_t newlen) -{ -	if (!table->data || !table->maxlen)  -		return -ENOTDIR; -	 -	if (oldval && oldlenp) { -		size_t bufsize; -		if (get_user(bufsize, oldlenp)) +	if (write) { +		unsigned long page = 0; +		char *kbuf; + +		if (left > PAGE_SIZE - 1) +			left = PAGE_SIZE - 1; + +		page = __get_free_page(GFP_TEMPORARY); +		kbuf = (char *) page; +		if (!kbuf) +			return -ENOMEM; +		if (copy_from_user(kbuf, buffer, left)) { +			free_page(page);  			return -EFAULT; -		if (bufsize) { -			size_t len = strlen(table->data), copied; - -			/* This shouldn't trigger for a well-formed sysctl */ -			if (len > table->maxlen) -				len = table->maxlen; - -			/* Copy up to a max of bufsize-1 bytes of the string */ -			copied = (len >= bufsize) ? bufsize - 1 : len; - -			if (copy_to_user(oldval, table->data, copied) || -			    put_user(0, (char __user *)(oldval + copied))) -				return -EFAULT; -			if (put_user(len, oldlenp)) -				return -EFAULT; +                } +		kbuf[left] = 0; + +		tmp_bitmap = kzalloc(BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long), +				     GFP_KERNEL); +		if (!tmp_bitmap) { +			free_page(page); +			return -ENOMEM;  		} -	} -	if (newval && newlen) { -		size_t len = newlen; -		if (len > table->maxlen) -			len = table->maxlen; -		if(copy_from_user(table->data, newval, len)) -			return -EFAULT; -		if (len == table->maxlen) -			len--; -		((char *) table->data)[len] = 0; -	} -	return 1; -} - -/* - * This function makes sure that all of the integers in the vector - * are between the minimum and maximum values given in the arrays - * table->extra1 and table->extra2, respectively. - */ -int sysctl_intvec(struct ctl_table *table, -		void __user *oldval, size_t __user *oldlenp, -		void __user *newval, size_t newlen) -{ - -	if (newval && newlen) { -		int __user *vec = (int __user *) newval; -		int *min = (int *) table->extra1; -		int *max = (int *) table->extra2; -		size_t length; -		int i; +		proc_skip_char(&kbuf, &left, '\n'); +		while (!err && left) { +			unsigned long val_a, val_b; +			bool neg; + +			err = proc_get_long(&kbuf, &left, &val_a, &neg, tr_a, +					     sizeof(tr_a), &c); +			if (err) +				break; +			if (val_a >= bitmap_len || neg) { +				err = -EINVAL; +				break; +			} -		if (newlen % sizeof(int) != 0) -			return -EINVAL; +			val_b = val_a; +			if (left) { +				kbuf++; +				left--; +			} -		if (!table->extra1 && !table->extra2) -			return 0; +			if (c == '-') { +				err = proc_get_long(&kbuf, &left, &val_b, +						     &neg, tr_b, sizeof(tr_b), +						     &c); +				if (err) +					break; +				if (val_b >= bitmap_len || neg || +				    val_a > val_b) { +					err = -EINVAL; +					break; +				} +				if (left) { +					kbuf++; +					left--; +				} +			} -		if (newlen > table->maxlen) -			newlen = table->maxlen; -		length = newlen / sizeof(int); +			while (val_a <= val_b) +				set_bit(val_a++, tmp_bitmap); -		for (i = 0; i < length; i++) { -			int value; -			if (get_user(value, vec + i)) -				return -EFAULT; -			if (min && value < min[i]) -				return -EINVAL; -			if (max && value > max[i]) -				return -EINVAL; +			first = 0; +			proc_skip_char(&kbuf, &left, '\n');  		} -	} -	return 0; -} - -/* Strategy function to convert jiffies to seconds */  -int sysctl_jiffies(struct ctl_table *table, -		void __user *oldval, size_t __user *oldlenp, -		void __user *newval, size_t newlen) -{ -	if (oldval && oldlenp) { -		size_t olen; +		free_page(page); +	} else { +		unsigned long bit_a, bit_b = 0; -		if (get_user(olen, oldlenp)) -			return -EFAULT; -		if (olen) { -			int val; +		while (left) { +			bit_a = find_next_bit(bitmap, bitmap_len, bit_b); +			if (bit_a >= bitmap_len) +				break; +			bit_b = find_next_zero_bit(bitmap, bitmap_len, +						   bit_a + 1) - 1; -			if (olen < sizeof(int)) -				return -EINVAL; +			if (!first) { +				err = proc_put_char(&buffer, &left, ','); +				if (err) +					break; +			} +			err = proc_put_long(&buffer, &left, bit_a, false); +			if (err) +				break; +			if (bit_a != bit_b) { +				err = proc_put_char(&buffer, &left, '-'); +				if (err) +					break; +				err = proc_put_long(&buffer, &left, bit_b, false); +				if (err) +					break; +			} -			val = *(int *)(table->data) / HZ; -			if (put_user(val, (int __user *)oldval)) -				return -EFAULT; -			if (put_user(sizeof(int), oldlenp)) -				return -EFAULT; +			first = 0; bit_b++;  		} +		if (!err) +			err = proc_put_char(&buffer, &left, '\n');  	} -	if (newval && newlen) {  -		int new; -		if (newlen != sizeof(int)) -			return -EINVAL;  -		if (get_user(new, (int __user *)newval)) -			return -EFAULT; -		*(int *)(table->data) = new*HZ;  -	} -	return 1; -} - -/* Strategy function to convert jiffies to seconds */  -int sysctl_ms_jiffies(struct ctl_table *table, -		void __user *oldval, size_t __user *oldlenp, -		void __user *newval, size_t newlen) -{ -	if (oldval && oldlenp) { -		size_t olen; - -		if (get_user(olen, oldlenp)) -			return -EFAULT; -		if (olen) { -			int val; -			if (olen < sizeof(int)) -				return -EINVAL; - -			val = jiffies_to_msecs(*(int *)(table->data)); -			if (put_user(val, (int __user *)oldval)) -				return -EFAULT; -			if (put_user(sizeof(int), oldlenp)) -				return -EFAULT; +	if (!err) { +		if (write) { +			if (*ppos) +				bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len); +			else +				memcpy(bitmap, tmp_bitmap, +					BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long));  		} +		kfree(tmp_bitmap); +		*lenp -= left; +		*ppos += *lenp; +		return 0; +	} else { +		kfree(tmp_bitmap); +		return err;  	} -	if (newval && newlen) {  -		int new; -		if (newlen != sizeof(int)) -			return -EINVAL;  -		if (get_user(new, (int __user *)newval)) -			return -EFAULT; -		*(int *)(table->data) = msecs_to_jiffies(new); -	} -	return 1;  } +#else /* CONFIG_PROC_FS */ - -#else /* CONFIG_SYSCTL_SYSCALL */ - - -SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args) +int proc_dostring(struct ctl_table *table, int write, +		  void __user *buffer, size_t *lenp, loff_t *ppos)  { -	struct __sysctl_args tmp; -	int error; - -	if (copy_from_user(&tmp, args, sizeof(tmp))) -		return -EFAULT; - -	error = deprecated_sysctl_warning(&tmp); - -	/* If no error reading the parameters then just -ENOSYS ... */ -	if (!error) -		error = -ENOSYS; - -	return error; +	return -ENOSYS;  } -int sysctl_data(struct ctl_table *table, -		  void __user *oldval, size_t __user *oldlenp, -		  void __user *newval, size_t newlen) +int proc_dointvec(struct ctl_table *table, int write, +		  void __user *buffer, size_t *lenp, loff_t *ppos)  {  	return -ENOSYS;  } -int sysctl_string(struct ctl_table *table, -		  void __user *oldval, size_t __user *oldlenp, -		  void __user *newval, size_t newlen) +int proc_dointvec_minmax(struct ctl_table *table, int write, +		    void __user *buffer, size_t *lenp, loff_t *ppos)  {  	return -ENOSYS;  } -int sysctl_intvec(struct ctl_table *table, -		void __user *oldval, size_t __user *oldlenp, -		void __user *newval, size_t newlen) +int proc_dointvec_jiffies(struct ctl_table *table, int write, +		    void __user *buffer, size_t *lenp, loff_t *ppos)  {  	return -ENOSYS;  } -int sysctl_jiffies(struct ctl_table *table, -		void __user *oldval, size_t __user *oldlenp, -		void __user *newval, size_t newlen) +int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, +		    void __user *buffer, size_t *lenp, loff_t *ppos)  {  	return -ENOSYS;  } -int sysctl_ms_jiffies(struct ctl_table *table, -		void __user *oldval, size_t __user *oldlenp, -		void __user *newval, size_t newlen) +int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, +			     void __user *buffer, size_t *lenp, loff_t *ppos)  {  	return -ENOSYS;  } -#endif /* CONFIG_SYSCTL_SYSCALL */ - -static int deprecated_sysctl_warning(struct __sysctl_args *args) +int proc_doulongvec_minmax(struct ctl_table *table, int write, +		    void __user *buffer, size_t *lenp, loff_t *ppos)  { -	static int msg_count; -	int name[CTL_MAXNAME]; -	int i; - -	/* Check args->nlen. */ -	if (args->nlen < 0 || args->nlen > CTL_MAXNAME) -		return -ENOTDIR; +	return -ENOSYS; +} -	/* Read in the sysctl name for better debug message logging */ -	for (i = 0; i < args->nlen; i++) -		if (get_user(name[i], args->name + i)) -			return -EFAULT; +int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, +				      void __user *buffer, +				      size_t *lenp, loff_t *ppos) +{ +    return -ENOSYS; +} -	/* Ignore accesses to kernel.version */ -	if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION)) -		return 0; -	if (msg_count < 5) { -		msg_count++; -		printk(KERN_INFO -			"warning: process `%s' used the deprecated sysctl " -			"system call with ", current->comm); -		for (i = 0; i < args->nlen; i++) -			printk("%d.", name[i]); -		printk("\n"); -	} -	return 0; -} +#endif /* CONFIG_PROC_FS */  /*   * No sense putting this after each symbol definition, twice, @@ -3181,9 +2967,4 @@ EXPORT_SYMBOL(proc_doulongvec_minmax);  EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);  EXPORT_SYMBOL(register_sysctl_table);  EXPORT_SYMBOL(register_sysctl_paths); -EXPORT_SYMBOL(sysctl_intvec); -EXPORT_SYMBOL(sysctl_jiffies); -EXPORT_SYMBOL(sysctl_ms_jiffies); -EXPORT_SYMBOL(sysctl_string); -EXPORT_SYMBOL(sysctl_data);  EXPORT_SYMBOL(unregister_sysctl_table); | 
