Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild
[sfrench/cifs-2.6.git] / kernel / sysctl.c
index ec14aa8ac51fc83b820330af559077e1cc2cf797..3b4efbe2644572a32576b1a591f003e9869699f0 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
-#include <linux/capability.h>
+#include <linux/security.h>
 #include <linux/ctype.h>
 #include <linux/utsname.h>
 #include <linux/smp_lock.h>
@@ -55,6 +55,8 @@
 #include <asm/stacktrace.h>
 #endif
 
+static int deprecated_sysctl_warning(struct __sysctl_args *args);
+
 #if defined(CONFIG_SYSCTL)
 
 /* External variables not in a header file. */
@@ -63,6 +65,7 @@ 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 max_threads;
 extern int core_uses_pid;
 extern int suid_dumpable;
@@ -79,6 +82,19 @@ extern int maps_protect;
 extern int sysctl_stat_interval;
 extern int audit_argv_kb;
 
+/* Constants used for minimum and  maximum */
+#ifdef CONFIG_DETECT_SOFTLOCKUP
+static int one = 1;
+static int sixty = 60;
+#endif
+
+#ifdef CONFIG_MMU
+static int two = 2;
+#endif
+
+static int zero;
+static int one_hundred = 100;
+
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
 static int minolduid;
@@ -128,32 +144,29 @@ extern int max_lock_depth;
 
 #ifdef CONFIG_SYSCTL_SYSCALL
 static int parse_table(int __user *, int, void __user *, size_t __user *,
-               void __user *, size_t, ctl_table *);
+               void __user *, size_t, struct ctl_table *);
 #endif
 
 
 #ifdef CONFIG_PROC_SYSCTL
-static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
+static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos);
-static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
+static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
                               void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
 
-static ctl_table root_table[];
+static struct ctl_table root_table[];
 static struct ctl_table_header root_table_header =
        { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
 
-static ctl_table kern_table[];
-static ctl_table vm_table[];
-static ctl_table fs_table[];
-static ctl_table debug_table[];
-static ctl_table dev_table[];
-extern ctl_table random_table[];
-#ifdef CONFIG_UNIX98_PTYS
-extern ctl_table pty_table[];
-#endif
+static struct ctl_table kern_table[];
+static struct ctl_table vm_table[];
+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 ctl_table inotify_table[];
+extern struct ctl_table inotify_table[];
 #endif
 
 #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
@@ -165,7 +178,7 @@ extern int lock_stat;
 
 /* The default sysctl tables: */
 
-static ctl_table root_table[] = {
+static struct ctl_table root_table[] = {
        {
                .ctl_name       = CTL_KERN,
                .procname       = "kernel",
@@ -218,7 +231,7 @@ static unsigned long min_wakeup_granularity_ns;                     /* 0 usecs */
 static unsigned long max_wakeup_granularity_ns = 1000000000;   /* 1 second */
 #endif
 
-static ctl_table kern_table[] = {
+static struct ctl_table kern_table[] = {
 #ifdef CONFIG_SCHED_DEBUG
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -351,7 +364,6 @@ static ctl_table kern_table[] = {
        },
 #ifdef CONFIG_PROC_SYSCTL
        {
-               .ctl_name       = KERN_TAINTED,
                .procname       = "tainted",
                .data           = &tainted,
                .maxlen         = sizeof(int),
@@ -359,14 +371,15 @@ static ctl_table kern_table[] = {
                .proc_handler   = &proc_dointvec_taint,
        },
 #endif
+#ifdef CONFIG_SECURITY_CAPABILITIES
        {
-               .ctl_name       = KERN_CAP_BSET,
                .procname       = "cap-bound",
                .data           = &cap_bset,
                .maxlen         = sizeof(kernel_cap_t),
                .mode           = 0600,
                .proc_handler   = &proc_dointvec_bset,
        },
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
 #ifdef CONFIG_BLK_DEV_INITRD
        {
                .ctl_name       = KERN_REALROOTDEV,
@@ -500,7 +513,6 @@ static ctl_table kern_table[] = {
 #endif
 #ifdef CONFIG_PROC_SYSCTL
        {
-               .ctl_name       = KERN_CADPID,
                .procname       = "cad_pid",
                .data           = NULL,
                .maxlen         = sizeof (int),
@@ -522,14 +534,6 @@ static ctl_table kern_table[] = {
                .mode           = 0555,
                .child          = random_table,
        },
-#ifdef CONFIG_UNIX98_PTYS
-       {
-               .ctl_name       = KERN_PTY,
-               .procname       = "pty",
-               .mode           = 0555,
-               .child          = pty_table,
-       },
-#endif
        {
                .ctl_name       = KERN_OVERFLOWUID,
                .procname       = "overflowuid",
@@ -636,7 +640,6 @@ static ctl_table kern_table[] = {
                .proc_handler   = &proc_dointvec,
        },
        {
-               .ctl_name       = KERN_NMI_WATCHDOG,
                .procname       = "nmi_watchdog",
                .data           = &nmi_watchdog_enabled,
                .maxlen         = sizeof (int),
@@ -692,7 +695,6 @@ static ctl_table kern_table[] = {
 #endif
 #if    defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86)
        {
-               .ctl_name       = KERN_ACPI_VIDEO_FLAGS,
                .procname       = "acpi_video_flags",
                .data           = &acpi_realmode_flags,
                .maxlen         = sizeof (unsigned long),
@@ -710,6 +712,19 @@ static ctl_table kern_table[] = {
                .proc_handler   = &proc_dointvec,
        },
 #endif
+#ifdef CONFIG_DETECT_SOFTLOCKUP
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "softlockup_thresh",
+               .data           = &softlockup_thresh,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &one,
+               .extra2         = &sixty,
+       },
+#endif
 #ifdef CONFIG_COMPAT
        {
                .ctl_name       = KERN_COMPAT_LOG,
@@ -756,14 +771,7 @@ static ctl_table kern_table[] = {
        { .ctl_name = 0 }
 };
 
-/* Constants for minimum and maximum testing in vm_table.
-   We use these as one-element integer vectors. */
-static int zero;
-static int two = 2;
-static int one_hundred = 100;
-
-
-static ctl_table vm_table[] = {
+static struct ctl_table vm_table[] = {
        {
                .ctl_name       = VM_OVERCOMMIT_MEMORY,
                .procname       = "overcommit_memory",
@@ -780,6 +788,14 @@ static ctl_table vm_table[] = {
                .mode           = 0644,
                .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,
+       },
        {
                .ctl_name       = VM_OVERCOMMIT_RATIO,
                .procname       = "overcommit_ratio",
@@ -813,13 +829,12 @@ static ctl_table vm_table[] = {
                .data           = &vm_dirty_ratio,
                .maxlen         = sizeof(vm_dirty_ratio),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
+               .proc_handler   = &dirty_ratio_handler,
                .strategy       = &sysctl_intvec,
                .extra1         = &zero,
                .extra2         = &one_hundred,
        },
        {
-               .ctl_name       = VM_DIRTY_WB_CS,
                .procname       = "dirty_writeback_centisecs",
                .data           = &dirty_writeback_interval,
                .maxlen         = sizeof(dirty_writeback_interval),
@@ -827,7 +842,6 @@ static ctl_table vm_table[] = {
                .proc_handler   = &dirty_writeback_centisecs_handler,
        },
        {
-               .ctl_name       = VM_DIRTY_EXPIRE_CS,
                .procname       = "dirty_expire_centisecs",
                .data           = &dirty_expire_interval,
                .maxlen         = sizeof(dirty_expire_interval),
@@ -855,7 +869,6 @@ static ctl_table vm_table[] = {
        },
 #ifdef CONFIG_HUGETLB_PAGE
         {
-               .ctl_name       = VM_HUGETLB_PAGES,
                .procname       = "nr_hugepages",
                .data           = &max_huge_pages,
                .maxlen         = sizeof(unsigned long),
@@ -880,6 +893,14 @@ static ctl_table vm_table[] = {
                .mode           = 0644,
                .proc_handler   = &hugetlb_treat_movable_handler,
        },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "hugetlb_dynamic_pool",
+               .data           = &hugetlb_dynamic_pool,
+               .maxlen         = sizeof(hugetlb_dynamic_pool),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
 #endif
        {
                .ctl_name       = VM_LOWMEM_RESERVE_RATIO,
@@ -1057,12 +1078,12 @@ static ctl_table vm_table[] = {
 };
 
 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
-static ctl_table binfmt_misc_table[] = {
+static struct ctl_table binfmt_misc_table[] = {
        { .ctl_name = 0 }
 };
 #endif
 
-static ctl_table fs_table[] = {
+static struct ctl_table fs_table[] = {
        {
                .ctl_name       = FS_NRINODE,
                .procname       = "inode-nr",
@@ -1080,7 +1101,6 @@ static ctl_table fs_table[] = {
                .proc_handler   = &proc_dointvec,
        },
        {
-               .ctl_name       = FS_NRFILE,
                .procname       = "file-nr",
                .data           = &files_stat,
                .maxlen         = 3*sizeof(int),
@@ -1156,7 +1176,6 @@ static ctl_table fs_table[] = {
                .extra2         = &two,
        },
        {
-               .ctl_name       = FS_AIO_NR,
                .procname       = "aio-nr",
                .data           = &aio_nr,
                .maxlen         = sizeof(aio_nr),
@@ -1164,7 +1183,6 @@ static ctl_table fs_table[] = {
                .proc_handler   = &proc_doulongvec_minmax,
        },
        {
-               .ctl_name       = FS_AIO_MAX_NR,
                .procname       = "aio-max-nr",
                .data           = &aio_max_nr,
                .maxlen         = sizeof(aio_max_nr),
@@ -1203,7 +1221,7 @@ static ctl_table fs_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table debug_table[] = {
+static struct ctl_table debug_table[] = {
 #if defined(CONFIG_X86) || defined(CONFIG_PPC)
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -1217,7 +1235,7 @@ static ctl_table debug_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table dev_table[] = {
+static struct ctl_table dev_table[] = {
        { .ctl_name = 0 }
 };
 
@@ -1333,10 +1351,15 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
        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 */
@@ -1357,7 +1380,7 @@ static int test_perm(int mode, int op)
        return -EACCES;
 }
 
-int sysctl_perm(ctl_table *table, int op)
+int sysctl_perm(struct ctl_table *table, int op)
 {
        int error;
        error = security_sysctl(table, op);
@@ -1370,7 +1393,7 @@ int sysctl_perm(ctl_table *table, int op)
 static int parse_table(int __user *name, int nlen,
                       void __user *oldval, size_t __user *oldlenp,
                       void __user *newval, size_t newlen,
-                      ctl_table *table)
+                      struct ctl_table *table)
 {
        int n;
 repeat:
@@ -1401,13 +1424,12 @@ repeat:
 }
 
 /* Perform the actual read/write of a sysctl table entry. */
-int do_sysctl_strategy (ctl_table *table, 
+int do_sysctl_strategy (struct ctl_table *table,
                        int __user *name, int nlen,
                        void __user *oldval, size_t __user *oldlenp,
                        void __user *newval, size_t newlen)
 {
        int op = 0, rc;
-       size_t len;
 
        if (oldval)
                op |= 004;
@@ -1428,25 +1450,10 @@ int do_sysctl_strategy (ctl_table *table,
        /* If there is no strategy routine, or if the strategy returns
         * zero, proceed with automatic r/w */
        if (table->data && table->maxlen) {
-               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) {
-                       len = newlen;
-                       if (len > table->maxlen)
-                               len = table->maxlen;
-                       if(copy_from_user(table->data, newval, len))
-                               return -EFAULT;
-               }
+               rc = sysctl_data(table, name, nlen, oldval, oldlenp,
+                                newval, newlen);
+               if (rc < 0)
+                       return rc;
        }
        return 0;
 }
@@ -1463,7 +1470,9 @@ static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
 
 static __init int sysctl_init(void)
 {
+       int err;
        sysctl_set_parent(NULL, root_table);
+       err = sysctl_check_table(root_table);
        return 0;
 }
 
@@ -1476,7 +1485,7 @@ core_initcall(sysctl_init);
  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
  * array. An entry with a ctl_name of 0 terminates the table. 
  *
- * The members of the &ctl_table structure are used as follows:
+ * 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
@@ -1537,7 +1546,7 @@ core_initcall(sysctl_init);
  * This routine returns %NULL on a failure to register, and a pointer
  * to the table header on success.
  */
-struct ctl_table_header *register_sysctl_table(ctl_table * table)
+struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
 {
        struct ctl_table_header *tmp;
        tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
@@ -1548,6 +1557,10 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table)
        tmp->used = 0;
        tmp->unregistering = NULL;
        sysctl_set_parent(NULL, table);
+       if (sysctl_check_table(tmp->ctl_table)) {
+               kfree(tmp);
+               return NULL;
+       }
        spin_lock(&sysctl_lock);
        list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
        spin_unlock(&sysctl_lock);
@@ -1571,7 +1584,7 @@ void unregister_sysctl_table(struct ctl_table_header * header)
 }
 
 #else /* !CONFIG_SYSCTL */
-struct ctl_table_header *register_sysctl_table(ctl_table * table)
+struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
 {
        return NULL;
 }
@@ -1664,7 +1677,7 @@ static int _proc_do_string(void* data, int maxlen, int write,
  *
  * Returns 0 on success.
  */
-int proc_dostring(ctl_table *table, int write, struct file *filp,
+int proc_dostring(struct ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return _proc_do_string(table->data, table->maxlen, write, filp,
@@ -1691,7 +1704,7 @@ static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
        return 0;
 }
 
-static int __do_proc_dointvec(void *tbl_data, ctl_table *table,
+static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
                  int write, struct file *filp, void __user *buffer,
                  size_t *lenp, loff_t *ppos,
                  int (*conv)(int *negp, unsigned long *lvalp, int *valp,
@@ -1801,7 +1814,7 @@ static int __do_proc_dointvec(void *tbl_data, ctl_table *table,
 #undef TMPBUFLEN
 }
 
-static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
+static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos,
                  int (*conv)(int *negp, unsigned long *lvalp, int *valp,
                              int write, void *data),
@@ -1825,7 +1838,7 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
  *
  * Returns 0 on success.
  */
-int proc_dointvec(ctl_table *table, int write, struct file *filp,
+int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
                     void __user *buffer, size_t *lenp, loff_t *ppos)
 {
     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -1861,11 +1874,12 @@ static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
        return 0;
 }
 
+#ifdef CONFIG_SECURITY_CAPABILITIES
 /*
  *     init may raise the set.
  */
-int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
+
+int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
                        void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        int op;
@@ -1874,15 +1888,16 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
                return -EPERM;
        }
 
-       op = is_init(current) ? OP_SET : OP_AND;
+       op = is_global_init(current) ? OP_SET : OP_AND;
        return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
                                do_proc_dointvec_bset_conv,&op);
 }
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
 
 /*
  *     Taint values can only be increased
  */
-static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
+static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
                               void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        int op;
@@ -1941,7 +1956,7 @@ static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,
  *
  * Returns 0 on success.
  */
-int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        struct do_proc_dointvec_minmax_conv_param param = {
@@ -1952,7 +1967,7 @@ int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
                                do_proc_dointvec_minmax_conv, &param);
 }
 
-static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write,
+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,
@@ -2057,7 +2072,7 @@ static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write,
 #undef TMPBUFLEN
 }
 
-static int do_proc_doulongvec_minmax(ctl_table *table, int write,
+static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
                                     struct file *filp,
                                     void __user *buffer,
                                     size_t *lenp, loff_t *ppos,
@@ -2085,7 +2100,7 @@ static int do_proc_doulongvec_minmax(ctl_table *table, int write,
  *
  * Returns 0 on success.
  */
-int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_doulongvec_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, lenp, ppos, 1l, 1l);
@@ -2109,7 +2124,7 @@ int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
  *
  * Returns 0 on success.
  */
-int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
+int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
                                      struct file *filp,
                                      void __user *buffer,
                                      size_t *lenp, loff_t *ppos)
@@ -2202,7 +2217,7 @@ static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,
  *
  * Returns 0 on success.
  */
-int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
                          void __user *buffer, size_t *lenp, loff_t *ppos)
 {
     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -2225,7 +2240,7 @@ int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
  *
  * Returns 0 on success.
  */
-int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
                                 void __user *buffer, size_t *lenp, loff_t *ppos)
 {
     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -2249,21 +2264,21 @@ int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
  *
  * Returns 0 on success.
  */
-int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
                             void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
                                do_proc_dointvec_ms_jiffies_conv, NULL);
 }
 
-static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
+static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
                           void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        struct pid *new_pid;
        pid_t tmp;
        int r;
 
-       tmp = pid_nr(cad_pid);
+       tmp = pid_nr_ns(cad_pid, current->nsproxy->pid_ns);
 
        r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
                               lenp, ppos, NULL, NULL);
@@ -2280,55 +2295,55 @@ static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
 
 #else /* CONFIG_PROC_FS */
 
-int proc_dostring(ctl_table *table, int write, struct file *filp,
+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(ctl_table *table, int write, struct file *filp,
+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_bset(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
                        void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return -ENOSYS;
 }
 
-int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
+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(ctl_table *table, int write, struct file *filp,
+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(ctl_table *table, int write, struct file *filp,
+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(ctl_table *table, int write, struct file *filp,
+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(ctl_table *table, int write, struct file *filp,
+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(ctl_table *table, int write,
+int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
                                      struct file *filp,
                                      void __user *buffer,
                                      size_t *lenp, loff_t *ppos)
@@ -2345,8 +2360,42 @@ int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
  * General sysctl support routines 
  */
 
+/* The generic sysctl data routine (used if no strategy routine supplied) */
+int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
+               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;
+       }
+       return 1;
+}
+
 /* The generic string strategy routine: */
-int sysctl_string(ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
                  void __user *oldval, size_t __user *oldlenp,
                  void __user *newval, size_t newlen)
 {
@@ -2392,7 +2441,7 @@ int sysctl_string(ctl_table *table, int __user *name, int nlen,
  * are between the minimum and maximum values given in the arrays
  * table->extra1 and table->extra2, respectively.
  */
-int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
+int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2428,7 +2477,7 @@ int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
 }
 
 /* Strategy function to convert jiffies to seconds */ 
-int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2462,7 +2511,7 @@ int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
 }
 
 /* Strategy function to convert jiffies to seconds */ 
-int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2502,59 +2551,50 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
 
 asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
 {
-       static int msg_count;
        struct __sysctl_args tmp;
-       int name[CTL_MAXNAME];
-       int i;
+       int error;
 
-       /* Read in the sysctl name for better debug message logging */
        if (copy_from_user(&tmp, args, sizeof(tmp)))
                return -EFAULT;
-       if (tmp.nlen <= 0 || tmp.nlen >= CTL_MAXNAME)
-               return -ENOTDIR;
-       for (i = 0; i < tmp.nlen; i++)
-               if (get_user(name[i], tmp.name + i))
-                       return -EFAULT;
 
-       /* Ignore accesses to kernel.version */
-       if ((tmp.nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
-               goto out;
+       error = deprecated_sysctl_warning(&tmp);
 
-       if (msg_count < 5) {
-               msg_count++;
-               printk(KERN_INFO
-                       "warning: process `%s' used the removed sysctl "
-                       "system call with ", current->comm);
-               for (i = 0; i < tmp.nlen; i++)
-                       printk("%d.", name[i]);
-               printk("\n");
-       }
-out:
+       /* If no error reading the parameters then just -ENOSYS ... */
+       if (!error)
+               error = -ENOSYS;
+
+       return error;
+}
+
+int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
+                 void __user *oldval, size_t __user *oldlenp,
+                 void __user *newval, size_t newlen)
+{
        return -ENOSYS;
 }
 
-int sysctl_string(ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
                  void __user *oldval, size_t __user *oldlenp,
                  void __user *newval, size_t newlen)
 {
        return -ENOSYS;
 }
 
-int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
+int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
        return -ENOSYS;
 }
 
-int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
        return -ENOSYS;
 }
 
-int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2563,6 +2603,33 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
 
 #endif /* CONFIG_SYSCTL_SYSCALL */
 
+static int deprecated_sysctl_warning(struct __sysctl_args *args)
+{
+       static int msg_count;
+       int name[CTL_MAXNAME];
+       int i;
+
+       /* 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;
+
+       /* 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;
+}
+
 /*
  * No sense putting this after each symbol definition, twice,
  * exception granted :-)
@@ -2580,4 +2647,5 @@ 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);