aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/shm.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/shm.c')
-rw-r--r--ipc/shm.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/ipc/shm.c b/ipc/shm.c
index 89fc354156cb..1fc3a61b443b 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -178,6 +178,7 @@ static void shm_rcu_free(struct rcu_head *head)
178 178
179static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s) 179static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s)
180{ 180{
181 list_del(&s->shm_clist);
181 ipc_rmid(&shm_ids(ns), &s->shm_perm); 182 ipc_rmid(&shm_ids(ns), &s->shm_perm);
182} 183}
183 184
@@ -268,14 +269,10 @@ static void shm_close(struct vm_area_struct *vma)
268} 269}
269 270
270/* Called with ns->shm_ids(ns).rwsem locked */ 271/* Called with ns->shm_ids(ns).rwsem locked */
271static int shm_try_destroy_current(int id, void *p, void *data) 272static void shm_mark_orphan(struct shmid_kernel *shp, struct ipc_namespace *ns)
272{ 273{
273 struct ipc_namespace *ns = data; 274 if (WARN_ON(shp->shm_creator != current)) /* Remove me when it works */
274 struct kern_ipc_perm *ipcp = p; 275 return;
275 struct shmid_kernel *shp = container_of(ipcp, struct shmid_kernel, shm_perm);
276
277 if (shp->shm_creator != current)
278 return 0;
279 276
280 /* 277 /*
281 * Mark it as orphaned to destroy the segment when 278 * Mark it as orphaned to destroy the segment when
@@ -289,13 +286,12 @@ static int shm_try_destroy_current(int id, void *p, void *data)
289 * is not set, it shouldn't be deleted here. 286 * is not set, it shouldn't be deleted here.
290 */ 287 */
291 if (!ns->shm_rmid_forced) 288 if (!ns->shm_rmid_forced)
292 return 0; 289 return;
293 290
294 if (shm_may_destroy(ns, shp)) { 291 if (shm_may_destroy(ns, shp)) {
295 shm_lock_by_ptr(shp); 292 shm_lock_by_ptr(shp);
296 shm_destroy(ns, shp); 293 shm_destroy(ns, shp);
297 } 294 }
298 return 0;
299} 295}
300 296
301/* Called with ns->shm_ids(ns).rwsem locked */ 297/* Called with ns->shm_ids(ns).rwsem locked */
@@ -333,14 +329,17 @@ void shm_destroy_orphaned(struct ipc_namespace *ns)
333void exit_shm(struct task_struct *task) 329void exit_shm(struct task_struct *task)
334{ 330{
335 struct ipc_namespace *ns = task->nsproxy->ipc_ns; 331 struct ipc_namespace *ns = task->nsproxy->ipc_ns;
332 struct shmid_kernel *shp, *n;
336 333
337 if (shm_ids(ns).in_use == 0) 334 if (shm_ids(ns).in_use == 0)
338 return; 335 return;
339 336
340 /* Destroy all already created segments, but not mapped yet */ 337 /* Destroy all already created segments, but not mapped yet */
341 down_write(&shm_ids(ns).rwsem); 338 down_write(&shm_ids(ns).rwsem);
342 if (shm_ids(ns).in_use) 339 list_for_each_entry_safe(shp, n, &task->sysvshm.shm_clist, shm_clist)
343 idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_current, ns); 340 shm_mark_orphan(shp, ns);
341 /* remove the list head from any segments still attached */
342 list_del(&task->sysvshm.shm_clist);
344 up_write(&shm_ids(ns).rwsem); 343 up_write(&shm_ids(ns).rwsem);
345} 344}
346 345
@@ -561,6 +560,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
561 shp->shm_nattch = 0; 560 shp->shm_nattch = 0;
562 shp->shm_file = file; 561 shp->shm_file = file;
563 shp->shm_creator = current; 562 shp->shm_creator = current;
563 list_add(&shp->shm_clist, &current->sysvshm.shm_clist);
564 564
565 /* 565 /*
566 * shmid gets reported as "inode#" in /proc/pid/maps. 566 * shmid gets reported as "inode#" in /proc/pid/maps.