aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/msg.c')
-rw-r--r--ipc/msg.c57
1 files changed, 12 insertions, 45 deletions
diff --git a/ipc/msg.c b/ipc/msg.c
index ec0c724054b9..46585a05473e 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -36,6 +36,7 @@
36#include <linux/seq_file.h> 36#include <linux/seq_file.h>
37#include <linux/rwsem.h> 37#include <linux/rwsem.h>
38#include <linux/nsproxy.h> 38#include <linux/nsproxy.h>
39#include <linux/ipc_namespace.h>
39 40
40#include <asm/current.h> 41#include <asm/current.h>
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
@@ -66,72 +67,37 @@ struct msg_sender {
66#define SEARCH_NOTEQUAL 3 67#define SEARCH_NOTEQUAL 3
67#define SEARCH_LESSEQUAL 4 68#define SEARCH_LESSEQUAL 4
68 69
69static struct ipc_ids init_msg_ids; 70#define msg_ids(ns) ((ns)->ids[IPC_MSG_IDS])
70
71#define msg_ids(ns) (*((ns)->ids[IPC_MSG_IDS]))
72 71
73#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm) 72#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm)
74#define msg_buildid(id, seq) ipc_buildid(id, seq) 73#define msg_buildid(id, seq) ipc_buildid(id, seq)
75 74
76static void freeque(struct ipc_namespace *, struct msg_queue *); 75static void freeque(struct ipc_namespace *, struct kern_ipc_perm *);
77static int newque(struct ipc_namespace *, struct ipc_params *); 76static int newque(struct ipc_namespace *, struct ipc_params *);
78#ifdef CONFIG_PROC_FS 77#ifdef CONFIG_PROC_FS
79static int sysvipc_msg_proc_show(struct seq_file *s, void *it); 78static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
80#endif 79#endif
81 80
82static void __msg_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids) 81void msg_init_ns(struct ipc_namespace *ns)
83{ 82{
84 ns->ids[IPC_MSG_IDS] = ids;
85 ns->msg_ctlmax = MSGMAX; 83 ns->msg_ctlmax = MSGMAX;
86 ns->msg_ctlmnb = MSGMNB; 84 ns->msg_ctlmnb = MSGMNB;
87 ns->msg_ctlmni = MSGMNI; 85 ns->msg_ctlmni = MSGMNI;
88 atomic_set(&ns->msg_bytes, 0); 86 atomic_set(&ns->msg_bytes, 0);
89 atomic_set(&ns->msg_hdrs, 0); 87 atomic_set(&ns->msg_hdrs, 0);
90 ipc_init_ids(ids); 88 ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
91}
92
93int msg_init_ns(struct ipc_namespace *ns)
94{
95 struct ipc_ids *ids;
96
97 ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
98 if (ids == NULL)
99 return -ENOMEM;
100
101 __msg_init_ns(ns, ids);
102 return 0;
103} 89}
104 90
91#ifdef CONFIG_IPC_NS
105void msg_exit_ns(struct ipc_namespace *ns) 92void msg_exit_ns(struct ipc_namespace *ns)
106{ 93{
107 struct msg_queue *msq; 94 free_ipcs(ns, &msg_ids(ns), freeque);
108 struct kern_ipc_perm *perm;
109 int next_id;
110 int total, in_use;
111
112 down_write(&msg_ids(ns).rw_mutex);
113
114 in_use = msg_ids(ns).in_use;
115
116 for (total = 0, next_id = 0; total < in_use; next_id++) {
117 perm = idr_find(&msg_ids(ns).ipcs_idr, next_id);
118 if (perm == NULL)
119 continue;
120 ipc_lock_by_ptr(perm);
121 msq = container_of(perm, struct msg_queue, q_perm);
122 freeque(ns, msq);
123 total++;
124 }
125
126 up_write(&msg_ids(ns).rw_mutex);
127
128 kfree(ns->ids[IPC_MSG_IDS]);
129 ns->ids[IPC_MSG_IDS] = NULL;
130} 95}
96#endif
131 97
132void __init msg_init(void) 98void __init msg_init(void)
133{ 99{
134 __msg_init_ns(&init_ipc_ns, &init_msg_ids); 100 msg_init_ns(&init_ipc_ns);
135 ipc_init_proc_interface("sysvipc/msg", 101 ipc_init_proc_interface("sysvipc/msg",
136 " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n", 102 " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
137 IPC_MSG_IDS, sysvipc_msg_proc_show); 103 IPC_MSG_IDS, sysvipc_msg_proc_show);
@@ -289,9 +255,10 @@ static void expunge_all(struct msg_queue *msq, int res)
289 * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held 255 * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held
290 * before freeque() is called. msg_ids.rw_mutex remains locked on exit. 256 * before freeque() is called. msg_ids.rw_mutex remains locked on exit.
291 */ 257 */
292static void freeque(struct ipc_namespace *ns, struct msg_queue *msq) 258static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
293{ 259{
294 struct list_head *tmp; 260 struct list_head *tmp;
261 struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);
295 262
296 expunge_all(msq, -EIDRM); 263 expunge_all(msq, -EIDRM);
297 ss_wakeup(&msq->q_senders, 1); 264 ss_wakeup(&msq->q_senders, 1);
@@ -597,7 +564,7 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
597 break; 564 break;
598 } 565 }
599 case IPC_RMID: 566 case IPC_RMID:
600 freeque(ns, msq); 567 freeque(ns, &msq->q_perm);
601 break; 568 break;
602 } 569 }
603 err = 0; 570 err = 0;