aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/namespace.c')
-rw-r--r--ipc/namespace.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 1b967655eb35..9171d948751e 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -20,10 +20,20 @@ static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
20 if (ns == NULL) 20 if (ns == NULL)
21 return ERR_PTR(-ENOMEM); 21 return ERR_PTR(-ENOMEM);
22 22
23 atomic_inc(&nr_ipc_ns);
24
23 sem_init_ns(ns); 25 sem_init_ns(ns);
24 msg_init_ns(ns); 26 msg_init_ns(ns);
25 shm_init_ns(ns); 27 shm_init_ns(ns);
26 28
29 /*
30 * msgmni has already been computed for the new ipc ns.
31 * Thus, do the ipcns creation notification before registering that
32 * new ipcns in the chain.
33 */
34 ipcns_notify(IPCNS_CREATED);
35 register_ipcns_notifier(ns);
36
27 kref_init(&ns->kref); 37 kref_init(&ns->kref);
28 return ns; 38 return ns;
29} 39}
@@ -79,8 +89,24 @@ void free_ipc_ns(struct kref *kref)
79 struct ipc_namespace *ns; 89 struct ipc_namespace *ns;
80 90
81 ns = container_of(kref, struct ipc_namespace, kref); 91 ns = container_of(kref, struct ipc_namespace, kref);
92 /*
93 * Unregistering the hotplug notifier at the beginning guarantees
94 * that the ipc namespace won't be freed while we are inside the
95 * callback routine. Since the blocking_notifier_chain_XXX routines
96 * hold a rw lock on the notifier list, unregister_ipcns_notifier()
97 * won't take the rw lock before blocking_notifier_call_chain() has
98 * released the rd lock.
99 */
100 unregister_ipcns_notifier(ns);
82 sem_exit_ns(ns); 101 sem_exit_ns(ns);
83 msg_exit_ns(ns); 102 msg_exit_ns(ns);
84 shm_exit_ns(ns); 103 shm_exit_ns(ns);
85 kfree(ns); 104 kfree(ns);
105 atomic_dec(&nr_ipc_ns);
106
107 /*
108 * Do the ipcns removal notification after decrementing nr_ipc_ns in
109 * order to have a correct value when recomputing msgmni.
110 */
111 ipcns_notify(IPCNS_REMOVED);
86} 112}