ALSA: usb-audio: add support for Akai MPD16
[safe/jmp/linux-2.6] / ipc / msg.c
index 80375bf..9547cb7 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -23,7 +23,6 @@
  */
 
 #include <linux/capability.h>
-#include <linux/slab.h>
 #include <linux/msg.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
@@ -98,20 +97,15 @@ void recompute_msgmni(struct ipc_namespace *ns)
 
        if (allowed < MSGMNI) {
                ns->msg_ctlmni = MSGMNI;
-               goto out_callback;
+               return;
        }
 
        if (allowed > IPCMNI / nb_ns) {
                ns->msg_ctlmni = IPCMNI / nb_ns;
-               goto out_callback;
+               return;
        }
 
        ns->msg_ctlmni = allowed;
-
-out_callback:
-
-       printk(KERN_INFO "msgmni has been set to %d for ipc namespace %p\n",
-               ns->msg_ctlmni, ns);
 }
 
 void msg_init_ns(struct ipc_namespace *ns)
@@ -130,33 +124,23 @@ void msg_init_ns(struct ipc_namespace *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);
 }
 
 /*
- * This routine is called in the paths where the rw_mutex is held to protect
- * access to the idr tree.
- */
-static inline struct msg_queue *msg_lock_check_down(struct ipc_namespace *ns,
-                                               int id)
-{
-       struct kern_ipc_perm *ipcp = ipc_lock_check_down(&msg_ids(ns), id);
-
-       if (IS_ERR(ipcp))
-               return (struct msg_queue *)ipcp;
-
-       return container_of(ipcp, struct msg_queue, q_perm);
-}
-
-/*
  * msg_lock_(check_) routines are called in the paths where the rw_mutex
  * is not held.
  */
@@ -325,7 +309,7 @@ static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
        return security_msg_queue_associate(msq, msgflg);
 }
 
-asmlinkage long sys_msgget(key_t key, int msgflg)
+SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg)
 {
        struct ipc_namespace *ns;
        struct ipc_ops msg_ops;
@@ -361,19 +345,19 @@ copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version)
                out.msg_rtime           = in->msg_rtime;
                out.msg_ctime           = in->msg_ctime;
 
-               if (in->msg_cbytes > USHRT_MAX)
-                       out.msg_cbytes  = USHRT_MAX;
+               if (in->msg_cbytes > USHORT_MAX)
+                       out.msg_cbytes  = USHORT_MAX;
                else
                        out.msg_cbytes  = in->msg_cbytes;
                out.msg_lcbytes         = in->msg_cbytes;
 
-               if (in->msg_qnum > USHRT_MAX)
-                       out.msg_qnum    = USHRT_MAX;
+               if (in->msg_qnum > USHORT_MAX)
+                       out.msg_qnum    = USHORT_MAX;
                else
                        out.msg_qnum    = in->msg_qnum;
 
-               if (in->msg_qbytes > USHRT_MAX)
-                       out.msg_qbytes  = USHRT_MAX;
+               if (in->msg_qbytes > USHORT_MAX)
+                       out.msg_qbytes  = USHORT_MAX;
                else
                        out.msg_qbytes  = in->msg_qbytes;
                out.msg_lqbytes         = in->msg_qbytes;
@@ -428,7 +412,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
                       struct msqid_ds __user *buf, int version)
 {
        struct kern_ipc_perm *ipcp;
-       struct msqid64_ds msqid64;
+       struct msqid64_ds uninitialized_var(msqid64);
        struct msg_queue *msq;
        int err;
 
@@ -437,35 +421,12 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
                        return -EFAULT;
        }
 
-       down_write(&msg_ids(ns).rw_mutex);
-       msq = msg_lock_check_down(ns, msqid);
-       if (IS_ERR(msq)) {
-               err = PTR_ERR(msq);
-               goto out_up;
-       }
-
-       ipcp = &msq->q_perm;
-
-       err = audit_ipc_obj(ipcp);
-       if (err)
-               goto out_unlock;
-
-       if (cmd == IPC_SET) {
-               err = audit_ipc_set_perm(msqid64.msg_qbytes,
-                                        msqid64.msg_perm.uid,
-                                        msqid64.msg_perm.gid,
-                                        msqid64.msg_perm.mode);
-               if (err)
-                       goto out_unlock;
-       }
+       ipcp = ipcctl_pre_down(&msg_ids(ns), msqid, cmd,
+                              &msqid64.msg_perm, msqid64.msg_qbytes);
+       if (IS_ERR(ipcp))
+               return PTR_ERR(ipcp);
 
-       if (current->euid != ipcp->cuid &&
-           current->euid != ipcp->uid &&
-           !capable(CAP_SYS_ADMIN)) {
-               /* We _could_ check for CAP_CHOWN above, but we don't */
-               err = -EPERM;
-               goto out_unlock;
-       }
+       msq = container_of(ipcp, struct msg_queue, q_perm);
 
        err = security_msg_queue_msgctl(msq, cmd);
        if (err)
@@ -484,10 +445,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
 
                msq->q_qbytes = msqid64.msg_qbytes;
 
-               ipcp->uid = msqid64.msg_perm.uid;
-               ipcp->gid = msqid64.msg_perm.gid;
-               ipcp->mode = (ipcp->mode & ~S_IRWXUGO) |
-                            (S_IRWXUGO & msqid64.msg_perm.mode);
+               ipc_update_perm(&msqid64.msg_perm, ipcp);
                msq->q_ctime = get_seconds();
                /* sleeping receivers might be excluded by
                 * stricter permissions.
@@ -508,7 +466,7 @@ out_up:
        return err;
 }
 
-asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
+SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
 {
        struct msg_queue *msq;
        int err, version;
@@ -765,8 +723,8 @@ out_free:
        return err;
 }
 
-asmlinkage long
-sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg)
+SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
+               int, msgflg)
 {
        long mtype;
 
@@ -946,8 +904,8 @@ out_unlock:
        return msgsz;
 }
 
-asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
-                          long msgtyp, int msgflg)
+SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
+               long, msgtyp, int, msgflg)
 {
        long err, mtype;