aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-04-07 05:15:40 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-07 05:15:40 -0400
commit5e34437840d33554f69380584311743b39e8fbeb (patch)
treee081135619ee146af5efb9ee883afca950df5757 /kernel/fork.c
parent77d05632baee21b1cef8730d7c06aa69601e4dca (diff)
parentd508afb437daee7cf07da085b635c44a4ebf9b38 (diff)
Merge branch 'linus' into core/softlockup
Conflicts: kernel/sysctl.c
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c88
1 files changed, 43 insertions, 45 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 3b5dcf9a66aa..989c7c202b3d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -60,7 +60,9 @@
60#include <linux/tty.h> 60#include <linux/tty.h>
61#include <linux/proc_fs.h> 61#include <linux/proc_fs.h>
62#include <linux/blkdev.h> 62#include <linux/blkdev.h>
63#include <linux/fs_struct.h>
63#include <trace/sched.h> 64#include <trace/sched.h>
65#include <linux/magic.h>
64 66
65#include <asm/pgtable.h> 67#include <asm/pgtable.h>
66#include <asm/pgalloc.h> 68#include <asm/pgalloc.h>
@@ -212,6 +214,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
212{ 214{
213 struct task_struct *tsk; 215 struct task_struct *tsk;
214 struct thread_info *ti; 216 struct thread_info *ti;
217 unsigned long *stackend;
218
215 int err; 219 int err;
216 220
217 prepare_to_copy(orig); 221 prepare_to_copy(orig);
@@ -237,6 +241,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
237 goto out; 241 goto out;
238 242
239 setup_thread_stack(tsk, orig); 243 setup_thread_stack(tsk, orig);
244 stackend = end_of_stack(tsk);
245 *stackend = STACK_END_MAGIC; /* for overflow detection */
240 246
241#ifdef CONFIG_CC_STACKPROTECTOR 247#ifdef CONFIG_CC_STACKPROTECTOR
242 tsk->stack_canary = get_random_int(); 248 tsk->stack_canary = get_random_int();
@@ -279,7 +285,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
279 mm->free_area_cache = oldmm->mmap_base; 285 mm->free_area_cache = oldmm->mmap_base;
280 mm->cached_hole_size = ~0UL; 286 mm->cached_hole_size = ~0UL;
281 mm->map_count = 0; 287 mm->map_count = 0;
282 cpus_clear(mm->cpu_vm_mask); 288 cpumask_clear(mm_cpumask(mm));
283 mm->mm_rb = RB_ROOT; 289 mm->mm_rb = RB_ROOT;
284 rb_link = &mm->mm_rb.rb_node; 290 rb_link = &mm->mm_rb.rb_node;
285 rb_parent = NULL; 291 rb_parent = NULL;
@@ -679,38 +685,21 @@ fail_nomem:
679 return retval; 685 return retval;
680} 686}
681 687
682static struct fs_struct *__copy_fs_struct(struct fs_struct *old)
683{
684 struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
685 /* We don't need to lock fs - think why ;-) */
686 if (fs) {
687 atomic_set(&fs->count, 1);
688 rwlock_init(&fs->lock);
689 fs->umask = old->umask;
690 read_lock(&old->lock);
691 fs->root = old->root;
692 path_get(&old->root);
693 fs->pwd = old->pwd;
694 path_get(&old->pwd);
695 read_unlock(&old->lock);
696 }
697 return fs;
698}
699
700struct fs_struct *copy_fs_struct(struct fs_struct *old)
701{
702 return __copy_fs_struct(old);
703}
704
705EXPORT_SYMBOL_GPL(copy_fs_struct);
706
707static int copy_fs(unsigned long clone_flags, struct task_struct *tsk) 688static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
708{ 689{
690 struct fs_struct *fs = current->fs;
709 if (clone_flags & CLONE_FS) { 691 if (clone_flags & CLONE_FS) {
710 atomic_inc(&current->fs->count); 692 /* tsk->fs is already what we want */
693 write_lock(&fs->lock);
694 if (fs->in_exec) {
695 write_unlock(&fs->lock);
696 return -EAGAIN;
697 }
698 fs->users++;
699 write_unlock(&fs->lock);
711 return 0; 700 return 0;
712 } 701 }
713 tsk->fs = __copy_fs_struct(current->fs); 702 tsk->fs = copy_fs_struct(fs);
714 if (!tsk->fs) 703 if (!tsk->fs)
715 return -ENOMEM; 704 return -ENOMEM;
716 return 0; 705 return 0;
@@ -839,6 +828,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
839 atomic_set(&sig->live, 1); 828 atomic_set(&sig->live, 1);
840 init_waitqueue_head(&sig->wait_chldexit); 829 init_waitqueue_head(&sig->wait_chldexit);
841 sig->flags = 0; 830 sig->flags = 0;
831 if (clone_flags & CLONE_NEWPID)
832 sig->flags |= SIGNAL_UNKILLABLE;
842 sig->group_exit_code = 0; 833 sig->group_exit_code = 0;
843 sig->group_exit_task = NULL; 834 sig->group_exit_task = NULL;
844 sig->group_stop_count = 0; 835 sig->group_stop_count = 0;
@@ -1118,7 +1109,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1118 goto bad_fork_cleanup_mm; 1109 goto bad_fork_cleanup_mm;
1119 if ((retval = copy_io(clone_flags, p))) 1110 if ((retval = copy_io(clone_flags, p)))
1120 goto bad_fork_cleanup_namespaces; 1111 goto bad_fork_cleanup_namespaces;
1121 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); 1112 retval = copy_thread(clone_flags, stack_start, stack_size, p, regs);
1122 if (retval) 1113 if (retval)
1123 goto bad_fork_cleanup_io; 1114 goto bad_fork_cleanup_io;
1124 1115
@@ -1177,10 +1168,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1177#endif 1168#endif
1178 clear_all_latency_tracing(p); 1169 clear_all_latency_tracing(p);
1179 1170
1180 /* Our parent execution domain becomes current domain
1181 These must match for thread signalling to apply */
1182 p->parent_exec_id = p->self_exec_id;
1183
1184 /* ok, now we should be set up.. */ 1171 /* ok, now we should be set up.. */
1185 p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL); 1172 p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL);
1186 p->pdeath_signal = 0; 1173 p->pdeath_signal = 0;
@@ -1218,10 +1205,13 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1218 set_task_cpu(p, smp_processor_id()); 1205 set_task_cpu(p, smp_processor_id());
1219 1206
1220 /* CLONE_PARENT re-uses the old parent */ 1207 /* CLONE_PARENT re-uses the old parent */
1221 if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) 1208 if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
1222 p->real_parent = current->real_parent; 1209 p->real_parent = current->real_parent;
1223 else 1210 p->parent_exec_id = current->parent_exec_id;
1211 } else {
1224 p->real_parent = current; 1212 p->real_parent = current;
1213 p->parent_exec_id = current->self_exec_id;
1214 }
1225 1215
1226 spin_lock(&current->sighand->siglock); 1216 spin_lock(&current->sighand->siglock);
1227 1217
@@ -1257,8 +1247,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1257 p->signal->leader_pid = pid; 1247 p->signal->leader_pid = pid;
1258 tty_kref_put(p->signal->tty); 1248 tty_kref_put(p->signal->tty);
1259 p->signal->tty = tty_kref_get(current->signal->tty); 1249 p->signal->tty = tty_kref_get(current->signal->tty);
1260 set_task_pgrp(p, task_pgrp_nr(current));
1261 set_task_session(p, task_session_nr(current));
1262 attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); 1250 attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
1263 attach_pid(p, PIDTYPE_SID, task_session(current)); 1251 attach_pid(p, PIDTYPE_SID, task_session(current));
1264 list_add_tail_rcu(&p->tasks, &init_task.tasks); 1252 list_add_tail_rcu(&p->tasks, &init_task.tasks);
@@ -1482,6 +1470,7 @@ void __init proc_caches_init(void)
1482 mm_cachep = kmem_cache_create("mm_struct", 1470 mm_cachep = kmem_cache_create("mm_struct",
1483 sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, 1471 sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
1484 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); 1472 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
1473 vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC);
1485 mmap_init(); 1474 mmap_init();
1486} 1475}
1487 1476
@@ -1537,12 +1526,16 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
1537{ 1526{
1538 struct fs_struct *fs = current->fs; 1527 struct fs_struct *fs = current->fs;
1539 1528
1540 if ((unshare_flags & CLONE_FS) && 1529 if (!(unshare_flags & CLONE_FS) || !fs)
1541 (fs && atomic_read(&fs->count) > 1)) { 1530 return 0;
1542 *new_fsp = __copy_fs_struct(current->fs); 1531
1543 if (!*new_fsp) 1532 /* don't need lock here; in the worst case we'll do useless copy */
1544 return -ENOMEM; 1533 if (fs->users == 1)
1545 } 1534 return 0;
1535
1536 *new_fsp = copy_fs_struct(fs);
1537 if (!*new_fsp)
1538 return -ENOMEM;
1546 1539
1547 return 0; 1540 return 0;
1548} 1541}
@@ -1658,8 +1651,13 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
1658 1651
1659 if (new_fs) { 1652 if (new_fs) {
1660 fs = current->fs; 1653 fs = current->fs;
1654 write_lock(&fs->lock);
1661 current->fs = new_fs; 1655 current->fs = new_fs;
1662 new_fs = fs; 1656 if (--fs->users)
1657 new_fs = NULL;
1658 else
1659 new_fs = fs;
1660 write_unlock(&fs->lock);
1663 } 1661 }
1664 1662
1665 if (new_mm) { 1663 if (new_mm) {
@@ -1698,7 +1696,7 @@ bad_unshare_cleanup_sigh:
1698 1696
1699bad_unshare_cleanup_fs: 1697bad_unshare_cleanup_fs:
1700 if (new_fs) 1698 if (new_fs)
1701 put_fs_struct(new_fs); 1699 free_fs_struct(new_fs);
1702 1700
1703bad_unshare_cleanup_thread: 1701bad_unshare_cleanup_thread:
1704bad_unshare_out: 1702bad_unshare_out: