vt8623fb: new framebuffer driver for VIA VT8623
[powerpc.git] / kernel / sysctl.c
index c3e2ac9..4073353 100644 (file)
@@ -76,6 +76,8 @@ extern int pid_max_min, pid_max_max;
 extern int sysctl_drop_caches;
 extern int percpu_pagelist_fraction;
 extern int compat_log;
+extern int maps_protect;
+extern int sysctl_stat_interval;
 
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
@@ -159,26 +161,6 @@ int sysctl_legacy_va_layout;
 #endif
 
 
-/* /proc declarations: */
-
-#ifdef CONFIG_PROC_SYSCTL
-
-static ssize_t proc_readsys(struct file *, char __user *, size_t, loff_t *);
-static ssize_t proc_writesys(struct file *, const char __user *, size_t, loff_t *);
-static int proc_opensys(struct inode *, struct file *);
-
-const struct file_operations proc_sys_file_operations = {
-       .open           = proc_opensys,
-       .read           = proc_readsys,
-       .write          = proc_writesys,
-};
-
-extern struct proc_dir_entry *proc_sys_root;
-
-static void register_proc_table(ctl_table *, struct proc_dir_entry *, void *);
-static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
-#endif
-
 /* The default sysctl tables: */
 
 static ctl_table root_table[] = {
@@ -623,6 +605,16 @@ static ctl_table kern_table[] = {
                .proc_handler   = &proc_dointvec,
        },
 #endif
+#ifdef CONFIG_PROC_FS
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "maps_protect",
+               .data           = &maps_protect,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
+#endif
 
        { .ctl_name = 0 }
 };
@@ -866,7 +858,19 @@ static ctl_table vm_table[] = {
                .extra2         = &one_hundred,
        },
 #endif
-#ifdef CONFIG_X86_32
+#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,
+       },
+#endif
+#if defined(CONFIG_X86_32) || \
+   (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
        {
                .ctl_name       = VM_VDSO_ENABLED,
                .procname       = "vdso_enabled",
@@ -1106,13 +1110,6 @@ struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
        return NULL;
 }
 
-void __init sysctl_init(void)
-{
-#ifdef CONFIG_PROC_SYSCTL
-       register_proc_table(root_table, proc_sys_root, &root_table_header);
-#endif
-}
-
 #ifdef CONFIG_SYSCTL_SYSCALL
 int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp,
               void __user *newval, size_t newlen)
@@ -1157,7 +1154,7 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
 #endif /* CONFIG_SYSCTL_SYSCALL */
 
 /*
- * ctl_perm does NOT grant the superuser all rights automatically, because
+ * sysctl_perm does NOT grant the superuser all rights automatically, because
  * some sysctl variables are readonly even to root.
  */
 
@@ -1172,7 +1169,7 @@ static int test_perm(int mode, int op)
        return -EACCES;
 }
 
