ipc/sem.c: remove code duplication
[sfrench/cifs-2.6.git] / ipc / msg.c
index 649853105a5d773d30fac9929327030cad118a67..c5d8e3749985be98b17c7bb1183dafb41332ea36 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
 #include <linux/ipc_namespace.h>
 
 #include <asm/current.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include "util.h"
 
-/*
- * one msg_receiver structure for each sleeping receiver:
- */
+/* one msg_receiver structure for each sleeping receiver */
 struct msg_receiver {
        struct list_head        r_list;
        struct task_struct      *r_tsk;
@@ -53,6 +51,12 @@ struct msg_receiver {
        long                    r_msgtype;
        long                    r_maxsize;
 
+       /*
+        * Mark r_msg volatile so that the compiler
+        * does not try to get smart and optimize
+        * it. We rely on this for the lockless
+        * receive algorithm.
+        */
        struct msg_msg          *volatile r_msg;
 };
 
@@ -70,75 +74,6 @@ struct msg_sender {
 
 #define msg_ids(ns)    ((ns)->ids[IPC_MSG_IDS])
 
-static void freeque(struct ipc_namespace *, struct kern_ipc_perm *);
-static int newque(struct ipc_namespace *, struct ipc_params *);
-#ifdef CONFIG_PROC_FS
-static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
-#endif
-
-/*
- * Scale msgmni with the available lowmem size: the memory dedicated to msg
- * queues should occupy at most 1/MSG_MEM_SCALE of lowmem.
- * Also take into account the number of nsproxies created so far.
- * This should be done staying within the (MSGMNI , IPCMNI/nr_ipc_ns) range.
- */
-void recompute_msgmni(struct ipc_namespace *ns)
-{
-       struct sysinfo i;
-       unsigned long allowed;
-       int nb_ns;
-
-       si_meminfo(&i);
-       allowed = (((i.totalram - i.totalhigh) / MSG_MEM_SCALE) * i.mem_unit)
-               / MSGMNB;
-       nb_ns = atomic_read(&nr_ipc_ns);
-       allowed /= nb_ns;
-
-       if (allowed < MSGMNI) {
-               ns->msg_ctlmni = MSGMNI;
-               return;
-       }
-
-       if (allowed > IPCMNI / nb_ns) {
-               ns->msg_ctlmni = IPCMNI / nb_ns;
-               return;
-       }
-
-       ns->msg_ctlmni = allowed;
-}
-
-void msg_init_ns(struct ipc_namespace *ns)
-{
-       ns->msg_ctlmax = MSGMAX;
-       ns->msg_ctlmnb = MSGMNB;
-
-       recompute_msgmni(ns);
-
-       atomic_set(&ns->msg_bytes, 0);
-       atomic_set(&ns->msg_hdrs, 0);
-       ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
-}
-
-#ifdef CONFIG_IPC_NS
-void msg_exit_ns(struct ipc_namespace *ns)
-{
-       free_ipcs(ns, &msg_ids(ns), freeque);
-       idr_destroy(&ns->ids[IPC_MSG_IDS].ipcs_idr);
-}
-#endif
-
-void __init msg_init(void)
-{
-       msg_init_ns(&init_ipc_ns);
-
-       printk(KERN_INFO "msgmni has been set to %d\n",
-               init_ipc_ns.msg_ctlmni);
-
-       ipc_init_proc_interface("sysvipc/msg",
-                               "       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n",
-                               IPC_MSG_IDS, sysvipc_msg_proc_show);
-}
-
 static inline struct msg_queue *msq_obtain_object(struct ipc_namespace *ns, int id)
 {
        struct kern_ipc_perm *ipcp = ipc_obtain_object(&msg_ids(ns), id);
@@ -227,7 +162,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params)
 static inline void ss_add(struct msg_queue *msq, struct msg_sender *mss)
 {
        mss->tsk = current;
-       current->state = TASK_INTERRUPTIBLE;
+       __set_current_state(TASK_INTERRUPTIBLE);
        list_add_tail(&mss->list, &msq->q_senders);
 }
 
@@ -306,15 +241,14 @@ static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
 SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg)
 {
        struct ipc_namespace *ns;
-       struct ipc_ops msg_ops;
+       static const struct ipc_ops msg_ops = {
+               .getnew = newque,
+               .associate = msg_security,
+       };
        struct ipc_params msg_params;
 
        ns = current->nsproxy->ipc_ns;
 
-       msg_ops.getnew = newque;
-       msg_ops.associate = msg_security;
-       msg_ops.more_checks = NULL;
-
        msg_params.key = key;
        msg_params.flg = msgflg;
 
@@ -612,23 +546,22 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
 
 static int testmsg(struct msg_msg *msg, long type, int mode)
 {
-       switch (mode)
-       {
-               case SEARCH_ANY:
-               case SEARCH_NUMBER:
+       switch (mode) {
+       case SEARCH_ANY:
+       case SEARCH_NUMBER:
+               return 1;
+       case SEARCH_LESSEQUAL:
+               if (msg->m_type <= type)
                        return 1;
-               case SEARCH_LESSEQUAL:
-                       if (msg->m_type <= type)
-                               return 1;
-                       break;
-               case SEARCH_EQUAL:
-                       if (msg->m_type == type)
-                               return 1;
-                       break;
-               case SEARCH_NOTEQUAL:
-                       if (msg->m_type != type)
-                               return 1;
-                       break;
+               break;
+       case SEARCH_EQUAL:
+               if (msg->m_type == type)
+                       return 1;
+               break;
+       case SEARCH_NOTEQUAL:
+               if (msg->m_type != type)
+                       return 1;
+               break;
        }
        return 0;
 }
@@ -978,7 +911,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
                else
                        msr_d.r_maxsize = bufsz;
                msr_d.r_msg = ERR_PTR(-EAGAIN);
-               current->state = TASK_INTERRUPTIBLE;
+               __set_current_state(TASK_INTERRUPTIBLE);
 
                ipc_unlock_object(&msq->q_perm);
                rcu_read_unlock();
@@ -1056,6 +989,57 @@ SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
        return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill);
 }
 
+/*
+ * Scale msgmni with the available lowmem size: the memory dedicated to msg
+ * queues should occupy at most 1/MSG_MEM_SCALE of lowmem.
+ * Also take into account the number of nsproxies created so far.
+ * This should be done staying within the (MSGMNI , IPCMNI/nr_ipc_ns) range.
+ */
+void recompute_msgmni(struct ipc_namespace *ns)
+{
+       struct sysinfo i;
+       unsigned long allowed;
+       int nb_ns;
+
+       si_meminfo(&i);
+       allowed = (((i.totalram - i.totalhigh) / MSG_MEM_SCALE) * i.mem_unit)
+               / MSGMNB;
+       nb_ns = atomic_read(&nr_ipc_ns);
+       allowed /= nb_ns;
+
+       if (allowed < MSGMNI) {
+               ns->msg_ctlmni = MSGMNI;
+               return;
+       }
+
+       if (allowed > IPCMNI / nb_ns) {
+               ns->msg_ctlmni = IPCMNI / nb_ns;
+               return;
+       }
+
+       ns->msg_ctlmni = allowed;
+}
+
+void msg_init_ns(struct ipc_namespace *ns)
+{
+       ns->msg_ctlmax = MSGMAX;
+       ns->msg_ctlmnb = MSGMNB;
+
+       recompute_msgmni(ns);
+
+       atomic_set(&ns->msg_bytes, 0);
+       atomic_set(&ns->msg_hdrs, 0);
+       ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
+}
+
+#ifdef CONFIG_IPC_NS
+void msg_exit_ns(struct ipc_namespace *ns)
+{
+       free_ipcs(ns, &msg_ids(ns), freeque);
+       idr_destroy(&ns->ids[IPC_MSG_IDS].ipcs_idr);
+}
+#endif
+
 #ifdef CONFIG_PROC_FS
 static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
 {
@@ -1080,3 +1064,15 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
                        msq->q_ctime);
 }
 #endif
+
+void __init msg_init(void)
+{
+       msg_init_ns(&init_ipc_ns);
+
+       printk(KERN_INFO "msgmni has been set to %d\n",
+               init_ipc_ns.msg_ctlmni);
+
+       ipc_init_proc_interface("sysvipc/msg",
+                               "       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n",
+                               IPC_MSG_IDS, sysvipc_msg_proc_show);
+}