diff options
author | Pierre Peiffer <pierre.peiffer@bull.net> | 2008-02-08 07:18:57 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 12:22:26 -0500 |
commit | 01b8b07a5d77d22e609267dcae74d15e3e9c5f13 (patch) | |
tree | dd53c51f75de9511da7fdf283c73080d6c2552a8 /ipc/shm.c | |
parent | ed2ddbf88c0ddeeae4c78bb306a116dfd867c55c (diff) |
IPC: consolidate sem_exit_ns(), msg_exit_ns() and shm_exit_ns()
sem_exit_ns(), msg_exit_ns() and shm_exit_ns() are all called when an
ipc_namespace is released to free all ipcs of each type. But in fact, they
do the same thing: they loop around all ipcs to free them individually by
calling a specific routine.
This patch proposes to consolidate this by introducing a common function,
free_ipcs(), that do the job. The specific routine to call on each
individual ipcs is passed as parameter. For this, these ipc-specific
'free' routines are reworked to take a generic 'struct ipc_perm' as
parameter.
Signed-off-by: Pierre Peiffer <pierre.peiffer@bull.net>
Cc: Cedric Le Goater <clg@fr.ibm.com>
Cc: Pavel Emelyanov <xemul@openvz.org>
Cc: Nadia Derbey <Nadia.Derbey@bull.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/shm.c')
-rw-r--r-- | ipc/shm.c | 27 |
1 files changed, 6 insertions, 21 deletions
@@ -83,8 +83,11 @@ void shm_init_ns(struct ipc_namespace *ns) | |||
83 | * Called with shm_ids.rw_mutex (writer) and the shp structure locked. | 83 | * Called with shm_ids.rw_mutex (writer) and the shp structure locked. |
84 | * Only shm_ids.rw_mutex remains locked on exit. | 84 | * Only shm_ids.rw_mutex remains locked on exit. |
85 | */ | 85 | */ |
86 | static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp) | 86 | static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) |
87 | { | 87 | { |
88 | struct shmid_kernel *shp; | ||
89 | shp = container_of(ipcp, struct shmid_kernel, shm_perm); | ||
90 | |||
88 | if (shp->shm_nattch){ | 91 | if (shp->shm_nattch){ |
89 | shp->shm_perm.mode |= SHM_DEST; | 92 | shp->shm_perm.mode |= SHM_DEST; |
90 | /* Do not find it any more */ | 93 | /* Do not find it any more */ |
@@ -97,25 +100,7 @@ static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp) | |||
97 | #ifdef CONFIG_IPC_NS | 100 | #ifdef CONFIG_IPC_NS |
98 | void shm_exit_ns(struct ipc_namespace *ns) | 101 | void shm_exit_ns(struct ipc_namespace *ns) |
99 | { | 102 | { |
100 | struct shmid_kernel *shp; | 103 | free_ipcs(ns, &shm_ids(ns), do_shm_rmid); |
101 | struct kern_ipc_perm *perm; | ||
102 | int next_id; | ||
103 | int total, in_use; | ||
104 | |||
105 | down_write(&shm_ids(ns).rw_mutex); | ||
106 | |||
107 | in_use = shm_ids(ns).in_use; | ||
108 | |||
109 | for (total = 0, next_id = 0; total < in_use; next_id++) { | ||
110 | perm = idr_find(&shm_ids(ns).ipcs_idr, next_id); | ||
111 | if (perm == NULL) | ||
112 | continue; | ||
113 | ipc_lock_by_ptr(perm); | ||
114 | shp = container_of(perm, struct shmid_kernel, shm_perm); | ||
115 | do_shm_rmid(ns, shp); | ||
116 | total++; | ||
117 | } | ||
118 | up_write(&shm_ids(ns).rw_mutex); | ||
119 | } | 104 | } |
120 | #endif | 105 | #endif |
121 | 106 | ||
@@ -832,7 +817,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) | |||
832 | if (err) | 817 | if (err) |
833 | goto out_unlock_up; | 818 | goto out_unlock_up; |
834 | 819 | ||
835 | do_shm_rmid(ns, shp); | 820 | do_shm_rmid(ns, &shp->shm_perm); |
836 | up_write(&shm_ids(ns).rw_mutex); | 821 | up_write(&shm_ids(ns).rw_mutex); |
837 | goto out; | 822 | goto out; |
838 | } | 823 | } |