diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-09-24 23:15:15 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-09-24 23:15:15 -0400 |
commit | c373ba999103fa794f041eab5bd490714d2dee88 (patch) | |
tree | 8f2b445b1e0af2491c83527967dbcda76054a486 /kernel/fork.c | |
parent | 6f3529f00a0a9ac06413d18d3926adf099cb59af (diff) | |
parent | 851b147e4411df6a1e7e90e2a609773c277eefd2 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 51ad0b0b7266..266c6af6ef1b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -434,6 +434,14 @@ __setup("coredump_filter=", coredump_filter_setup); | |||
434 | 434 | ||
435 | #include <linux/init_task.h> | 435 | #include <linux/init_task.h> |
436 | 436 | ||
437 | static void mm_init_aio(struct mm_struct *mm) | ||
438 | { | ||
439 | #ifdef CONFIG_AIO | ||
440 | spin_lock_init(&mm->ioctx_lock); | ||
441 | INIT_HLIST_HEAD(&mm->ioctx_list); | ||
442 | #endif | ||
443 | } | ||
444 | |||
437 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | 445 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) |
438 | { | 446 | { |
439 | atomic_set(&mm->mm_users, 1); | 447 | atomic_set(&mm->mm_users, 1); |
@@ -447,10 +455,9 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | |||
447 | set_mm_counter(mm, file_rss, 0); | 455 | set_mm_counter(mm, file_rss, 0); |
448 | set_mm_counter(mm, anon_rss, 0); | 456 | set_mm_counter(mm, anon_rss, 0); |
449 | spin_lock_init(&mm->page_table_lock); | 457 | spin_lock_init(&mm->page_table_lock); |
450 | spin_lock_init(&mm->ioctx_lock); | ||
451 | INIT_HLIST_HEAD(&mm->ioctx_list); | ||
452 | mm->free_area_cache = TASK_UNMAPPED_BASE; | 458 | mm->free_area_cache = TASK_UNMAPPED_BASE; |
453 | mm->cached_hole_size = ~0UL; | 459 | mm->cached_hole_size = ~0UL; |
460 | mm_init_aio(mm); | ||
454 | mm_init_owner(mm, p); | 461 | mm_init_owner(mm, p); |
455 | 462 | ||
456 | if (likely(!mm_alloc_pgd(mm))) { | 463 | if (likely(!mm_alloc_pgd(mm))) { |
@@ -511,6 +518,8 @@ void mmput(struct mm_struct *mm) | |||
511 | spin_unlock(&mmlist_lock); | 518 | spin_unlock(&mmlist_lock); |
512 | } | 519 | } |
513 | put_swap_token(mm); | 520 | put_swap_token(mm); |
521 | if (mm->binfmt) | ||
522 | module_put(mm->binfmt->module); | ||
514 | mmdrop(mm); | 523 | mmdrop(mm); |
515 | } | 524 | } |
516 | } | 525 | } |
@@ -636,9 +645,14 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
636 | mm->hiwater_rss = get_mm_rss(mm); | 645 | mm->hiwater_rss = get_mm_rss(mm); |
637 | mm->hiwater_vm = mm->total_vm; | 646 | mm->hiwater_vm = mm->total_vm; |
638 | 647 | ||
648 | if (mm->binfmt && !try_module_get(mm->binfmt->module)) | ||
649 | goto free_pt; | ||
650 | |||
639 | return mm; | 651 | return mm; |
640 | 652 | ||
641 | free_pt: | 653 | free_pt: |
654 | /* don't put binfmt in mmput, we haven't got module yet */ | ||
655 | mm->binfmt = NULL; | ||
642 | mmput(mm); | 656 | mmput(mm); |
643 | 657 | ||
644 | fail_nomem: | 658 | fail_nomem: |
@@ -979,6 +993,16 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
979 | if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM)) | 993 | if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM)) |
980 | return ERR_PTR(-EINVAL); | 994 | return ERR_PTR(-EINVAL); |
981 | 995 | ||
996 | /* | ||
997 | * Siblings of global init remain as zombies on exit since they are | ||
998 | * not reaped by their parent (swapper). To solve this and to avoid | ||
999 | * multi-rooted process trees, prevent global and container-inits | ||
1000 | * from creating siblings. | ||
1001 | */ | ||
1002 | if ((clone_flags & CLONE_PARENT) && | ||
1003 | current->signal->flags & SIGNAL_UNKILLABLE) | ||
1004 | return ERR_PTR(-EINVAL); | ||
1005 | |||
982 | retval = security_task_create(clone_flags); | 1006 | retval = security_task_create(clone_flags); |
983 | if (retval) | 1007 | if (retval) |
984 | goto fork_out; | 1008 | goto fork_out; |
@@ -1020,9 +1044,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1020 | if (!try_module_get(task_thread_info(p)->exec_domain->module)) | 1044 | if (!try_module_get(task_thread_info(p)->exec_domain->module)) |
1021 | goto bad_fork_cleanup_count; | 1045 | goto bad_fork_cleanup_count; |
1022 | 1046 | ||
1023 | if (p->binfmt && !try_module_get(p->binfmt->module)) | ||
1024 | goto bad_fork_cleanup_put_domain; | ||
1025 | |||
1026 | p->did_exec = 0; | 1047 | p->did_exec = 0; |
1027 | delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ | 1048 | delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ |
1028 | copy_flags(clone_flags, p); | 1049 | copy_flags(clone_flags, p); |
@@ -1310,9 +1331,6 @@ bad_fork_cleanup_cgroup: | |||
1310 | #endif | 1331 | #endif |
1311 | cgroup_exit(p, cgroup_callbacks_done); | 1332 | cgroup_exit(p, cgroup_callbacks_done); |
1312 | delayacct_tsk_free(p); | 1333 | delayacct_tsk_free(p); |
1313 | if (p->binfmt) | ||
1314 | module_put(p->binfmt->module); | ||
1315 | bad_fork_cleanup_put_domain: | ||
1316 | module_put(task_thread_info(p)->exec_domain->module); | 1334 | module_put(task_thread_info(p)->exec_domain->module); |
1317 | bad_fork_cleanup_count: | 1335 | bad_fork_cleanup_count: |
1318 | atomic_dec(&p->cred->user->processes); | 1336 | atomic_dec(&p->cred->user->processes); |