diff options
-rw-r--r-- | include/linux/ipc_namespace.h | 1 | ||||
-rw-r--r-- | ipc/namespace.c | 48 |
2 files changed, 24 insertions, 25 deletions
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h index 3bf40e246a80..804e4e4a2b62 100644 --- a/include/linux/ipc_namespace.h +++ b/include/linux/ipc_namespace.h | |||
@@ -94,7 +94,6 @@ static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; } | |||
94 | #endif | 94 | #endif |
95 | 95 | ||
96 | #if defined(CONFIG_IPC_NS) | 96 | #if defined(CONFIG_IPC_NS) |
97 | extern void free_ipc_ns(struct ipc_namespace *ns); | ||
98 | extern struct ipc_namespace *copy_ipcs(unsigned long flags, | 97 | extern struct ipc_namespace *copy_ipcs(unsigned long flags, |
99 | struct ipc_namespace *ns); | 98 | struct ipc_namespace *ns); |
100 | extern void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids, | 99 | extern void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids, |
diff --git a/ipc/namespace.c b/ipc/namespace.c index 231ee5359abf..a1094ff0befa 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c | |||
@@ -83,6 +83,30 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids, | |||
83 | up_write(&ids->rw_mutex); | 83 | up_write(&ids->rw_mutex); |
84 | } | 84 | } |
85 | 85 | ||
86 | static void free_ipc_ns(struct ipc_namespace *ns) | ||
87 | { | ||
88 | /* | ||
89 | * Unregistering the hotplug notifier at the beginning guarantees | ||
90 | * that the ipc namespace won't be freed while we are inside the | ||
91 | * callback routine. Since the blocking_notifier_chain_XXX routines | ||
92 | * hold a rw lock on the notifier list, unregister_ipcns_notifier() | ||
93 | * won't take the rw lock before blocking_notifier_call_chain() has | ||
94 | * released the rd lock. | ||
95 | */ | ||
96 | unregister_ipcns_notifier(ns); | ||
97 | sem_exit_ns(ns); | ||
98 | msg_exit_ns(ns); | ||
99 | shm_exit_ns(ns); | ||
100 | kfree(ns); | ||
101 | atomic_dec(&nr_ipc_ns); | ||
102 | |||
103 | /* | ||
104 | * Do the ipcns removal notification after decrementing nr_ipc_ns in | ||
105 | * order to have a correct value when recomputing msgmni. | ||
106 | */ | ||
107 | ipcns_notify(IPCNS_REMOVED); | ||
108 | } | ||
109 | |||
86 | /* | 110 | /* |
87 | * put_ipc_ns - drop a reference to an ipc namespace. | 111 | * put_ipc_ns - drop a reference to an ipc namespace. |
88 | * @ns: the namespace to put | 112 | * @ns: the namespace to put |
@@ -108,27 +132,3 @@ void put_ipc_ns(struct ipc_namespace *ns) | |||
108 | free_ipc_ns(ns); | 132 | free_ipc_ns(ns); |
109 | } | 133 | } |
110 | } | 134 | } |
111 | |||
112 | void free_ipc_ns(struct ipc_namespace *ns) | ||
113 | { | ||
114 | /* | ||
115 | * Unregistering the hotplug notifier at the beginning guarantees | ||
116 | * that the ipc namespace won't be freed while we are inside the | ||
117 | * callback routine. Since the blocking_notifier_chain_XXX routines | ||
118 | * hold a rw lock on the notifier list, unregister_ipcns_notifier() | ||
119 | * won't take the rw lock before blocking_notifier_call_chain() has | ||
120 | * released the rd lock. | ||
121 | */ | ||
122 | unregister_ipcns_notifier(ns); | ||
123 | sem_exit_ns(ns); | ||
124 | msg_exit_ns(ns); | ||
125 | shm_exit_ns(ns); | ||
126 | kfree(ns); | ||
127 | atomic_dec(&nr_ipc_ns); | ||
128 | |||
129 | /* | ||
130 | * Do the ipcns removal notification after decrementing nr_ipc_ns in | ||
131 | * order to have a correct value when recomputing msgmni. | ||
132 | */ | ||
133 | ipcns_notify(IPCNS_REMOVED); | ||
134 | } | ||