io_uring: add abstraction around apoll cache
[linux-2.6-microblaze.git] / ipc / mq_sysctl.c
index 72a92a0..fbf6a8b 100644 (file)
@@ -9,39 +9,9 @@
 #include <linux/ipc_namespace.h>
 #include <linux/sysctl.h>
 
-#ifdef CONFIG_PROC_SYSCTL
-static void *get_mq(struct ctl_table *table)
-{
-       char *which = table->data;
-       struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
-       which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
-       return which;
-}
-
-static int proc_mq_dointvec(struct ctl_table *table, int write,
-                           void *buffer, size_t *lenp, loff_t *ppos)
-{
-       struct ctl_table mq_table;
-       memcpy(&mq_table, table, sizeof(mq_table));
-       mq_table.data = get_mq(table);
-
-       return proc_dointvec(&mq_table, write, buffer, lenp, ppos);
-}
-
-static int proc_mq_dointvec_minmax(struct ctl_table *table, int write,
-               void *buffer, size_t *lenp, loff_t *ppos)
-{
-       struct ctl_table mq_table;
-       memcpy(&mq_table, table, sizeof(mq_table));
-       mq_table.data = get_mq(table);
-
-       return proc_dointvec_minmax(&mq_table, write, buffer,
-                                       lenp, ppos);
-}
-#else
-#define proc_mq_dointvec NULL
-#define proc_mq_dointvec_minmax NULL
-#endif
+#include <linux/stat.h>
+#include <linux/capability.h>
+#include <linux/slab.h>
 
 static int msg_max_limit_min = MIN_MSGMAX;
 static int msg_max_limit_max = HARD_MSGMAX;
@@ -55,14 +25,14 @@ static struct ctl_table mq_sysctls[] = {
                .data           = &init_ipc_ns.mq_queues_max,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_mq_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .procname       = "msg_max",
                .data           = &init_ipc_ns.mq_msg_max,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_mq_dointvec_minmax,
+               .proc_handler   = proc_dointvec_minmax,
                .extra1         = &msg_max_limit_min,
                .extra2         = &msg_max_limit_max,
        },
@@ -71,7 +41,7 @@ static struct ctl_table mq_sysctls[] = {
                .data           = &init_ipc_ns.mq_msgsize_max,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_mq_dointvec_minmax,
+               .proc_handler   = proc_dointvec_minmax,
                .extra1         = &msg_maxsize_limit_min,
                .extra2         = &msg_maxsize_limit_max,
        },
@@ -80,7 +50,7 @@ static struct ctl_table mq_sysctls[] = {
                .data           = &init_ipc_ns.mq_msg_default,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_mq_dointvec_minmax,
+               .proc_handler   = proc_dointvec_minmax,
                .extra1         = &msg_max_limit_min,
                .extra2         = &msg_max_limit_max,
        },
@@ -89,32 +59,73 @@ static struct ctl_table mq_sysctls[] = {
                .data           = &init_ipc_ns.mq_msgsize_default,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_mq_dointvec_minmax,
+               .proc_handler   = proc_dointvec_minmax,
                .extra1         = &msg_maxsize_limit_min,
                .extra2         = &msg_maxsize_limit_max,
        },
        {}
 };
 
-static struct ctl_table mq_sysctl_dir[] = {
-       {
-               .procname       = "mqueue",
-               .mode           = 0555,
-               .child          = mq_sysctls,
-       },
-       {}
-};
+static struct ctl_table_set *set_lookup(struct ctl_table_root *root)
+{
+       return &current->nsproxy->ipc_ns->mq_set;
+}
 
-static struct ctl_table mq_sysctl_root[] = {
-       {
-               .procname       = "fs",
-               .mode           = 0555,
-               .child          = mq_sysctl_dir,
-       },
-       {}
+static int set_is_seen(struct ctl_table_set *set)
+{
+       return &current->nsproxy->ipc_ns->mq_set == set;
+}
+
+static struct ctl_table_root set_root = {
+       .lookup = set_lookup,
 };
 
-struct ctl_table_header *mq_register_sysctl_table(void)
+bool setup_mq_sysctls(struct ipc_namespace *ns)
 {
-       return register_sysctl_table(mq_sysctl_root);
+       struct ctl_table *tbl;
+
+       setup_sysctl_set(&ns->mq_set, &set_root, set_is_seen);
+
+       tbl = kmemdup(mq_sysctls, sizeof(mq_sysctls), GFP_KERNEL);
+       if (tbl) {
+               int i;
+
+               for (i = 0; i < ARRAY_SIZE(mq_sysctls); i++) {
+                       if (tbl[i].data == &init_ipc_ns.mq_queues_max)
+                               tbl[i].data = &ns->mq_queues_max;
+
+                       else if (tbl[i].data == &init_ipc_ns.mq_msg_max)
+                               tbl[i].data = &ns->mq_msg_max;
+
+                       else if (tbl[i].data == &init_ipc_ns.mq_msgsize_max)
+                               tbl[i].data = &ns->mq_msgsize_max;
+
+                       else if (tbl[i].data == &init_ipc_ns.mq_msg_default)
+                               tbl[i].data = &ns->mq_msg_default;
+
+                       else if (tbl[i].data == &init_ipc_ns.mq_msgsize_default)
+                               tbl[i].data = &ns->mq_msgsize_default;
+                       else
+                               tbl[i].data = NULL;
+               }
+
+               ns->mq_sysctls = __register_sysctl_table(&ns->mq_set, "fs/mqueue", tbl);
+       }
+       if (!ns->mq_sysctls) {
+               kfree(tbl);
+               retire_sysctl_set(&ns->mq_set);
+               return false;
+       }
+
+       return true;
+}
+
+void retire_mq_sysctls(struct ipc_namespace *ns)
+{
+       struct ctl_table *tbl;
+
+       tbl = ns->mq_sysctls->ctl_table_arg;
+       unregister_sysctl_table(ns->mq_sysctls);
+       retire_sysctl_set(&ns->mq_set);
+       kfree(tbl);
 }