Commit 614b84cf4e4a920d2af32b8f147ea1e3b8c27ea6

Authored by Serge E. Hallyn
Committed by Linus Torvalds
1 parent 909e6d9479

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>

Showing 7 changed files with 145 additions and 71 deletions Side-by-side Diff

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