Commit 614b84cf4e4a920d2af32b8f147ea1e3b8c27ea6
Committed by
Linus Torvalds
1 parent
909e6d9479
Exists in
master
and in
39 other branches
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); |
init/Kconfig
... | ... | @@ -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)" |
ipc/mqueue.c
... | ... | @@ -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; |
ipc/msgutil.c
... | ... | @@ -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; |
ipc/namespace.c
... | ... | @@ -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 |
ipc/util.c
... | ... | @@ -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) |
ipc/util.h
... | ... | @@ -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 |