diff options
Diffstat (limited to 'ipc/namespace.c')
| -rw-r--r-- | ipc/namespace.c | 26 |
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 | } |
