docs/sysfs: Specify ABI documentation requirements
[sfrench/cifs-2.6.git] / ipc / mqueue.c
index 14fb6d67e6a3efc339dd8aee3b7b8a5e57245c51..ed049ea568f45ee6026941b5d8335853c33efcd8 100644 (file)
@@ -113,72 +113,75 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
 {
        struct user_struct *u = current_user();
        struct inode *inode;
+       int ret = -ENOMEM;
 
        inode = new_inode(sb);
-       if (inode) {
-               inode->i_ino = get_next_ino();
-               inode->i_mode = mode;
-               inode->i_uid = current_fsuid();
-               inode->i_gid = current_fsgid();
-               inode->i_mtime = inode->i_ctime = inode->i_atime =
-                               CURRENT_TIME;
+       if (!inode)
+               goto err;
 
-               if (S_ISREG(mode)) {
-                       struct mqueue_inode_info *info;
-                       struct task_struct *p = current;
-                       unsigned long mq_bytes, mq_msg_tblsz;
-
-                       inode->i_fop = &mqueue_file_operations;
-                       inode->i_size = FILENT_SIZE;
-                       /* mqueue specific info */
-                       info = MQUEUE_I(inode);
-                       spin_lock_init(&info->lock);
-                       init_waitqueue_head(&info->wait_q);
-                       INIT_LIST_HEAD(&info->e_wait_q[0].list);
-                       INIT_LIST_HEAD(&info->e_wait_q[1].list);
-                       info->notify_owner = NULL;
-                       info->qsize = 0;
-                       info->user = NULL;      /* set when all is ok */
-                       memset(&info->attr, 0, sizeof(info->attr));
-                       info->attr.mq_maxmsg = ipc_ns->mq_msg_max;
-                       info->attr.mq_msgsize = ipc_ns->mq_msgsize_max;
-                       if (attr) {
-                               info->attr.mq_maxmsg = attr->mq_maxmsg;
-                               info->attr.mq_msgsize = attr->mq_msgsize;
-                       }
-                       mq_msg_tblsz = info->attr.mq_maxmsg * sizeof(struct msg_msg *);
-                       info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
-                       if (!info->messages)
-                               goto out_inode;
-
-                       mq_bytes = (mq_msg_tblsz +
-                               (info->attr.mq_maxmsg * info->attr.mq_msgsize));
-
-                       spin_lock(&mq_lock);
-                       if (u->mq_bytes + mq_bytes < u->mq_bytes ||
-                           u->mq_bytes + mq_bytes >
-                           task_rlimit(p, RLIMIT_MSGQUEUE)) {
-                               spin_unlock(&mq_lock);
-                               /* mqueue_evict_inode() releases info->messages */
-                               goto out_inode;
-                       }
-                       u->mq_bytes += mq_bytes;
-                       spin_unlock(&mq_lock);
+       inode->i_ino = get_next_ino();
+       inode->i_mode = mode;
+       inode->i_uid = current_fsuid();
+       inode->i_gid = current_fsgid();
+       inode->i_mtime = inode->i_ctime = inode->i_atime = CURRENT_TIME;
+
+       if (S_ISREG(mode)) {
+               struct mqueue_inode_info *info;
+               struct task_struct *p = current;
+               unsigned long mq_bytes, mq_msg_tblsz;
+
+               inode->i_fop = &mqueue_file_operations;
+               inode->i_size = FILENT_SIZE;
+               /* mqueue specific info */
+               info = MQUEUE_I(inode);
+               spin_lock_init(&info->lock);
+               init_waitqueue_head(&info->wait_q);
+               INIT_LIST_HEAD(&info->e_wait_q[0].list);
+               INIT_LIST_HEAD(&info->e_wait_q[1].list);
+               info->notify_owner = NULL;
+               info->qsize = 0;
+               info->user = NULL;      /* set when all is ok */
+               memset(&info->attr, 0, sizeof(info->attr));
+               info->attr.mq_maxmsg = ipc_ns->mq_msg_max;
+               info->attr.mq_msgsize = ipc_ns->mq_msgsize_max;
+               if (attr) {
+                       info->attr.mq_maxmsg = attr->mq_maxmsg;
+                       info->attr.mq_msgsize = attr->mq_msgsize;
+               }
+               mq_msg_tblsz = info->attr.mq_maxmsg * sizeof(struct msg_msg *);
+               info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
+               if (!info->messages)
+                       goto out_inode;
 
-                       /* all is ok */
-                       info->user = get_uid(u);
-               } else if (S_ISDIR(mode)) {
-                       inc_nlink(inode);
-                       /* Some things misbehave if size == 0 on a directory */
-                       inode->i_size = 2 * DIRENT_SIZE;
-                       inode->i_op = &mqueue_dir_inode_operations;
-                       inode->i_fop = &simple_dir_operations;
+               mq_bytes = (mq_msg_tblsz +
+                       (info->attr.mq_maxmsg * info->attr.mq_msgsize));
+
+               spin_lock(&mq_lock);
+               if (u->mq_bytes + mq_bytes < u->mq_bytes ||
+                   u->mq_bytes + mq_bytes > task_rlimit(p, RLIMIT_MSGQUEUE)) {
+                       spin_unlock(&mq_lock);
+                       /* mqueue_evict_inode() releases info->messages */
+                       ret = -EMFILE;
+                       goto out_inode;
                }
+               u->mq_bytes += mq_bytes;
+               spin_unlock(&mq_lock);
+
+               /* all is ok */
+               info->user = get_uid(u);
+       } else if (S_ISDIR(mode)) {
+               inc_nlink(inode);
+               /* Some things misbehave if size == 0 on a directory */
+               inode->i_size = 2 * DIRENT_SIZE;
+               inode->i_op = &mqueue_dir_inode_operations;
+               inode->i_fop = &simple_dir_operations;
        }
+
        return inode;
 out_inode:
        iput(inode);
-       return NULL;
+err:
+       return ERR_PTR(ret);
 }
 
 static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
@@ -194,8 +197,8 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
 
        inode = mqueue_get_inode(sb, ns, S_IFDIR | S_ISVTX | S_IRWXUGO,
                                NULL);
-       if (!inode) {
-               error = -ENOMEM;
+       if (IS_ERR(inode)) {
+               error = PTR_ERR(inode);
                goto out;
        }
 
@@ -315,8 +318,8 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry,
        spin_unlock(&mq_lock);
 
        inode = mqueue_get_inode(dir->i_sb, ipc_ns, mode, attr);
-       if (!inode) {
-               error = -ENOMEM;
+       if (IS_ERR(inode)) {
+               error = PTR_ERR(inode);
                spin_lock(&mq_lock);
                ipc_ns->mq_queues_count--;
                goto out_unlock;