-static inline int ctl_perm(ctl_table *table, int op)
+int sysctl_perm(ctl_table *table, int op)
 {
        int error;
        error = security_sysctl(table, op);
@@ -1199,7 +1196,7 @@ repeat:
                if (n == table->ctl_name) {
                        int error;
                        if (table->child) {
-                               if (ctl_perm(table, 001))
+                               if (sysctl_perm(table, 001))
                                        return -EPERM;
                                name++;
                                nlen--;
@@ -1228,7 +1225,7 @@ int do_sysctl_strategy (ctl_table *table,
                op |= 004;
        if (newval) 
                op |= 002;
-       if (ctl_perm(table, op))
+       if (sysctl_perm(table, op))
                return -EPERM;
 
        if (table->strategy) {
@@ -1267,6 +1264,23 @@ int do_sysctl_strategy (ctl_table *table,
 }
 #endif /* CONFIG_SYSCTL_SYSCALL */
 
+static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
+{
+       for (; table->ctl_name || table->procname; table++) {
+               table->parent = parent;
+               if (table->child)
+                       sysctl_set_parent(table, table->child);
+       }
+}
+
+static __init int sysctl_init(void)
+{
+       sysctl_set_parent(NULL, root_table);
+       return 0;
+}
+
+core_initcall(sysctl_init);
+
 /**
  * register_sysctl_table - register a sysctl hierarchy
  * @table: the top-level table structure
@@ -1345,12 +1359,10 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table)
        INIT_LIST_HEAD(&tmp->ctl_entry);
        tmp->used = 0;
        tmp->unregistering = NULL;
+       sysctl_set_parent(NULL, table);
        spin_lock(&sysctl_lock);
        list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
        spin_unlock(&sysctl_lock);
-#ifdef CONFIG_PROC_SYSCTL
-       register_proc_table(table, proc_sys_root, tmp);
-#endif
        return tmp;
 }
 
@@ -1366,16 +1378,12 @@ void unregister_sysctl_table(struct ctl_table_header * header)
        might_sleep();
        spin_lock(&sysctl_lock);
        start_unregistering(header);
-#ifdef CONFIG_PROC_SYSCTL
-       unregister_proc_table(header->ctl_table, proc_sys_root);
-#endif
        spin_unlock(&sysctl_lock);
        kfree(header);
 }
 
 #else /* !CONFIG_SYSCTL */
-struct ctl_table_header * register_sysctl_table(ctl_table * table,
-                                               int insert_at_head)
+struct ctl_table_header *register_sysctl_table(ctl_table * table)
 {
        return NULL;
 }
@@ -1392,155 +1400,6 @@ void unregister_sysctl_table(struct ctl_table_header * table)
 
 #ifdef CONFIG_PROC_SYSCTL
 
-/* Scan the sysctl entries in table and add them all into /proc */
-static void register_proc_table(ctl_table * table, struct proc_dir_entry *root, void *set)
-{
-       struct proc_dir_entry *de;
-       int len;
-       mode_t mode;
-       
-       for (; table->ctl_name || table->procname; table++) {
-               /* Can't do anything without a proc name. */
-               if (!table->procname)
-                       continue;
-               /* Maybe we can't do anything with it... */
-               if (!table->proc_handler && !table->child) {
-                       printk(KERN_WARNING "SYSCTL: Can't register %s\n",
-                               table->procname);
-                       continue;
-               }
-
-               len = strlen(table->procname);
-               mode = table->mode;
-
-               de = NULL;
-               if (table->proc_handler)
-                       mode |= S_IFREG;
-               else {
-                       mode |= S_IFDIR;
-                       for (de = root->subdir; de; de = de->next) {
-                               if (proc_match(len, table->procname, de))
-                                       break;
-                       }
-                       /* If the subdir exists already, de is non-NULL */
-               }
-
-               if (!de) {
-                       de = create_proc_entry(table->procname, mode, root);
-                       if (!de)
-                               continue;
-                       de->set = set;
-                       de->data = (void *) table;
-                       if (table->proc_handler)
-                               de->proc_fops = &proc_sys_file_operations;
-               }
-               table->de = de;
-               if (de->mode & S_IFDIR)
-                       register_proc_table(table->child, de, set);
-       }
-}
-
-/*
- * Unregister a /proc sysctl table and any subdirectories.
- */
-static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root)
-{
-       struct proc_dir_entry *de;
-       for (; table->ctl_name || table->procname; table++) {
-               if (!(de = table->de))
-                       continue;
-               if (de->mode & S_IFDIR) {
-                       if (!table->child) {
-                               printk (KERN_ALERT "Help - malformed sysctl tree on free\n");
-                               continue;
-                       }
-                       unregister_proc_table(table->child, de);
-
-                       /* Don't unregister directories which still have entries.. */
-                       if (de->subdir)
-                               continue;
-               }
-
-               /*
-                * In any case, mark the entry as goner; we'll keep it
-                * around if it's busy, but we'll know to do nothing with
-                * its fields.  We are under sysctl_lock here.
-                */
-               de->data = NULL;
-
-               /* Don't unregister proc entries that are still being used.. */
-               if (atomic_read(&de->count))
-                       continue;
-
-               table->de = NULL;
-               remove_proc_entry(table->procname, root);
-       }
-}
-
-static ssize_t do_rw_proc(int write, struct file * file, char __user * buf,
-                         size_t count, loff_t *ppos)
-{
-       int op;
-       struct proc_dir_entry *de = PDE(file->f_path.dentry->d_inode);
-       struct ctl_table *table;
-       size_t res;
-       ssize_t error = -ENOTDIR;
-       
-       spin_lock(&sysctl_lock);
-       if (de && de->data && use_table(de->set)) {
-               /*
-                * at that point we know that sysctl was not unregistered
-                * and won't be until we finish
-                */
-               spin_unlock(&sysctl_lock);
-               table = (struct ctl_table *) de->data;
-               if (!table || !table->proc_handler)
-                       goto out;
-               error = -EPERM;
-               op = (write ? 002 : 004);
-               if (ctl_perm(table, op))
-                       goto out;
-               
-               /* careful: calling conventions are nasty here */
-               res = count;
-               error = (*table->proc_handler)(table, write, file,
-                                               buf, &res, ppos);
-               if (!error)
-                       error = res;
-       out:
-               spin_lock(&sysctl_lock);
-               unuse_table(de->set);
-       }
-       spin_unlock(&sysctl_lock);
-       return error;
-}
-
-static int proc_opensys(struct inode *inode, struct file *file)
-{
-       if (file->f_mode & FMODE_WRITE) {
-               /*
-                * sysctl entries that are not writable,
-                * are _NOT_ writable, capabilities or not.
-                */
-               if (!(inode->i_mode & S_IWUSR))
-                       return -EPERM;
-       }
-
-       return 0;
-}
-
-static ssize_t proc_readsys(struct file * file, char __user * buf,
-                           size_t count, loff_t *ppos)
-{
-       return do_rw_proc(0, file, buf, count, ppos);
-}
-
-static ssize_t proc_writesys(struct file * file, const char __user * buf,
-                            size_t count, loff_t *ppos)
-{
-       return do_rw_proc(1, file, (char __user *) buf, count, ppos);
-}
-
 static int _proc_do_string(void* data, int maxlen, int write,
                           struct file *filp, void __user *buffer,
                           size_t *lenp, loff_t *ppos)
@@ -1840,7 +1699,7 @@ static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
 {
        int op;
 
-       if (!capable(CAP_SYS_ADMIN))
+       if (write && !capable(CAP_SYS_ADMIN))
                return -EPERM;
 
        op = OP_OR;