aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/mqueue.c124
-rw-r--r--ipc/msgutil.c22
-rw-r--r--ipc/namespace.c2
-rw-r--r--ipc/util.c9
-rw-r--r--ipc/util.h16
5 files changed, 108 insertions, 65 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 916785363f0f..a3673a09069a 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -31,6 +31,7 @@
31#include <linux/mutex.h> 31#include <linux/mutex.h>
32#include <linux/nsproxy.h> 32#include <linux/nsproxy.h>
33#include <linux/pid.h> 33#include <linux/pid.h>
34#include <linux/ipc_namespace.h>
34 35
35#include <net/sock.h> 36#include <net/sock.h>
36#include "util.h" 37#include "util.h"
@@ -46,12 +47,6 @@
46#define STATE_PENDING 1 47#define STATE_PENDING 1
47#define STATE_READY 2 48#define STATE_READY 2
48 49
49/* default values */
50#define DFLT_QUEUESMAX 256 /* max number of message queues */
51#define DFLT_MSGMAX 10 /* max number of messages in each queue */
52#define HARD_MSGMAX (131072/sizeof(void*))
53#define DFLT_MSGSIZEMAX 8192 /* max message size */
54
55/* 50/*
56 * Define the ranges various user-specified maximum values can 51 * Define the ranges various user-specified maximum values can
57 * be set to. 52 * be set to.
@@ -95,12 +90,6 @@ static void remove_notification(struct mqueue_inode_info *info);
95 90
96static spinlock_t mq_lock; 91static spinlock_t mq_lock;
97static struct kmem_cache *mqueue_inode_cachep; 92static struct kmem_cache *mqueue_inode_cachep;
98static struct vfsmount *mqueue_mnt;
99
100static unsigned int queues_count;
101static unsigned int queues_max = DFLT_QUEUESMAX;
102static unsigned int msg_max = DFLT_MSGMAX;
103static unsigned int msgsize_max = DFLT_MSGSIZEMAX;
104 93
105static struct ctl_table_header * mq_sysctl_table; 94static struct ctl_table_header * mq_sysctl_table;
106 95
@@ -109,11 +98,27 @@ static inline struct mqueue_inode_info *MQUEUE_I(struct inode *inode)
109 return container_of(inode, struct mqueue_inode_info, vfs_inode); 98 return container_of(inode, struct mqueue_inode_info, vfs_inode);
110} 99}
111 100
101void mq_init_ns(struct ipc_namespace *ns)
102{
103 ns->mq_queues_count = 0;
104 ns->mq_queues_max = DFLT_QUEUESMAX;
105 ns->mq_msg_max = DFLT_MSGMAX;
106 ns->mq_msgsize_max = DFLT_MSGSIZEMAX;
107 ns->mq_mnt = mntget(init_ipc_ns.mq_mnt);
108}
109
110void mq_exit_ns(struct ipc_namespace *ns)
111{
112 /* will need to clear out ns->mq_mnt->mnt_sb->s_fs_info here */
113 mntput(ns->mq_mnt);
114}
115
112static struct inode *mqueue_get_inode(struct super_block *sb, int mode, 116static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
113 struct mq_attr *attr) 117 struct mq_attr *attr)
114{ 118{
115 struct user_struct *u = current_user(); 119 struct user_struct *u = current_user();
116 struct inode *inode; 120 struct inode *inode;
121 struct ipc_namespace *ipc_ns = &init_ipc_ns;
117 122
118 inode = new_inode(sb); 123 inode = new_inode(sb);
119 if (inode) { 124 if (inode) {
@@ -141,8 +146,8 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
141 info->qsize = 0; 146 info->qsize = 0;
142 info->user = NULL; /* set when all is ok */ 147 info->user = NULL; /* set when all is ok */
143 memset(&info->attr, 0, sizeof(info->attr)); 148 memset(&info->attr, 0, sizeof(info->attr));
144 info->attr.mq_maxmsg = msg_max; 149 info->attr.mq_maxmsg = ipc_ns->mq_msg_max;
145 info->attr.mq_msgsize = msgsize_max; 150 info->attr.mq_msgsize = ipc_ns->mq_msgsize_max;
146 if (attr) { 151 if (attr) {
147 info->attr.mq_maxmsg = attr->mq_maxmsg; 152 info->attr.mq_maxmsg = attr->mq_maxmsg;
148 info->attr.mq_msgsize = attr->mq_msgsize; 153 info->attr.mq_msgsize = attr->mq_msgsize;
@@ -242,6 +247,7 @@ static void mqueue_delete_inode(struct inode *inode)
242 struct user_struct *user; 247 struct user_struct *user;
243 unsigned long mq_bytes; 248 unsigned long mq_bytes;
244 int i; 249 int i;
250 struct ipc_namespace *ipc_ns = &init_ipc_ns;
245 251
246 if (S_ISDIR(inode->i_mode)) { 252 if (S_ISDIR(inode->i_mode)) {
247 clear_inode(inode); 253 clear_inode(inode);
@@ -262,7 +268,7 @@ static void mqueue_delete_inode(struct inode *inode)
262 if (user) { 268 if (user) {
263 spin_lock(&mq_lock); 269 spin_lock(&mq_lock);
264 user->mq_bytes -= mq_bytes; 270 user->mq_bytes -= mq_bytes;
265 queues_count--; 271 ipc_ns->mq_queues_count--;
266 spin_unlock(&mq_lock); 272 spin_unlock(&mq_lock);
267 free_uid(user); 273 free_uid(user);
268 } 274 }
@@ -274,21 +280,23 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry,
274 struct inode *inode; 280 struct inode *inode;
275 struct mq_attr *attr = dentry->d_fsdata; 281 struct mq_attr *attr = dentry->d_fsdata;
276 int error; 282 int error;
283 struct ipc_namespace *ipc_ns = &init_ipc_ns;
277 284
278 spin_lock(&mq_lock); 285 spin_lock(&mq_lock);
279 if (queues_count >= queues_max && !capable(CAP_SYS_RESOURCE)) { 286 if (ipc_ns->mq_queues_count >= ipc_ns->mq_queues_max &&
287 !capable(CAP_SYS_RESOURCE)) {
280 error = -ENOSPC; 288 error = -ENOSPC;
281 goto out_lock; 289 goto out_unlock;
282 } 290 }
283 queues_count++; 291 ipc_ns->mq_queues_count++;
284 spin_unlock(&mq_lock); 292 spin_unlock(&mq_lock);
285 293
286 inode = mqueue_get_inode(dir->i_sb, mode, attr); 294 inode = mqueue_get_inode(dir->i_sb, mode, attr);
287 if (!inode) { 295 if (!inode) {
288 error = -ENOMEM; 296 error = -ENOMEM;
289 spin_lock(&mq_lock); 297 spin_lock(&mq_lock);
290 queues_count--; 298 ipc_ns->mq_queues_count--;
291 goto out_lock; 299 goto out_unlock;
292 } 300 }
293 301
294 dir->i_size += DIRENT_SIZE; 302 dir->i_size += DIRENT_SIZE;
@@ -297,7 +305,7 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry,
297 d_instantiate(dentry, inode); 305 d_instantiate(dentry, inode);
298 dget(dentry); 306 dget(dentry);
299 return 0; 307 return 0;
300out_lock: 308out_unlock:
301 spin_unlock(&mq_lock); 309 spin_unlock(&mq_lock);
302 return error; 310 return error;
303} 311}
@@ -562,7 +570,7 @@ static void remove_notification(struct mqueue_inode_info *info)
562 info->notify_owner = NULL; 570 info->notify_owner = NULL;
563} 571}
564 572
565static int mq_attr_ok(struct mq_attr *attr) 573static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr)
566{ 574{
567 if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0) 575 if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0)
568 return 0; 576 return 0;
@@ -570,8 +578,8 @@ static int mq_attr_ok(struct mq_attr *attr)
570 if (attr->mq_maxmsg > HARD_MSGMAX) 578 if (attr->mq_maxmsg > HARD_MSGMAX)
571 return 0; 579 return 0;
572 } else { 580 } else {
573 if (attr->mq_maxmsg > msg_max || 581 if (attr->mq_maxmsg > ipc_ns->mq_msg_max ||
574 attr->mq_msgsize > msgsize_max) 582 attr->mq_msgsize > ipc_ns->mq_msgsize_max)
575 return 0; 583 return 0;
576 } 584 }
577 /* check for overflow */ 585 /* check for overflow */
@@ -587,8 +595,9 @@ static int mq_attr_ok(struct mq_attr *attr)
587/* 595/*
588 * Invoked when creating a new queue via sys_mq_open 596 * Invoked when creating a new queue via sys_mq_open
589 */ 597 */
590static struct file *do_create(struct dentry *dir, struct dentry *dentry, 598static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir,
591 int oflag, mode_t mode, struct mq_attr *attr) 599 struct dentry *dentry, int oflag, mode_t mode,
600 struct mq_attr *attr)
592{ 601{
593 const struct cred *cred = current_cred(); 602 const struct cred *cred = current_cred();
594 struct file *result; 603 struct file *result;
@@ -596,14 +605,14 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
596 605
597 if (attr) { 606 if (attr) {
598 ret = -EINVAL; 607 ret = -EINVAL;
599 if (!mq_attr_ok(attr)) 608 if (!mq_attr_ok(ipc_ns, attr))
600 goto out; 609 goto out;
601 /* store for use during create */ 610 /* store for use during create */
602 dentry->d_fsdata = attr; 611 dentry->d_fsdata = attr;
603 } 612 }
604 613
605 mode &= ~current_umask(); 614 mode &= ~current_umask();
606 ret = mnt_want_write(mqueue_mnt); 615 ret = mnt_want_write(ipc_ns->mq_mnt);
607 if (ret) 616 if (ret)
608 goto out; 617 goto out;
609 ret = vfs_create(dir->d_inode, dentry, mode, NULL); 618 ret = vfs_create(dir->d_inode, dentry, mode, NULL);
@@ -611,24 +620,25 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
611 if (ret) 620 if (ret)
612 goto out_drop_write; 621 goto out_drop_write;
613 622
614 result = dentry_open(dentry, mqueue_mnt, oflag, cred); 623 result = dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred);
615 /* 624 /*
616 * dentry_open() took a persistent mnt_want_write(), 625 * dentry_open() took a persistent mnt_want_write(),
617 * so we can now drop this one. 626 * so we can now drop this one.
618 */ 627 */
619 mnt_drop_write(mqueue_mnt); 628 mnt_drop_write(ipc_ns->mq_mnt);
620 return result; 629 return result;
621 630
622out_drop_write: 631out_drop_write:
623 mnt_drop_write(mqueue_mnt); 632 mnt_drop_write(ipc_ns->mq_mnt);
624out: 633out:
625 dput(dentry); 634 dput(dentry);
626 mntput(mqueue_mnt); 635 mntput(ipc_ns->mq_mnt);
627 return ERR_PTR(ret); 636 return ERR_PTR(ret);
628} 637}
629 638
630/* Opens existing queue */ 639/* Opens existing queue */
631static struct file *do_open(struct dentry *dentry, int oflag) 640static struct file *do_open(struct ipc_namespace *ipc_ns,
641 struct dentry *dentry, int oflag)
632{ 642{
633 const struct cred *cred = current_cred(); 643 const struct cred *cred = current_cred();
634 644
@@ -637,17 +647,17 @@ static struct file *do_open(struct dentry *dentry, int oflag)
637 647
638 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { 648 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
639 dput(dentry); 649 dput(dentry);
640 mntput(mqueue_mnt); 650 mntput(ipc_ns->mq_mnt);
641 return ERR_PTR(-EINVAL); 651 return ERR_PTR(-EINVAL);
642 } 652 }
643 653
644 if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) { 654 if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) {
645 dput(dentry); 655 dput(dentry);
646 mntput(mqueue_mnt); 656 mntput(ipc_ns->mq_mnt);
647 return ERR_PTR(-EACCES); 657 return ERR_PTR(-EACCES);
648 } 658 }
649 659
650 return dentry_open(dentry, mqueue_mnt, oflag, cred); 660 return dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred);
651} 661}
652 662
653SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, 663SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
@@ -658,6 +668,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
658 char *name; 668 char *name;
659 struct mq_attr attr; 669 struct mq_attr attr;
660 int fd, error; 670 int fd, error;
671 struct ipc_namespace *ipc_ns = &init_ipc_ns;
661 672
662 if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr))) 673 if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
663 return -EFAULT; 674 return -EFAULT;
@@ -671,13 +682,13 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
671 if (fd < 0) 682 if (fd < 0)
672 goto out_putname; 683 goto out_putname;
673 684
674 mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex); 685 mutex_lock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
675 dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); 686 dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name));
676 if (IS_ERR(dentry)) { 687 if (IS_ERR(dentry)) {
677 error = PTR_ERR(dentry); 688 error = PTR_ERR(dentry);
678 goto out_err; 689 goto out_err;
679 } 690 }
680 mntget(mqueue_mnt); 691 mntget(ipc_ns->mq_mnt);
681 692
682 if (oflag & O_CREAT) { 693 if (oflag & O_CREAT) {
683 if (dentry->d_inode) { /* entry already exists */ 694 if (dentry->d_inode) { /* entry already exists */
@@ -685,10 +696,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
685 error = -EEXIST; 696 error = -EEXIST;
686 if (oflag & O_EXCL) 697 if (oflag & O_EXCL)
687 goto out; 698 goto out;
688 filp = do_open(dentry, oflag); 699 filp = do_open(ipc_ns, dentry, oflag);
689 } else { 700 } else {
690 filp = do_create(mqueue_mnt->mnt_root, dentry, 701 filp = do_create(ipc_ns, ipc_ns->mq_mnt->mnt_root,
691 oflag, mode, 702 dentry, oflag, mode,
692 u_attr ? &attr : NULL); 703 u_attr ? &attr : NULL);
693 } 704 }
694 } else { 705 } else {
@@ -696,7 +707,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
696 if (!dentry->d_inode) 707 if (!dentry->d_inode)
697 goto out; 708 goto out;
698 audit_inode(name, dentry); 709 audit_inode(name, dentry);
699 filp = do_open(dentry, oflag); 710 filp = do_open(ipc_ns, dentry, oflag);
700 } 711 }
701 712
702 if (IS_ERR(filp)) { 713 if (IS_ERR(filp)) {
@@ -709,13 +720,13 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
709 720
710out: 721out:
711 dput(dentry); 722 dput(dentry);
712 mntput(mqueue_mnt); 723 mntput(ipc_ns->mq_mnt);
713out_putfd: 724out_putfd:
714 put_unused_fd(fd); 725 put_unused_fd(fd);
715out_err: 726out_err:
716 fd = error; 727 fd = error;
717out_upsem: 728out_upsem:
718 mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex); 729 mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
719out_putname: 730out_putname:
720 putname(name); 731 putname(name);
721 return fd; 732 return fd;
@@ -727,14 +738,15 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
727 char *name; 738 char *name;
728 struct dentry *dentry; 739 struct dentry *dentry;
729 struct inode *inode = NULL; 740 struct inode *inode = NULL;
741 struct ipc_namespace *ipc_ns = &init_ipc_ns;
730 742
731 name = getname(u_name); 743 name = getname(u_name);
732 if (IS_ERR(name)) 744 if (IS_ERR(name))
733 return PTR_ERR(name); 745 return PTR_ERR(name);
734 746
735 mutex_lock_nested(&mqueue_mnt->mnt_root->d_inode->i_mutex, 747 mutex_lock_nested(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex,
736 I_MUTEX_PARENT); 748 I_MUTEX_PARENT);
737 dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); 749 dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name));
738 if (IS_ERR(dentry)) { 750 if (IS_ERR(dentry)) {
739 err = PTR_ERR(dentry); 751 err = PTR_ERR(dentry);
740 goto out_unlock; 752 goto out_unlock;
@@ -748,16 +760,16 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
748 inode = dentry->d_inode; 760 inode = dentry->d_inode;
749 if (inode) 761 if (inode)
750 atomic_inc(&inode->i_count); 762 atomic_inc(&inode->i_count);
751 err = mnt_want_write(mqueue_mnt); 763 err = mnt_want_write(ipc_ns->mq_mnt);
752 if (err) 764 if (err)
753 goto out_err; 765 goto out_err;
754 err = vfs_unlink(dentry->d_parent->d_inode, dentry); 766 err = vfs_unlink(dentry->d_parent->d_inode, dentry);
755 mnt_drop_write(mqueue_mnt); 767 mnt_drop_write(ipc_ns->mq_mnt);
756out_err: 768out_err:
757 dput(dentry); 769 dput(dentry);
758 770
759out_unlock: 771out_unlock:
760 mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex); 772 mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
761 putname(name); 773 putname(name);
762 if (inode) 774 if (inode)
763 iput(inode); 775 iput(inode);
@@ -1214,14 +1226,14 @@ static int msg_maxsize_limit_max = MAX_MSGSIZEMAX;
1214static ctl_table mq_sysctls[] = { 1226static ctl_table mq_sysctls[] = {
1215 { 1227 {
1216 .procname = "queues_max", 1228 .procname = "queues_max",
1217 .data = &queues_max, 1229 .data = &init_ipc_ns.mq_queues_max,
1218 .maxlen = sizeof(int), 1230 .maxlen = sizeof(int),
1219 .mode = 0644, 1231 .mode = 0644,
1220 .proc_handler = &proc_dointvec, 1232 .proc_handler = &proc_dointvec,
1221 }, 1233 },
1222 { 1234 {
1223 .procname = "msg_max", 1235 .procname = "msg_max",
1224 .data = &msg_max, 1236 .data = &init_ipc_ns.mq_msg_max,
1225 .maxlen = sizeof(int), 1237 .maxlen = sizeof(int),
1226 .mode = 0644, 1238 .mode = 0644,
1227 .proc_handler = &proc_dointvec_minmax, 1239 .proc_handler = &proc_dointvec_minmax,
@@ -1230,7 +1242,7 @@ static ctl_table mq_sysctls[] = {
1230 }, 1242 },
1231 { 1243 {
1232 .procname = "msgsize_max", 1244 .procname = "msgsize_max",
1233 .data = &msgsize_max, 1245 .data = &init_ipc_ns.mq_msgsize_max,
1234 .maxlen = sizeof(int), 1246 .maxlen = sizeof(int),
1235 .mode = 0644, 1247 .mode = 0644,
1236 .proc_handler = &proc_dointvec_minmax, 1248 .proc_handler = &proc_dointvec_minmax,
@@ -1276,13 +1288,13 @@ static int __init init_mqueue_fs(void)
1276 if (error) 1288 if (error)
1277 goto out_sysctl; 1289 goto out_sysctl;
1278 1290
1279 if (IS_ERR(mqueue_mnt = kern_mount(&mqueue_fs_type))) { 1291 init_ipc_ns.mq_mnt = kern_mount(&mqueue_fs_type);
1280 error = PTR_ERR(mqueue_mnt); 1292 if (IS_ERR(init_ipc_ns.mq_mnt)) {
1293 error = PTR_ERR(init_ipc_ns.mq_mnt);
1281 goto out_filesystem; 1294 goto out_filesystem;
1282 } 1295 }
1283 1296
1284 /* internal initialization - not common for vfs */ 1297 /* internal initialization - not common for vfs */
1285 queues_count = 0;
1286 spin_lock_init(&mq_lock); 1298 spin_lock_init(&mq_lock);
1287 1299
1288 return 0; 1300 return 0;
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index c82c215693d7..73c316cb8613 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -13,10 +13,32 @@
13#include <linux/security.h> 13#include <linux/security.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/ipc.h> 15#include <linux/ipc.h>
16#include <linux/ipc_namespace.h>
16#include <asm/uaccess.h> 17#include <asm/uaccess.h>
17 18
18#include "util.h" 19#include "util.h"
19 20
21/*
22 * The next 2 defines are here bc this is the only file
23 * compiled when either CONFIG_SYSVIPC and CONFIG_POSIX_MQUEUE
24 * and not CONFIG_IPC_NS.
25 */
26struct ipc_namespace init_ipc_ns = {
27 .kref = {
28 /* It's not for this patch to change, but should this be 1? */
29 .refcount = ATOMIC_INIT(2),
30 },
31#ifdef CONFIG_POSIX_MQUEUE
32 .mq_mnt = NULL,
33 .mq_queues_count = 0,
34 .mq_queues_max = DFLT_QUEUESMAX,
35 .mq_msg_max = DFLT_MSGMAX,
36 .mq_msgsize_max = DFLT_MSGSIZEMAX,
37#endif
38};
39
40atomic_t nr_ipc_ns = ATOMIC_INIT(1);
41
20struct msg_msgseg { 42struct msg_msgseg {
21 struct msg_msgseg* next; 43 struct msg_msgseg* next;
22 /* the next part of the message follows immediately */ 44 /* the next part of the message follows immediately */
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 9171d948751e..4b4dc6d847f1 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -25,6 +25,7 @@ static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
25 sem_init_ns(ns); 25 sem_init_ns(ns);
26 msg_init_ns(ns); 26 msg_init_ns(ns);
27 shm_init_ns(ns); 27 shm_init_ns(ns);
28 mq_init_ns(ns);
28 29
29 /* 30 /*
30 * msgmni has already been computed for the new ipc ns. 31 * msgmni has already been computed for the new ipc ns.
@@ -101,6 +102,7 @@ void free_ipc_ns(struct kref *kref)
101 sem_exit_ns(ns); 102 sem_exit_ns(ns);
102 msg_exit_ns(ns); 103 msg_exit_ns(ns);
103 shm_exit_ns(ns); 104 shm_exit_ns(ns);
105 mq_exit_ns(ns);
104 kfree(ns); 106 kfree(ns);
105 atomic_dec(&nr_ipc_ns); 107 atomic_dec(&nr_ipc_ns);
106 108
diff --git a/ipc/util.c b/ipc/util.c
index 7585a72e259b..b8e4ba92f6d1 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -47,15 +47,6 @@ struct ipc_proc_iface {
47 int (*show)(struct seq_file *, void *); 47 int (*show)(struct seq_file *, void *);
48}; 48};
49 49
50struct ipc_namespace init_ipc_ns = {
51 .kref = {
52 .refcount = ATOMIC_INIT(2),
53 },
54};
55
56atomic_t nr_ipc_ns = ATOMIC_INIT(1);
57
58
59#ifdef CONFIG_MEMORY_HOTPLUG 50#ifdef CONFIG_MEMORY_HOTPLUG
60 51
61static void ipc_memory_notifier(struct work_struct *work) 52static void ipc_memory_notifier(struct work_struct *work)
diff --git a/ipc/util.h b/ipc/util.h
index 3646b45a03c9..0e7d9223acc1 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -20,6 +20,13 @@ void shm_init (void);
20 20
21struct ipc_namespace; 21struct ipc_namespace;
22 22
23#ifdef CONFIG_POSIX_MQUEUE
24void mq_exit_ns(struct ipc_namespace *ns);
25#else
26static inline void mq_exit_ns(struct ipc_namespace *ns) { }
27#endif
28
29#ifdef CONFIG_SYSVIPC
23void sem_init_ns(struct ipc_namespace *ns); 30void sem_init_ns(struct ipc_namespace *ns);
24void msg_init_ns(struct ipc_namespace *ns); 31void msg_init_ns(struct ipc_namespace *ns);
25void shm_init_ns(struct ipc_namespace *ns); 32void shm_init_ns(struct ipc_namespace *ns);
@@ -27,6 +34,15 @@ void shm_init_ns(struct ipc_namespace *ns);
27void sem_exit_ns(struct ipc_namespace *ns); 34void sem_exit_ns(struct ipc_namespace *ns);
28void msg_exit_ns(struct ipc_namespace *ns); 35void msg_exit_ns(struct ipc_namespace *ns);
29void shm_exit_ns(struct ipc_namespace *ns); 36void shm_exit_ns(struct ipc_namespace *ns);
37#else
38static inline void sem_init_ns(struct ipc_namespace *ns) { }
39static inline void msg_init_ns(struct ipc_namespace *ns) { }
40static inline void shm_init_ns(struct ipc_namespace *ns) { }
41
42static inline void sem_exit_ns(struct ipc_namespace *ns) { }
43static inline void msg_exit_ns(struct ipc_namespace *ns) { }
44static inline void shm_exit_ns(struct ipc_namespace *ns) { }
45#endif
30 46
31/* 47/*
32 * Structure that holds the parameters needed by the ipc operations 48 * Structure that holds the parameters needed by the ipc operations