ALSA: es1968: Clear interrupts before enabling them
[safe/jmp/linux-2.6] / ipc / mqueue.c
index 3660c33..722b013 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/nsproxy.h>
 #include <linux/pid.h>
 #include <linux/ipc_namespace.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 #include "util.h"
@@ -155,7 +156,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
                        spin_lock(&mq_lock);
                        if (u->mq_bytes + mq_bytes < u->mq_bytes ||
                            u->mq_bytes + mq_bytes >
-                           p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
+                           task_rlimit(p, RLIMIT_MSGQUEUE)) {
                                spin_unlock(&mq_lock);
                                kfree(info->messages);
                                goto out_inode;
@@ -184,7 +185,7 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
 {
        struct inode *inode;
        struct ipc_namespace *ns = data;
-       int error = 0;
+       int error;
 
        sb->s_blocksize = PAGE_CACHE_SIZE;
        sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -202,7 +203,9 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
        if (!sb->s_root) {
                iput(inode);
                error = -ENOMEM;
+               goto out;
        }
+       error = 0;
 
 out:
        return error;
@@ -261,8 +264,9 @@ static void mqueue_delete_inode(struct inode *inode)
 
        clear_inode(inode);
 
-       mq_bytes = (info->attr.mq_maxmsg * sizeof(struct msg_msg *) +
-                  (info->attr.mq_maxmsg * info->attr.mq_msgsize));
+       /* Total amount of bytes accounted for the mqueue */
+       mq_bytes = info->attr.mq_maxmsg * (sizeof(struct msg_msg *)
+           + info->attr.mq_msgsize);
        user = info->user;
        if (user) {
                spin_lock(&mq_lock);
@@ -601,8 +605,8 @@ static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr)
        /* check for overflow */
        if (attr->mq_msgsize > ULONG_MAX/attr->mq_maxmsg)
                return 0;
-       if ((unsigned long)(attr->mq_maxmsg * attr->mq_msgsize) +
-           (attr->mq_maxmsg * sizeof (struct msg_msg *)) <
+       if ((unsigned long)(attr->mq_maxmsg * (attr->mq_msgsize
+           + sizeof (struct msg_msg *))) <
            (unsigned long)(attr->mq_maxmsg * attr->mq_msgsize))
                return 0;
        return 1;
@@ -620,9 +624,10 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir,
        int ret;
 
        if (attr) {
-               ret = -EINVAL;
-               if (!mq_attr_ok(ipc_ns, attr))
+               if (!mq_attr_ok(ipc_ns, attr)) {
+                       ret = -EINVAL;
                        goto out;
+               }
                /* store for use during create */
                dentry->d_fsdata = attr;
        }
@@ -656,24 +661,28 @@ out:
 static struct file *do_open(struct ipc_namespace *ipc_ns,
                                struct dentry *dentry, int oflag)
 {
+       int ret;
        const struct cred *cred = current_cred();
 
        static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
                                                  MAY_READ | MAY_WRITE };
 
        if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
-               dput(dentry);
-               mntput(ipc_ns->mq_mnt);
-               return ERR_PTR(-EINVAL);
+               ret = -EINVAL;
+               goto err;
        }
 
        if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) {
-               dput(dentry);
-               mntput(ipc_ns->mq_mnt);
-               return ERR_PTR(-EACCES);
+               ret = -EACCES;
+               goto err;
        }
 
        return dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred);
+
+err:
+       dput(dentry);
+       mntput(ipc_ns->mq_mnt);
+       return ERR_PTR(ret);
 }
 
 SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
@@ -709,9 +718,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
        if (oflag & O_CREAT) {
                if (dentry->d_inode) {  /* entry already exists */
                        audit_inode(name, dentry);
-                       error = -EEXIST;
-                       if (oflag & O_EXCL)
+                       if (oflag & O_EXCL) {
+                               error = -EEXIST;
                                goto out;
+                       }
                        filp = do_open(ipc_ns, dentry, oflag);
                } else {
                        filp = do_create(ipc_ns, ipc_ns->mq_mnt->mnt_root,
@@ -719,9 +729,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
                                                u_attr ? &attr : NULL);
                }
        } else {
-               error = -ENOENT;
-               if (!dentry->d_inode)
+               if (!dentry->d_inode) {
+                       error = -ENOENT;
                        goto out;
+               }
                audit_inode(name, dentry);
                filp = do_open(ipc_ns, dentry, oflag);
        }
@@ -868,19 +879,24 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
        audit_mq_sendrecv(mqdes, msg_len, msg_prio, p);
        timeout = prepare_timeout(p);
 
-       ret = -EBADF;
        filp = fget(mqdes);
