patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / ipc / mqueue.c
index f7acbb5..40a8d41 100644 (file)
@@ -97,7 +97,8 @@ static inline struct mqueue_inode_info *MQUEUE_I(struct inode *inode)
        return container_of(inode, struct mqueue_inode_info, vfs_inode);
 }
 
-static struct inode *mqueue_get_inode(struct super_block *sb, int mode)
+static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
+                                                       struct mq_attr *attr)
 {
        struct inode *inode;
 
@@ -127,7 +128,11 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode)
                        memset(&info->attr, 0, sizeof(info->attr));
                        info->attr.mq_maxmsg = DFLT_MSGMAX;
                        info->attr.mq_msgsize = DFLT_MSGSIZEMAX;
-                       info->messages = kmalloc(DFLT_MSGMAX * sizeof(struct msg_msg *), GFP_KERNEL);
+                       if (attr) {
+                               info->attr.mq_maxmsg = attr->mq_maxmsg;
+                               info->attr.mq_msgsize = attr->mq_msgsize;
+                       }
+                       info->messages = kmalloc(info->attr.mq_maxmsg * sizeof(struct msg_msg *), GFP_KERNEL);
                        if (!info->messages) {
                                make_bad_inode(inode);
                                iput(inode);
@@ -153,7 +158,7 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_magic = MQUEUE_MAGIC;
        sb->s_op = &mqueue_super_ops;
 
-       inode = mqueue_get_inode(sb, S_IFDIR | S_ISVTX | S_IRWXUGO);
+       inode = mqueue_get_inode(sb, S_IFDIR | S_ISVTX | S_IRWXUGO, NULL);
        if (!inode)
                return -ENOMEM;
 
@@ -226,6 +231,7 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry,
                                int mode, struct nameidata *nd)
 {
        struct inode *inode;
+       struct mq_attr *attr = dentry->d_fsdata;
        int error;
 
        spin_lock(&mq_lock);
@@ -236,7 +242,7 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry,
        queues_count++;
        spin_unlock(&mq_lock);
 
-       inode = mqueue_get_inode(dir->i_sb, mode);
+       inode = mqueue_get_inode(dir->i_sb, mode, attr);
        if (!inode) {
                error = -ENOMEM;
                spin_lock(&mq_lock);
@@ -535,9 +541,6 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
                        int oflag, mode_t mode, struct mq_attr __user *u_attr)
 {
        struct file *filp;
-       struct inode *inode;
-       struct mqueue_inode_info *info;
-       struct msg_msg **msgs = NULL;
        struct mq_attr attr;
        int ret;
 
@@ -555,28 +558,14 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
                                        attr.mq_msgsize > msgsize_max)
                                return ERR_PTR(-EINVAL);
                }
-               msgs = kmalloc(attr.mq_maxmsg * sizeof(*msgs), GFP_KERNEL);
-               if (!msgs)
-                       return ERR_PTR(-ENOMEM);
-       } else {
-               msgs = NULL;
+               /* store for use during create */
+               dentry->d_fsdata = &attr;
        }
 
        ret = vfs_create(dir->d_inode, dentry, mode, NULL);
-       if (ret) {
-               kfree(msgs);
+       dentry->d_fsdata = NULL;
+       if (ret)
                return ERR_PTR(ret);
-       }
-
-       inode = dentry->d_inode;
-       info = MQUEUE_I(inode);
-
-       if (msgs) {
-               info->attr.mq_maxmsg = attr.mq_maxmsg;
-               info->attr.mq_msgsize = attr.mq_msgsize;
-               kfree(info->messages);
-               info->messages = msgs;
-       }
 
        filp = dentry_open(dentry, mqueue_mnt, oflag);
        if (!IS_ERR(filp))
@@ -791,7 +780,7 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
 
        /* First try to allocate memory, before doing anything with
         * existing queues. */
-       msg_ptr = load_msg((void *)u_msg_ptr, msg_len);
+       msg_ptr = load_msg(u_msg_ptr, msg_len);
        if (unlikely(IS_ERR(msg_ptr))) {
                ret = PTR_ERR(msg_ptr);
                goto out_fput;