Merge tag 's390-4.19-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[linux-2.6-microblaze.git] / ipc / msg.c
index 3b65453..883642c 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -38,6 +38,7 @@
 #include <linux/rwsem.h>
 #include <linux/nsproxy.h>
 #include <linux/ipc_namespace.h>
+#include <linux/rhashtable.h>
 
 #include <asm/current.h>
 #include <linux/uaccess.h>
@@ -162,7 +163,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params)
        /* ipc_addid() locks msq upon success. */
        retval = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
        if (retval < 0) {
-               call_rcu(&msq->q_perm.rcu, msg_rcu_free);
+               ipc_rcu_putref(&msq->q_perm, msg_rcu_free);
                return retval;
        }
 
@@ -385,7 +386,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
        down_write(&msg_ids(ns).rwsem);
        rcu_read_lock();
 
-       ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd,
+       ipcp = ipcctl_obtain_check(ns, &msg_ids(ns), msqid, cmd,
                                      &msqid64->msg_perm, msqid64->msg_qbytes);
        if (IS_ERR(ipcp)) {
                err = PTR_ERR(ipcp);
@@ -455,7 +456,7 @@ static int msgctl_info(struct ipc_namespace *ns, int msqid,
                         int cmd, struct msginfo *msginfo)
 {
        int err;
-       int max_id;
+       int max_idx;
 
        /*
         * We must not return kernel stack data.
@@ -482,16 +483,15 @@ static int msgctl_info(struct ipc_namespace *ns, int msqid,
                msginfo->msgpool = MSGPOOL;
                msginfo->msgtql = MSGTQL;
        }
-       max_id = ipc_get_maxid(&msg_ids(ns));
+       max_idx = ipc_get_maxidx(&msg_ids(ns));
        up_read(&msg_ids(ns).rwsem);
-       return (max_id < 0) ? 0 : max_id;
+       return (max_idx < 0) ? 0 : max_idx;
 }
 
 static int msgctl_stat(struct ipc_namespace *ns, int msqid,
                         int cmd, struct msqid64_ds *p)
 {
        struct msg_queue *msq;
-       int id = 0;
        int err;
 
        memset(p, 0, sizeof(*p));
@@ -503,7 +503,6 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
                        err = PTR_ERR(msq);
                        goto out_unlock;
                }
-               id = msq->q_perm.id;
        } else { /* IPC_STAT */
                msq = msq_obtain_object_check(ns, msqid);
                if (IS_ERR(msq)) {
@@ -548,10 +547,21 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
        p->msg_lspid  = pid_vnr(msq->q_lspid);
        p->msg_lrpid  = pid_vnr(msq->q_lrpid);
 
-       ipc_unlock_object(&msq->q_perm);
-       rcu_read_unlock();
-       return id;
+       if (cmd == IPC_STAT) {
+               /*
+                * As defined in SUS:
+                * Return 0 on success
+                */
+               err = 0;
+       } else {
+               /*
+                * MSG_STAT and MSG_STAT_ANY (both Linux specific)
+                * Return the full id, including the sequence number
+                */
+               err = msq->q_perm.id;
+       }
 
+       ipc_unlock_object(&msq->q_perm);
 out_unlock:
        rcu_read_unlock();
        return err;
@@ -1228,7 +1238,7 @@ COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
 }
 #endif
 
-int msg_init_ns(struct ipc_namespace *ns)
+void msg_init_ns(struct ipc_namespace *ns)
 {
        ns->msg_ctlmax = MSGMAX;
        ns->msg_ctlmnb = MSGMNB;
@@ -1236,7 +1246,7 @@ int msg_init_ns(struct ipc_namespace *ns)
 
        atomic_set(&ns->msg_bytes, 0);
        atomic_set(&ns->msg_hdrs, 0);
-       return ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
+       ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
 }
 
 #ifdef CONFIG_IPC_NS
@@ -1277,12 +1287,11 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
 }
 #endif
 
-int __init msg_init(void)
+void __init msg_init(void)
 {
-       const int err = msg_init_ns(&init_ipc_ns);
+       msg_init_ns(&init_ipc_ns);
 
        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);
-       return err;
 }