aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerge E. Hallyn <serue@us.ibm.com>2009-04-06 22:01:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 11:31:09 -0400
commit614b84cf4e4a920d2af32b8f147ea1e3b8c27ea6 (patch)
tree52478e38cd400042bd89f123c4101c95943ae492
parent909e6d94795654040ed416ac69858d5d2ce66dd3 (diff)
namespaces: mqueue ns: move mqueue_mnt into struct ipc_namespace
Move mqueue vfsmount plus a few tunables into the ipc_namespace struct. The CONFIG_IPC_NS boolean and the ipc_namespace struct will serve both the posix message queue namespaces and the SYSV ipc namespaces. The sysctl code will be fixed separately in patch 3. After just this patch, making a change to posix mqueue tunables always changes the values in the initial ipc namespace. Signed-off-by: Cedric Le Goater <clg@fr.ibm.com> Signed-off-by: Serge E. Hallyn <serue@us.ibm.com> Cc: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/ipc_namespace.h39
-rw-r--r--init/Kconfig4
-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
7 files changed, 145 insertions, 71 deletions
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
index ea330f9e7100..3e6fcacebe8a 100644
--- a/include/linux/ipc_namespace.h
+++ b/include/linux/ipc_namespace.h
@@ -44,24 +44,55 @@ struct ipc_namespace {
44 int shm_tot; 44 int shm_tot;
45 45
46 struct notifier_block ipcns_nb; 46 struct notifier_block ipcns_nb;
47
48 /* The kern_mount of the mqueuefs sb. We take a ref on it */
49 struct vfsmount *mq_mnt;
50
51 /* # queues in this ns, protected by mq_lock */
52 unsigned int mq_queues_count;
53
54 /* next fields are set through sysctl */
55 unsigned int mq_queues_max; /* initialized to DFLT_QUEUESMAX */
56 unsigned int mq_msg_max; /* initialized to DFLT_MSGMAX */
57 unsigned int mq_msgsize_max; /* initialized to DFLT_MSGSIZEMAX */
58
47}; 59};
48 60
49extern struct ipc_namespace init_ipc_ns; 61extern struct ipc_namespace init_ipc_ns;
50extern atomic_t nr_ipc_ns; 62extern atomic_t nr_ipc_ns;
51 63
52#ifdef CONFIG_SYSVIPC 64#if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC)
53#define INIT_IPC_NS(ns) .ns = &init_ipc_ns, 65#define INIT_IPC_NS(ns) .ns = &init_ipc_ns,
66#else
67#define INIT_IPC_NS(ns)
68#endif
54 69
70#ifdef CONFIG_SYSVIPC
55extern int register_ipcns_notifier(struct ipc_namespace *); 71extern int register_ipcns_notifier(struct ipc_namespace *);
56extern int cond_register_ipcns_notifier(struct ipc_namespace *); 72extern int cond_register_ipcns_notifier(struct ipc_namespace *);
57extern void unregister_ipcns_notifier(struct ipc_namespace *); 73extern void unregister_ipcns_notifier(struct ipc_namespace *);
58extern int ipcns_notify(unsigned long); 74extern int ipcns_notify(unsigned long);
59
60#else /* CONFIG_SYSVIPC */ 75#else /* CONFIG_SYSVIPC */
61#define INIT_IPC_NS(ns) 76static inline int register_ipcns_notifier(struct ipc_namespace *ns)
77{ return 0; }
78static inline int cond_register_ipcns_notifier(struct ipc_namespace *ns)
79{ return 0; }
80static inline void unregister_ipcns_notifier(struct ipc_namespace *ns) { }
81static inline int ipcns_notify(unsigned long l) { return 0; }
62#endif /* CONFIG_SYSVIPC */ 82#endif /* CONFIG_SYSVIPC */
63 83
64#if defined(CONFIG_SYSVIPC) && defined(CONFIG_IPC_NS) 84#ifdef CONFIG_POSIX_MQUEUE
85extern void mq_init_ns(struct ipc_namespace *ns);
86/* default values */
87#define DFLT_QUEUESMAX 256 /* max number of message queues */
88#define DFLT_MSGMAX 10 /* max number of messages in each queue */
89#define HARD_MSGMAX (131072/sizeof(void *))
90#define DFLT_MSGSIZEMAX 8192 /* max message size */
91#else
92#define mq_init_ns(ns) ((void) 0)
93#endif
94
95#if defined(CONFIG_IPC_NS)
65extern void free_ipc_ns(struct kref *kref); 96extern void free_ipc_ns(struct kref *kref);
66extern struct ipc_namespace *copy_ipcs(unsigned long flags, 97extern struct ipc_namespace *copy_ipcs(unsigned long flags,
67 struct ipc_namespace *ns); 98 struct ipc_namespace *ns);
diff --git a/init/Kconfig b/init/Kconfig
index c52d1d48272a..a0807ba91644 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -670,10 +670,10 @@ config UTS_NS
670 670
671config IPC_NS 671config IPC_NS
672 bool "IPC namespace" 672 bool "IPC namespace"
673 depends on NAMESPACES && SYSVIPC 673 depends on NAMESPACES && (SYSVIPC || POSIX_MQUEUE)
674 help 674 help
675 In this namespace tasks work with IPC ids which correspond to 675 In this namespace tasks work with IPC ids which correspond to
676 different IPC objects in different namespaces 676 different IPC objects in different namespaces.
677 677
678config USER_NS 678config USER_NS
679 bool "User namespace (EXPERIMENTAL)" 679 bool "User namespace (EXPERIMENTAL)"
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