upgrade to fedora-2.6.12-1.1398.FC4 + vserver 2.0.rc7
[linux-2.6.git] / ipc / mqueue.c
index cb0cd3c..e30be56 100644 (file)
@@ -23,6 +23,9 @@
 #include <linux/skbuff.h>
 #include <linux/netlink.h>
 #include <linux/syscalls.h>
+#include <linux/signal.h>
+#include <linux/vs_context.h>
+#include <linux/vs_limit.h>
 #include <net/sock.h>
 #include "util.h"
 
@@ -146,17 +149,20 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
                        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) {
+                           p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur ||
+                           !vx_ipcmsg_avail(p->vx_info, mq_bytes)) {
                                spin_unlock(&mq_lock);
                                goto out_inode;
                        }
                        u->mq_bytes += mq_bytes;
+                       vx_ipcmsg_add(p->vx_info, u, mq_bytes);
                        spin_unlock(&mq_lock);
 
                        info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
                        if (!info->messages) {
                                spin_lock(&mq_lock);
                                u->mq_bytes -= mq_bytes;
+                               vx_ipcmsg_sub(p->vx_info, u, mq_bytes);
                                spin_unlock(&mq_lock);
                                goto out_inode;
                        }
@@ -254,10 +260,14 @@ static void mqueue_delete_inode(struct inode *inode)
                   (info->attr.mq_maxmsg * info->attr.mq_msgsize));
        user = info->user;
        if (user) {
+               struct vx_info *vxi = locate_vx_info(user->xid);
+
                spin_lock(&mq_lock);
                user->mq_bytes -= mq_bytes;
+               vx_ipcmsg_sub(vxi, user, mq_bytes);
                queues_count--;
                spin_unlock(&mq_lock);
+               put_vx_info(vxi);
                free_uid(user);
        }
 }
@@ -767,7 +777,7 @@ static inline void pipelined_send(struct mqueue_inode_info *info,
        list_del(&receiver->list);
        receiver->state = STATE_PENDING;
        wake_up_process(receiver->task);
-       wmb();
+       smp_wmb();
        receiver->state = STATE_READY;
 }
 
@@ -786,7 +796,7 @@ static inline void pipelined_receive(struct mqueue_inode_info *info)
        list_del(&sender->list);
        sender->state = STATE_PENDING;
        wake_up_process(sender->task);
-       wmb();
+       smp_wmb();
        sender->state = STATE_READY;
 }
 
@@ -976,8 +986,7 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
                             notification.sigev_notify != SIGEV_THREAD))
                        return -EINVAL;
                if (notification.sigev_notify == SIGEV_SIGNAL &&
-                       (notification.sigev_signo < 0 ||
-                        notification.sigev_signo > _NSIG)) {
+                       !valid_signal(notification.sigev_signo)) {
                        return -EINVAL;
                }
                if (notification.sigev_notify == SIGEV_THREAD) {