-       if (unlikely(!filp))
+       if (unlikely(!filp)) {
+               ret = -EBADF;
                goto out;
+       }
 
        inode = filp->f_path.dentry->d_inode;
-       if (unlikely(filp->f_op != &mqueue_file_operations))
+       if (unlikely(filp->f_op != &mqueue_file_operations)) {
+               ret = -EBADF;
                goto out_fput;
+       }
        info = MQUEUE_I(inode);
        audit_inode(NULL, filp->f_path.dentry);
 
-       if (unlikely(!(filp->f_mode & FMODE_WRITE)))
+       if (unlikely(!(filp->f_mode & FMODE_WRITE))) {
+               ret = -EBADF;
                goto out_fput;
+       }
 
        if (unlikely(msg_len > info->attr.mq_msgsize)) {
                ret = -EMSGSIZE;
@@ -957,19 +973,24 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
        audit_mq_sendrecv(mqdes, msg_len, 0, p);
        timeout = prepare_timeout(p);
 
-       ret = -EBADF;
        filp = fget(mqdes);
-       if (unlikely(!filp))
+       if (unlikely(!filp)) {
+               ret = -EBADF;
                goto out;
+       }
 
        inode = filp->f_path.dentry->d_inode;
-       if (unlikely(filp->f_op != &mqueue_file_operations))
+       if (unlikely(filp->f_op != &mqueue_file_operations)) {
+               ret = -EBADF;
                goto out_fput;
+       }
        info = MQUEUE_I(inode);
        audit_inode(NULL, filp->f_path.dentry);
 
-       if (unlikely(!(filp->f_mode & FMODE_READ)))
+       if (unlikely(!(filp->f_mode & FMODE_READ))) {
+               ret = -EBADF;
                goto out_fput;
+       }
 
        /* checks if buffer is big enough */
        if (unlikely(msg_len < info->attr.mq_msgsize)) {
@@ -1059,13 +1080,14 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
 
                        /* create the notify skb */
                        nc = alloc_skb(NOTIFY_COOKIE_LEN, GFP_KERNEL);
-                       ret = -ENOMEM;
-                       if (!nc)
+                       if (!nc) {
+                               ret = -ENOMEM;
                                goto out;
-                       ret = -EFAULT;
+                       }
                        if (copy_from_user(nc->data,
                                        notification.sigev_value.sival_ptr,
                                        NOTIFY_COOKIE_LEN)) {
+                               ret = -EFAULT;
                                goto out;
                        }
 
@@ -1074,9 +1096,10 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
                        /* and attach it to the socket */
 retry:
                        filp = fget(notification.sigev_signo);
-                       ret = -EBADF;
-                       if (!filp)
+                       if (!filp) {
+                               ret = -EBADF;
                                goto out;
+                       }
                        sock = netlink_getsockbyfilp(filp);
                        fput(filp);
                        if (IS_ERR(sock)) {
@@ -1088,7 +1111,7 @@ retry:
                        timeo = MAX_SCHEDULE_TIMEOUT;
                        ret = netlink_attachskb(sock, nc, &timeo, NULL);
                        if (ret == 1)
-                               goto retry;
+                               goto retry;
                        if (ret) {
                                sock = NULL;
                                nc = NULL;
@@ -1097,14 +1120,17 @@ retry:
                }
        }
 
-       ret = -EBADF;
        filp = fget(mqdes);
-       if (!filp)
+       if (!filp) {
+               ret = -EBADF;
                goto out;
+       }
 
        inode = filp->f_path.dentry->d_inode;
-       if (unlikely(filp->f_op != &mqueue_file_operations))
+       if (unlikely(filp->f_op != &mqueue_file_operations)) {
+               ret = -EBADF;
                goto out_fput;
+       }
        info = MQUEUE_I(inode);
 
        ret = 0;
@@ -1167,14 +1193,17 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
                        return -EINVAL;
        }
 
-       ret = -EBADF;
        filp = fget(mqdes);
-       if (!filp)
+       if (!filp) {
+               ret = -EBADF;
                goto out;
+       }
 
        inode = filp->f_path.dentry->d_inode;
-       if (unlikely(filp->f_op != &mqueue_file_operations))
+       if (unlikely(filp->f_op != &mqueue_file_operations)) {
+               ret = -EBADF;
                goto out_fput;
+       }
        info = MQUEUE_I(inode);
 
        spin_lock(&info->lock);
@@ -1268,7 +1297,7 @@ static int __init init_mqueue_fs(void)
        if (mqueue_inode_cachep == NULL)
                return -ENOMEM;
 
-       /* ignore failues - they are not fatal */
+       /* ignore failures - they are not fatal */
        mq_sysctl_table = mq_register_sysctl_table();
 
        error = register_filesystem(&mqueue_fs_type);