Blame view

kernel/fork.c 42.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
  /*
   *  linux/kernel/fork.c
   *
   *  Copyright (C) 1991, 1992  Linus Torvalds
   */
  
  /*
   *  'fork.c' contains the help-routines for the 'fork' system call
   * (see also entry.S and others).
   * Fork is rather simple, once you get the hang of it, but the memory
   * management can be a bitch. See 'mm/memory.c': 'copy_page_range()'
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  #include <linux/slab.h>
  #include <linux/init.h>
  #include <linux/unistd.h>
  #include <linux/smp_lock.h>
  #include <linux/module.h>
  #include <linux/vmalloc.h>
  #include <linux/completion.h>
  #include <linux/namespace.h>
  #include <linux/personality.h>
  #include <linux/mempolicy.h>
  #include <linux/sem.h>
  #include <linux/file.h>
  #include <linux/key.h>
  #include <linux/binfmts.h>
  #include <linux/mman.h>
  #include <linux/fs.h>
ab516013a   Serge E. Hallyn   [PATCH] namespace...
29
  #include <linux/nsproxy.h>
c59ede7b7   Randy.Dunlap   [PATCH] move capa...
30
  #include <linux/capability.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
35
36
37
  #include <linux/cpu.h>
  #include <linux/cpuset.h>
  #include <linux/security.h>
  #include <linux/swap.h>
  #include <linux/syscalls.h>
  #include <linux/jiffies.h>
  #include <linux/futex.h>
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
38
  #include <linux/rcupdate.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
43
44
  #include <linux/ptrace.h>
  #include <linux/mount.h>
  #include <linux/audit.h>
  #include <linux/profile.h>
  #include <linux/rmap.h>
  #include <linux/acct.h>
8f0ab5147   Jay Lan   [PATCH] csa: conv...
45
  #include <linux/tsacct_kern.h>
9f46080c4   Matt Helsley   [PATCH] Process E...
46
  #include <linux/cn_proc.h>
ca74e92b4   Shailabh Nagar   [PATCH] per-task-...
47
  #include <linux/delayacct.h>
ad4ecbcba   Shailabh Nagar   [PATCH] delay acc...
48
  #include <linux/taskstats_kern.h>
0a4254058   Arjan van de Ven   [PATCH] Add the c...
49
  #include <linux/random.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  
  #include <asm/pgtable.h>
  #include <asm/pgalloc.h>
  #include <asm/uaccess.h>
  #include <asm/mmu_context.h>
  #include <asm/cacheflush.h>
  #include <asm/tlbflush.h>
  
  /*
   * Protected counters by write_lock_irq(&tasklist_lock)
   */
  unsigned long total_forks;	/* Handle normal Linux uptimes. */
  int nr_threads; 		/* The idle threads do not count.. */
  
  int max_threads;		/* tunable limit on nr_threads */
  
  DEFINE_PER_CPU(unsigned long, process_counts) = 0;
c59923a15   Christoph Hellwig   [PATCH] remove th...
67
  __cacheline_aligned DEFINE_RWLOCK(tasklist_lock);  /* outer */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  
  int nr_processes(void)
  {
  	int cpu;
  	int total = 0;
  
  	for_each_online_cpu(cpu)
  		total += per_cpu(process_counts, cpu);
  
  	return total;
  }
  
  #ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
  # define alloc_task_struct()	kmem_cache_alloc(task_struct_cachep, GFP_KERNEL)
  # define free_task_struct(tsk)	kmem_cache_free(task_struct_cachep, (tsk))
  static kmem_cache_t *task_struct_cachep;
  #endif
  
  /* SLAB cache for signal_struct structures (tsk->signal) */
6b3934ef5   Oleg Nesterov   [PATCH] copy_proc...
87
  static kmem_cache_t *signal_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  
  /* SLAB cache for sighand_struct structures (tsk->sighand) */
  kmem_cache_t *sighand_cachep;
  
  /* SLAB cache for files_struct structures (tsk->files) */
  kmem_cache_t *files_cachep;
  
  /* SLAB cache for fs_struct structures (tsk->fs) */
  kmem_cache_t *fs_cachep;
  
  /* SLAB cache for vm_area_struct structures */
  kmem_cache_t *vm_area_cachep;
  
  /* SLAB cache for mm_struct structures (tsk->mm) */
  static kmem_cache_t *mm_cachep;
  
  void free_task(struct task_struct *tsk)
  {
  	free_thread_info(tsk->thread_info);
23f78d4a0   Ingo Molnar   [PATCH] pi-futex:...
107
  	rt_mutex_debug_task_free(tsk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
110
  	free_task_struct(tsk);
  }
  EXPORT_SYMBOL(free_task);
158d9ebd1   Andrew Morton   [PATCH] resurrect...
111
  void __put_task_struct(struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
113
114
115
  {
  	WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
  	WARN_ON(atomic_read(&tsk->usage));
  	WARN_ON(tsk == current);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
118
  	security_task_free(tsk);
  	free_uid(tsk->user);
  	put_group_info(tsk->group_info);
35df17c57   Shailabh Nagar   [PATCH] task dela...
119
  	delayacct_tsk_free(tsk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  
  	if (!profile_handoff_task(tsk))
  		free_task(tsk);
  }
  
  void __init fork_init(unsigned long mempages)
  {
  #ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
  #ifndef ARCH_MIN_TASKALIGN
  #define ARCH_MIN_TASKALIGN	L1_CACHE_BYTES
  #endif
  	/* create a slab on which task_structs can be allocated */
  	task_struct_cachep =
  		kmem_cache_create("task_struct", sizeof(struct task_struct),
  			ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL, NULL);
  #endif
  
  	/*
  	 * The default maximum number of threads is set to a safe
  	 * value: the thread structures can take up at most half
  	 * of memory.
  	 */
  	max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
  
  	/*
  	 * we need to allow at least 20 threads to boot a system
  	 */
  	if(max_threads < 20)
  		max_threads = 20;
  
  	init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
  	init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
  	init_task.signal->rlim[RLIMIT_SIGPENDING] =
  		init_task.signal->rlim[RLIMIT_NPROC];
  }
  
  static struct task_struct *dup_task_struct(struct task_struct *orig)
  {
  	struct task_struct *tsk;
  	struct thread_info *ti;
  
  	prepare_to_copy(orig);
  
  	tsk = alloc_task_struct();
  	if (!tsk)
  		return NULL;
  
  	ti = alloc_thread_info(tsk);
  	if (!ti) {
  		free_task_struct(tsk);
  		return NULL;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
  	*tsk = *orig;
  	tsk->thread_info = ti;
10ebffde3   Al Viro   [PATCH] m68k: int...
174
  	setup_thread_stack(tsk, orig);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175

0a4254058   Arjan van de Ven   [PATCH] Add the c...
176
177
178
  #ifdef CONFIG_CC_STACKPROTECTOR
  	tsk->stack_canary = get_random_int();
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
180
  	/* One for us, one for whoever does the "release_task()" (usually parent) */
  	atomic_set(&tsk->usage,2);
4b5d37ac0   Giancarlo Formicuccia   [PATCH] Clear tas...
181
  	atomic_set(&tsk->fs_excl, 0);
6c5c93415   Alexey Dobriyan   [PATCH] ifdef blk...
182
  #ifdef CONFIG_BLK_DEV_IO_TRACE
2056a782f   Jens Axboe   [PATCH] Block que...
183
  	tsk->btrace_seq = 0;
6c5c93415   Alexey Dobriyan   [PATCH] ifdef blk...
184
  #endif
a0aa7f68a   Jens Axboe   [PATCH] Don't inh...
185
  	tsk->splice_pipe = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
187
188
189
  	return tsk;
  }
  
  #ifdef CONFIG_MMU
fd3e42fcc   Hugh Dickins   [PATCH] mm: dup_m...
190
  static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
  {
fd3e42fcc   Hugh Dickins   [PATCH] mm: dup_m...
192
  	struct vm_area_struct *mpnt, *tmp, **pprev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
194
195
196
197
198
  	struct rb_node **rb_link, *rb_parent;
  	int retval;
  	unsigned long charge;
  	struct mempolicy *pol;
  
  	down_write(&oldmm->mmap_sem);
fd3e42fcc   Hugh Dickins   [PATCH] mm: dup_m...
199
  	flush_cache_mm(oldmm);
ad3394517   Ingo Molnar   [PATCH] lockdep: ...
200
201
202
203
  	/*
  	 * Not linked in yet - no deadlock potential:
  	 */
  	down_write_nested(&mm->mmap_sem, SINGLE_DEPTH_NESTING);
7ee782325   Hugh Dickins   [PATCH] mm: dup_m...
204

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
206
207
208
  	mm->locked_vm = 0;
  	mm->mmap = NULL;
  	mm->mmap_cache = NULL;
  	mm->free_area_cache = oldmm->mmap_base;
1363c3cd8   Wolfgang Wander   [PATCH] Avoiding ...
209
  	mm->cached_hole_size = ~0UL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
  	mm->map_count = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
212
213
214
215
  	cpus_clear(mm->cpu_vm_mask);
  	mm->mm_rb = RB_ROOT;
  	rb_link = &mm->mm_rb.rb_node;
  	rb_parent = NULL;
  	pprev = &mm->mmap;
fd3e42fcc   Hugh Dickins   [PATCH] mm: dup_m...
216
  	for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
218
219
  		struct file *file;
  
  		if (mpnt->vm_flags & VM_DONTCOPY) {
3b6bfcdb1   Hugh Dickins   [PATCH] lower VM_...
220
221
  			long pages = vma_pages(mpnt);
  			mm->total_vm -= pages;
ab50b8ed8   Hugh Dickins   [PATCH] mm: vm_st...
222
  			vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
3b6bfcdb1   Hugh Dickins   [PATCH] lower VM_...
223
  								-pages);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
  			continue;
  		}
  		charge = 0;
  		if (mpnt->vm_flags & VM_ACCOUNT) {
  			unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
  			if (security_vm_enough_memory(len))
  				goto fail_nomem;
  			charge = len;
  		}
  		tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
  		if (!tmp)
  			goto fail_nomem;
  		*tmp = *mpnt;
  		pol = mpol_copy(vma_policy(mpnt));
  		retval = PTR_ERR(pol);
  		if (IS_ERR(pol))
  			goto fail_nomem_policy;
  		vma_set_policy(tmp, pol);
  		tmp->vm_flags &= ~VM_LOCKED;
  		tmp->vm_mm = mm;
  		tmp->vm_next = NULL;
  		anon_vma_link(tmp);
  		file = tmp->vm_file;
  		if (file) {
  			struct inode *inode = file->f_dentry->d_inode;
  			get_file(file);
  			if (tmp->vm_flags & VM_DENYWRITE)
  				atomic_dec(&inode->i_writecount);
        
  			/* insert tmp into the share list, just after mpnt */
  			spin_lock(&file->f_mapping->i_mmap_lock);
  			tmp->vm_truncate_count = mpnt->vm_truncate_count;
  			flush_dcache_mmap_lock(file->f_mapping);
  			vma_prio_tree_add(tmp, mpnt);
  			flush_dcache_mmap_unlock(file->f_mapping);
  			spin_unlock(&file->f_mapping->i_mmap_lock);
  		}
  
  		/*
7ee782325   Hugh Dickins   [PATCH] mm: dup_m...
263
  		 * Link in the new vma and copy the page table entries.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264
  		 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
268
269
270
271
272
  		*pprev = tmp;
  		pprev = &tmp->vm_next;
  
  		__vma_link_rb(mm, tmp, rb_link, rb_parent);
  		rb_link = &tmp->vm_rb.rb_right;
  		rb_parent = &tmp->vm_rb;
  
  		mm->map_count++;
0b0db14c5   Hugh Dickins   [PATCH] unpaged: ...
273
  		retval = copy_page_range(mm, oldmm, mpnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
275
276
277
278
279
280
281
  
  		if (tmp->vm_ops && tmp->vm_ops->open)
  			tmp->vm_ops->open(tmp);
  
  		if (retval)
  			goto out;
  	}
  	retval = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
  out:
7ee782325   Hugh Dickins   [PATCH] mm: dup_m...
283
  	up_write(&mm->mmap_sem);
fd3e42fcc   Hugh Dickins   [PATCH] mm: dup_m...
284
  	flush_tlb_mm(oldmm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
  	up_write(&oldmm->mmap_sem);
  	return retval;
  fail_nomem_policy:
  	kmem_cache_free(vm_area_cachep, tmp);
  fail_nomem:
  	retval = -ENOMEM;
  	vm_unacct_memory(charge);
  	goto out;
  }
  
  static inline int mm_alloc_pgd(struct mm_struct * mm)
  {
  	mm->pgd = pgd_alloc(mm);
  	if (unlikely(!mm->pgd))
  		return -ENOMEM;
  	return 0;
  }
  
  static inline void mm_free_pgd(struct mm_struct * mm)
  {
  	pgd_free(mm->pgd);
  }
  #else
  #define dup_mmap(mm, oldmm)	(0)
  #define mm_alloc_pgd(mm)	(0)
  #define mm_free_pgd(mm)
  #endif /* CONFIG_MMU */
  
   __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);
  
  #define allocate_mm()	(kmem_cache_alloc(mm_cachep, SLAB_KERNEL))
  #define free_mm(mm)	(kmem_cache_free(mm_cachep, (mm)))
  
  #include <linux/init_task.h>
  
  static struct mm_struct * mm_init(struct mm_struct * mm)
  {
  	atomic_set(&mm->mm_users, 1);
  	atomic_set(&mm->mm_count, 1);
  	init_rwsem(&mm->mmap_sem);
  	INIT_LIST_HEAD(&mm->mmlist);
  	mm->core_waiters = 0;
  	mm->nr_ptes = 0;
4294621f4   Hugh Dickins   [PATCH] mm: rss =...
328
  	set_mm_counter(mm, file_rss, 0);
404351e67   Hugh Dickins   [PATCH] mm: mm_in...
329
  	set_mm_counter(mm, anon_rss, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
330
331
332
  	spin_lock_init(&mm->page_table_lock);
  	rwlock_init(&mm->ioctx_list_lock);
  	mm->ioctx_list = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
333
  	mm->free_area_cache = TASK_UNMAPPED_BASE;
1363c3cd8   Wolfgang Wander   [PATCH] Avoiding ...
334
  	mm->cached_hole_size = ~0UL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
  
  	if (likely(!mm_alloc_pgd(mm))) {
  		mm->def_flags = 0;
  		return mm;
  	}
  	free_mm(mm);
  	return NULL;
  }
  
  /*
   * Allocate and initialize an mm_struct.
   */
  struct mm_struct * mm_alloc(void)
  {
  	struct mm_struct * mm;
  
  	mm = allocate_mm();
  	if (mm) {
  		memset(mm, 0, sizeof(*mm));
  		mm = mm_init(mm);
  	}
  	return mm;
  }
  
  /*
   * Called when the last reference to the mm
   * is dropped: either by a lazy thread or by
   * mmput. Free the page directory and the mm.
   */
  void fastcall __mmdrop(struct mm_struct *mm)
  {
  	BUG_ON(mm == &init_mm);
  	mm_free_pgd(mm);
  	destroy_context(mm);
  	free_mm(mm);
  }
  
  /*
   * Decrement the use count and release all resources for an mm.
   */
  void mmput(struct mm_struct *mm)
  {
0ae26f1b3   Andrew Morton   [PATCH] mmput() m...
377
  	might_sleep();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
  	if (atomic_dec_and_test(&mm->mm_users)) {
  		exit_aio(mm);
  		exit_mmap(mm);
  		if (!list_empty(&mm->mmlist)) {
  			spin_lock(&mmlist_lock);
  			list_del(&mm->mmlist);
  			spin_unlock(&mmlist_lock);
  		}
  		put_swap_token(mm);
  		mmdrop(mm);
  	}
  }
  EXPORT_SYMBOL_GPL(mmput);
  
  /**
   * get_task_mm - acquire a reference to the task's mm
   *
   * Returns %NULL if the task has no mm.  Checks PF_BORROWED_MM (meaning
   * this kernel workthread has transiently adopted a user mm with use_mm,
   * to do its AIO) is not set and if so returns a reference to it, after
   * bumping up the use count.  User must release the mm via mmput()
   * after use.  Typically used by /proc and ptrace.
   */
  struct mm_struct *get_task_mm(struct task_struct *task)
  {
  	struct mm_struct *mm;
  
  	task_lock(task);
  	mm = task->mm;
  	if (mm) {
  		if (task->flags & PF_BORROWED_MM)
  			mm = NULL;
  		else
  			atomic_inc(&mm->mm_users);
  	}
  	task_unlock(task);
  	return mm;
  }
  EXPORT_SYMBOL_GPL(get_task_mm);
  
  /* Please note the differences between mmput and mm_release.
   * mmput is called whenever we stop holding onto a mm_struct,
   * error success whatever.
   *
   * mm_release is called after a mm_struct has been removed
   * from the current process.
   *
   * This difference is important for error handling, when we
   * only half set up a mm_struct for a new process and need to restore
   * the old one.  Because we mmput the new mm_struct before
   * restoring the old one. . .
   * Eric Biederman 10 January 1998
   */
  void mm_release(struct task_struct *tsk, struct mm_struct *mm)
  {
  	struct completion *vfork_done = tsk->vfork_done;
  
  	/* Get rid of any cached register state */
  	deactivate_mm(tsk, mm);
  
  	/* notify parent sleeping on vfork() */
  	if (vfork_done) {
  		tsk->vfork_done = NULL;
  		complete(vfork_done);
  	}
  	if (tsk->clear_child_tid && atomic_read(&mm->mm_users) > 1) {
  		u32 __user * tidptr = tsk->clear_child_tid;
  		tsk->clear_child_tid = NULL;
  
  		/*
  		 * We don't check the error code - if userspace has
  		 * not set up a proper pointer then tough luck.
  		 */
  		put_user(0, tidptr);
  		sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
  	}
  }
a0a7ec308   JANAK DESAI   [PATCH] unshare s...
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
  /*
   * Allocate a new mm structure and copy contents from the
   * mm structure of the passed in task structure.
   */
  static struct mm_struct *dup_mm(struct task_struct *tsk)
  {
  	struct mm_struct *mm, *oldmm = current->mm;
  	int err;
  
  	if (!oldmm)
  		return NULL;
  
  	mm = allocate_mm();
  	if (!mm)
  		goto fail_nomem;
  
  	memcpy(mm, oldmm, sizeof(*mm));
  
  	if (!mm_init(mm))
  		goto fail_nomem;
  
  	if (init_new_context(tsk, mm))
  		goto fail_nocontext;
  
  	err = dup_mmap(mm, oldmm);
  	if (err)
  		goto free_pt;
  
  	mm->hiwater_rss = get_mm_rss(mm);
  	mm->hiwater_vm = mm->total_vm;
  
  	return mm;
  
  free_pt:
  	mmput(mm);
  
  fail_nomem:
  	return NULL;
  
  fail_nocontext:
  	/*
  	 * If init_new_context() failed, we cannot use mmput() to free the mm
  	 * because it calls destroy_context()
  	 */
  	mm_free_pgd(mm);
  	free_mm(mm);
  	return NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
  static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
  {
  	struct mm_struct * mm, *oldmm;
  	int retval;
  
  	tsk->min_flt = tsk->maj_flt = 0;
  	tsk->nvcsw = tsk->nivcsw = 0;
  
  	tsk->mm = NULL;
  	tsk->active_mm = NULL;
  
  	/*
  	 * Are we cloning a kernel thread?
  	 *
  	 * We need to steal a active VM for that..
  	 */
  	oldmm = current->mm;
  	if (!oldmm)
  		return 0;
  
  	if (clone_flags & CLONE_VM) {
  		atomic_inc(&oldmm->mm_users);
  		mm = oldmm;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
528
529
  		goto good_mm;
  	}
  
  	retval = -ENOMEM;
a0a7ec308   JANAK DESAI   [PATCH] unshare s...
530
  	mm = dup_mm(tsk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
532
  	if (!mm)
  		goto fail_nomem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
533
534
535
536
  good_mm:
  	tsk->mm = mm;
  	tsk->active_mm = mm;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537
538
  fail_nomem:
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
  }
  
  static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old)
  {
  	struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
  	/* We don't need to lock fs - think why ;-) */
  	if (fs) {
  		atomic_set(&fs->count, 1);
  		rwlock_init(&fs->lock);
  		fs->umask = old->umask;
  		read_lock(&old->lock);
  		fs->rootmnt = mntget(old->rootmnt);
  		fs->root = dget(old->root);
  		fs->pwdmnt = mntget(old->pwdmnt);
  		fs->pwd = dget(old->pwd);
  		if (old->altroot) {
  			fs->altrootmnt = mntget(old->altrootmnt);
  			fs->altroot = dget(old->altroot);
  		} else {
  			fs->altrootmnt = NULL;
  			fs->altroot = NULL;
  		}
  		read_unlock(&old->lock);
  	}
  	return fs;
  }
  
  struct fs_struct *copy_fs_struct(struct fs_struct *old)
  {
  	return __copy_fs_struct(old);
  }
  
  EXPORT_SYMBOL_GPL(copy_fs_struct);
  
  static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk)
  {
  	if (clone_flags & CLONE_FS) {
  		atomic_inc(&current->fs->count);
  		return 0;
  	}
  	tsk->fs = __copy_fs_struct(current->fs);
  	if (!tsk->fs)
  		return -ENOMEM;
  	return 0;
  }
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
584
  static int count_open_files(struct fdtable *fdt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
585
  {
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
586
  	int size = fdt->max_fdset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
588
589
590
  	int i;
  
  	/* Find the last open fd */
  	for (i = size/(8*sizeof(long)); i > 0; ) {
badf16621   Dipankar Sarma   [PATCH] files: br...
591
  		if (fdt->open_fds->fds_bits[--i])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
592
593
594
595
596
  			break;
  	}
  	i = (i+1) * 8 * sizeof(long);
  	return i;
  }
badf16621   Dipankar Sarma   [PATCH] files: br...
597
598
599
600
601
602
603
604
605
606
607
608
  static struct files_struct *alloc_files(void)
  {
  	struct files_struct *newf;
  	struct fdtable *fdt;
  
  	newf = kmem_cache_alloc(files_cachep, SLAB_KERNEL);
  	if (!newf)
  		goto out;
  
  	atomic_set(&newf->count, 1);
  
  	spin_lock_init(&newf->file_lock);
0c9e63fd3   Eric Dumazet   [PATCH] Shrinks s...
609
  	newf->next_fd = 0;
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
610
  	fdt = &newf->fdtab;
badf16621   Dipankar Sarma   [PATCH] files: br...
611
  	fdt->max_fds = NR_OPEN_DEFAULT;
0c9e63fd3   Eric Dumazet   [PATCH] Shrinks s...
612
613
614
  	fdt->max_fdset = EMBEDDED_FD_SET_SIZE;
  	fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init;
  	fdt->open_fds = (fd_set *)&newf->open_fds_init;
badf16621   Dipankar Sarma   [PATCH] files: br...
615
  	fdt->fd = &newf->fd_array[0];
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
616
617
618
619
  	INIT_RCU_HEAD(&fdt->rcu);
  	fdt->free_files = NULL;
  	fdt->next = NULL;
  	rcu_assign_pointer(newf->fdt, fdt);
badf16621   Dipankar Sarma   [PATCH] files: br...
620
621
622
  out:
  	return newf;
  }
a016f3389   JANAK DESAI   [PATCH] unshare s...
623
624
625
  /*
   * Allocate a new files structure and copy contents from the
   * passed in files structure.
6e6672604   Prasanna Meda   [PATCH] dup fd er...
626
   * errorp will be valid only when the returned files_struct is NULL.
a016f3389   JANAK DESAI   [PATCH] unshare s...
627
628
   */
  static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
629
  {
a016f3389   JANAK DESAI   [PATCH] unshare s...
630
  	struct files_struct *newf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631
  	struct file **old_fds, **new_fds;
a016f3389   JANAK DESAI   [PATCH] unshare s...
632
  	int open_files, size, i, expand;
badf16621   Dipankar Sarma   [PATCH] files: br...
633
  	struct fdtable *old_fdt, *new_fdt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
634

6e6672604   Prasanna Meda   [PATCH] dup fd er...
635
  	*errorp = -ENOMEM;
badf16621   Dipankar Sarma   [PATCH] files: br...
636
637
  	newf = alloc_files();
  	if (!newf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
639
  	spin_lock(&oldf->file_lock);
badf16621   Dipankar Sarma   [PATCH] files: br...
640
641
642
  	old_fdt = files_fdtable(oldf);
  	new_fdt = files_fdtable(newf);
  	size = old_fdt->max_fdset;
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
643
  	open_files = count_open_files(old_fdt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
645
646
647
648
649
  	expand = 0;
  
  	/*
  	 * Check whether we need to allocate a larger fd array or fd set.
  	 * Note: we're not a clone task, so the open count won't  change.
  	 */
badf16621   Dipankar Sarma   [PATCH] files: br...
650
651
  	if (open_files > new_fdt->max_fdset) {
  		new_fdt->max_fdset = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
653
  		expand = 1;
  	}
badf16621   Dipankar Sarma   [PATCH] files: br...
654
655
  	if (open_files > new_fdt->max_fds) {
  		new_fdt->max_fds = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
657
658
659
660
661
662
  		expand = 1;
  	}
  
  	/* if the old fdset gets grown now, we'll only copy up to "size" fds */
  	if (expand) {
  		spin_unlock(&oldf->file_lock);
  		spin_lock(&newf->file_lock);
a016f3389   JANAK DESAI   [PATCH] unshare s...
663
  		*errorp = expand_files(newf, open_files-1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
664
  		spin_unlock(&newf->file_lock);
a016f3389   JANAK DESAI   [PATCH] unshare s...
665
  		if (*errorp < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666
  			goto out_release;
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
667
668
669
670
671
672
  		new_fdt = files_fdtable(newf);
  		/*
  		 * Reacquire the oldf lock and a pointer to its fd table
  		 * who knows it may have a new bigger fd table. We need
  		 * the latest pointer.
  		 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
673
  		spin_lock(&oldf->file_lock);
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
674
  		old_fdt = files_fdtable(oldf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
675
  	}
badf16621   Dipankar Sarma   [PATCH] files: br...
676
677
  	old_fds = old_fdt->fd;
  	new_fds = new_fdt->fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
678

badf16621   Dipankar Sarma   [PATCH] files: br...
679
680
  	memcpy(new_fdt->open_fds->fds_bits, old_fdt->open_fds->fds_bits, open_files/8);
  	memcpy(new_fdt->close_on_exec->fds_bits, old_fdt->close_on_exec->fds_bits, open_files/8);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
682
683
684
685
686
687
688
689
690
691
692
  
  	for (i = open_files; i != 0; i--) {
  		struct file *f = *old_fds++;
  		if (f) {
  			get_file(f);
  		} else {
  			/*
  			 * The fd may be claimed in the fd bitmap but not yet
  			 * instantiated in the files array if a sibling thread
  			 * is partway through open().  So make sure that this
  			 * fd is available to the new process.
  			 */
badf16621   Dipankar Sarma   [PATCH] files: br...
693
  			FD_CLR(open_files - i, new_fdt->open_fds);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
694
  		}
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
695
  		rcu_assign_pointer(*new_fds++, f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
696
697
698
699
  	}
  	spin_unlock(&oldf->file_lock);
  
  	/* compute the remainder to be cleared */
badf16621   Dipankar Sarma   [PATCH] files: br...
700
  	size = (new_fdt->max_fds - open_files) * sizeof(struct file *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
701
702
703
  
  	/* This is long word aligned thus could use a optimized version */ 
  	memset(new_fds, 0, size); 
badf16621   Dipankar Sarma   [PATCH] files: br...
704
705
  	if (new_fdt->max_fdset > open_files) {
  		int left = (new_fdt->max_fdset-open_files)/8;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
706
  		int start = open_files / (8 * sizeof(unsigned long));
badf16621   Dipankar Sarma   [PATCH] files: br...
707
708
  		memset(&new_fdt->open_fds->fds_bits[start], 0, left);
  		memset(&new_fdt->close_on_exec->fds_bits[start], 0, left);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
709
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710
  out:
a016f3389   JANAK DESAI   [PATCH] unshare s...
711
  	return newf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
712
713
  
  out_release:
badf16621   Dipankar Sarma   [PATCH] files: br...
714
715
716
  	free_fdset (new_fdt->close_on_exec, new_fdt->max_fdset);
  	free_fdset (new_fdt->open_fds, new_fdt->max_fdset);
  	free_fd_array(new_fdt->fd, new_fdt->max_fds);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
717
  	kmem_cache_free(files_cachep, newf);
428622986   Kirill Korotaev   [PATCH] wrong err...
718
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
719
  }
a016f3389   JANAK DESAI   [PATCH] unshare s...
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
  {
  	struct files_struct *oldf, *newf;
  	int error = 0;
  
  	/*
  	 * A background process may not have any files ...
  	 */
  	oldf = current->files;
  	if (!oldf)
  		goto out;
  
  	if (clone_flags & CLONE_FILES) {
  		atomic_inc(&oldf->count);
  		goto out;
  	}
  
  	/*
  	 * Note: we may be using current for both targets (See exec.c)
  	 * This works because we cache current->files (old) as oldf. Don't
  	 * break this.
  	 */
  	tsk->files = NULL;
a016f3389   JANAK DESAI   [PATCH] unshare s...
743
744
745
746
747
748
749
750
751
  	newf = dup_fd(oldf, &error);
  	if (!newf)
  		goto out;
  
  	tsk->files = newf;
  	error = 0;
  out:
  	return error;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
753
754
755
756
757
758
759
760
761
  /*
   *	Helper to unshare the files of the current task.
   *	We don't want to expose copy_files internals to
   *	the exec layer of the kernel.
   */
  
  int unshare_files(void)
  {
  	struct files_struct *files  = current->files;
  	int rc;
910dea7fd   Eric Sesterhenn   BUG_ON() Conversi...
762
  	BUG_ON(!files);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
  
  	/* This can race but the race causes us to copy when we don't
  	   need to and drop the copy */
  	if(atomic_read(&files->count) == 1)
  	{
  		atomic_inc(&files->count);
  		return 0;
  	}
  	rc = copy_files(0, current);
  	if(rc)
  		current->files = files;
  	return rc;
  }
  
  EXPORT_SYMBOL(unshare_files);
  
  static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
  {
  	struct sighand_struct *sig;
  
  	if (clone_flags & (CLONE_SIGHAND | CLONE_THREAD)) {
  		atomic_inc(&current->sighand->count);
  		return 0;
  	}
  	sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
e56d09031   Ingo Molnar   [PATCH] RCU signa...
788
  	rcu_assign_pointer(tsk->sighand, sig);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
789
790
  	if (!sig)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
791
792
793
794
  	atomic_set(&sig->count, 1);
  	memcpy(sig->action, current->sighand->action, sizeof(sig->action));
  	return 0;
  }
a7e5328a0   Oleg Nesterov   [PATCH] cleanup _...
795
  void __cleanup_sighand(struct sighand_struct *sighand)
c81addc9d   Oleg Nesterov   [PATCH] rename __...
796
  {
c81addc9d   Oleg Nesterov   [PATCH] rename __...
797
798
799
  	if (atomic_dec_and_test(&sighand->count))
  		kmem_cache_free(sighand_cachep, sighand);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800
801
802
803
804
805
806
807
  static inline int copy_signal(unsigned long clone_flags, struct task_struct * tsk)
  {
  	struct signal_struct *sig;
  	int ret;
  
  	if (clone_flags & CLONE_THREAD) {
  		atomic_inc(&current->signal->count);
  		atomic_inc(&current->signal->live);
ad4ecbcba   Shailabh Nagar   [PATCH] delay acc...
808
  		taskstats_tgid_alloc(current->signal);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
  		return 0;
  	}
  	sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
  	tsk->signal = sig;
  	if (!sig)
  		return -ENOMEM;
  
  	ret = copy_thread_group_keys(tsk);
  	if (ret < 0) {
  		kmem_cache_free(signal_cachep, sig);
  		return ret;
  	}
  
  	atomic_set(&sig->count, 1);
  	atomic_set(&sig->live, 1);
  	init_waitqueue_head(&sig->wait_chldexit);
  	sig->flags = 0;
  	sig->group_exit_code = 0;
  	sig->group_exit_task = NULL;
  	sig->group_stop_count = 0;
  	sig->curr_target = NULL;
  	init_sigpending(&sig->shared_pending);
  	INIT_LIST_HEAD(&sig->posix_timers);
7978672c4   George Anzinger   [PATCH] hrtimers:...
832
  	hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_REL);
2ff678b8d   Thomas Gleixner   [PATCH] hrtimer: ...
833
  	sig->it_real_incr.tv64 = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
834
  	sig->real_timer.function = it_real_fn;
05cfb614d   Roman Zippel   [PATCH] hrtimers:...
835
  	sig->tsk = tsk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
836
837
838
839
840
  
  	sig->it_virt_expires = cputime_zero;
  	sig->it_virt_incr = cputime_zero;
  	sig->it_prof_expires = cputime_zero;
  	sig->it_prof_incr = cputime_zero;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841
842
843
844
845
846
847
848
849
850
  	sig->leader = 0;	/* session leadership doesn't inherit */
  	sig->tty_old_pgrp = 0;
  
  	sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
  	sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
  	sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
  	sig->sched_time = 0;
  	INIT_LIST_HEAD(&sig->cpu_timers[0]);
  	INIT_LIST_HEAD(&sig->cpu_timers[1]);
  	INIT_LIST_HEAD(&sig->cpu_timers[2]);
ad4ecbcba   Shailabh Nagar   [PATCH] delay acc...
851
  	taskstats_tgid_init(sig);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
852
853
854
855
856
857
858
859
860
861
862
863
864
  
  	task_lock(current->group_leader);
  	memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
  	task_unlock(current->group_leader);
  
  	if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
  		/*
  		 * New sole thread in the process gets an expiry time
  		 * of the whole CPU time limit.
  		 */
  		tsk->it_prof_expires =
  			secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
  	}
0e4648141   KaiGai Kohei   [PATCH] pacct: ad...
865
  	acct_init_pacct(&sig->pacct);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
866
867
868
  
  	return 0;
  }
6b3934ef5   Oleg Nesterov   [PATCH] copy_proc...
869
870
871
  void __cleanup_signal(struct signal_struct *sig)
  {
  	exit_thread_group_keys(sig);
ad4ecbcba   Shailabh Nagar   [PATCH] delay acc...
872
  	taskstats_tgid_free(sig);
6b3934ef5   Oleg Nesterov   [PATCH] copy_proc...
873
874
875
876
877
878
879
880
881
882
883
884
  	kmem_cache_free(signal_cachep, sig);
  }
  
  static inline void cleanup_signal(struct task_struct *tsk)
  {
  	struct signal_struct *sig = tsk->signal;
  
  	atomic_dec(&sig->live);
  
  	if (atomic_dec_and_test(&sig->count))
  		__cleanup_signal(sig);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
885
886
887
  static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
  {
  	unsigned long new_flags = p->flags;
d1209d049   Alan Stern   [PATCH] Threads s...
888
  	new_flags &= ~(PF_SUPERPRIV | PF_NOFREEZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
889
890
891
892
893
894
895
896
897
898
899
900
  	new_flags |= PF_FORKNOEXEC;
  	if (!(clone_flags & CLONE_PTRACE))
  		p->ptrace = 0;
  	p->flags = new_flags;
  }
  
  asmlinkage long sys_set_tid_address(int __user *tidptr)
  {
  	current->clear_child_tid = tidptr;
  
  	return current->pid;
  }
23f78d4a0   Ingo Molnar   [PATCH] pi-futex:...
901
902
903
904
905
906
  static inline void rt_mutex_init_task(struct task_struct *p)
  {
  #ifdef CONFIG_RT_MUTEXES
  	spin_lock_init(&p->pi_lock);
  	plist_head_init(&p->pi_waiters, &p->pi_lock);
  	p->pi_blocked_on = NULL;
23f78d4a0   Ingo Molnar   [PATCH] pi-futex:...
907
908
  #endif
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
909
910
911
912
913
914
915
916
  /*
   * This creates a new process as a copy of the old one,
   * but does not actually start it yet.
   *
   * It copies the registers, and all the appropriate
   * parts of the process environment (as per the clone
   * flags). The actual kick-off is left to the caller.
   */
36c8b5868   Ingo Molnar   [PATCH] sched: cl...
917
918
919
920
921
922
923
  static struct task_struct *copy_process(unsigned long clone_flags,
  					unsigned long stack_start,
  					struct pt_regs *regs,
  					unsigned long stack_size,
  					int __user *parent_tidptr,
  					int __user *child_tidptr,
  					int pid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
  {
  	int retval;
  	struct task_struct *p = NULL;
  
  	if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
  		return ERR_PTR(-EINVAL);
  
  	/*
  	 * Thread groups must share signals as well, and detached threads
  	 * can only be started up within the thread group.
  	 */
  	if ((clone_flags & CLONE_THREAD) && !(clone_flags & CLONE_SIGHAND))
  		return ERR_PTR(-EINVAL);
  
  	/*
  	 * Shared signal handlers imply shared VM. By way of the above,
  	 * thread groups also imply shared VM. Blocking this case allows
  	 * for various simplifications in other code.
  	 */
  	if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM))
  		return ERR_PTR(-EINVAL);
  
  	retval = security_task_create(clone_flags);
  	if (retval)
  		goto fork_out;
  
  	retval = -ENOMEM;
  	p = dup_task_struct(current);
  	if (!p)
  		goto fork_out;
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
954
955
956
957
  #ifdef CONFIG_TRACE_IRQFLAGS
  	DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
  	DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
  	retval = -EAGAIN;
  	if (atomic_read(&p->user->processes) >=
  			p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
  		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
  				p->user != &root_user)
  			goto bad_fork_free;
  	}
  
  	atomic_inc(&p->user->__count);
  	atomic_inc(&p->user->processes);
  	get_group_info(p->group_info);
  
  	/*
  	 * If multiple threads are within copy_process(), then this check
  	 * triggers too late. This doesn't hurt, the check is only there
  	 * to stop root fork bombs.
  	 */
  	if (nr_threads >= max_threads)
  		goto bad_fork_cleanup_count;
a1261f546   Al Viro   [PATCH] m68k: int...
977
  	if (!try_module_get(task_thread_info(p)->exec_domain->module))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
978
979
980
981
982
983
  		goto bad_fork_cleanup_count;
  
  	if (p->binfmt && !try_module_get(p->binfmt->module))
  		goto bad_fork_cleanup_put_domain;
  
  	p->did_exec = 0;
ca74e92b4   Shailabh Nagar   [PATCH] per-task-...
984
  	delayacct_tsk_init(p);	/* Must remain after dup_task_struct() */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
985
986
987
988
989
  	copy_flags(clone_flags, p);
  	p->pid = pid;
  	retval = -EFAULT;
  	if (clone_flags & CLONE_PARENT_SETTID)
  		if (put_user(p->pid, parent_tidptr))
35df17c57   Shailabh Nagar   [PATCH] task dela...
990
  			goto bad_fork_cleanup_delays_binfmt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
991

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
992
993
994
995
  	INIT_LIST_HEAD(&p->children);
  	INIT_LIST_HEAD(&p->sibling);
  	p->vfork_done = NULL;
  	spin_lock_init(&p->alloc_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
  
  	clear_tsk_thread_flag(p, TIF_SIGPENDING);
  	init_sigpending(&p->pending);
  
  	p->utime = cputime_zero;
  	p->stime = cputime_zero;
   	p->sched_time = 0;
  	p->rchar = 0;		/* I/O counter: bytes read */
  	p->wchar = 0;		/* I/O counter: bytes written */
  	p->syscr = 0;		/* I/O counter: read syscalls */
  	p->syscw = 0;		/* I/O counter: write syscalls */
  	acct_clear_integrals(p);
  
   	p->it_virt_expires = cputime_zero;
  	p->it_prof_expires = cputime_zero;
   	p->it_sched_expires = 0;
   	INIT_LIST_HEAD(&p->cpu_timers[0]);
   	INIT_LIST_HEAD(&p->cpu_timers[1]);
   	INIT_LIST_HEAD(&p->cpu_timers[2]);
  
  	p->lock_depth = -1;		/* -1 = no lock */
  	do_posix_clock_monotonic_gettime(&p->start_time);
  	p->security = NULL;
  	p->io_context = NULL;
  	p->io_wait = NULL;
  	p->audit_context = NULL;
b4b264184   Paul Jackson   [PATCH] cpuset: f...
1022
  	cpuset_fork(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1023
1024
1025
1026
1027
  #ifdef CONFIG_NUMA
   	p->mempolicy = mpol_copy(p->mempolicy);
   	if (IS_ERR(p->mempolicy)) {
   		retval = PTR_ERR(p->mempolicy);
   		p->mempolicy = NULL;
b4b264184   Paul Jackson   [PATCH] cpuset: f...
1028
   		goto bad_fork_cleanup_cpuset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1029
   	}
c61afb181   Paul Jackson   [PATCH] cpuset me...
1030
  	mpol_fix_fork_child_flag(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1031
  #endif
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
1032
1033
  #ifdef CONFIG_TRACE_IRQFLAGS
  	p->irq_events = 0;
b36e4758d   Russell King   [ARM] Fix kernel/...
1034
1035
1036
  #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
  	p->hardirqs_enabled = 1;
  #else
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
1037
  	p->hardirqs_enabled = 0;
b36e4758d   Russell King   [ARM] Fix kernel/...
1038
  #endif
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
  	p->hardirq_enable_ip = 0;
  	p->hardirq_enable_event = 0;
  	p->hardirq_disable_ip = _THIS_IP_;
  	p->hardirq_disable_event = 0;
  	p->softirqs_enabled = 1;
  	p->softirq_enable_ip = _THIS_IP_;
  	p->softirq_enable_event = 0;
  	p->softirq_disable_ip = 0;
  	p->softirq_disable_event = 0;
  	p->hardirq_context = 0;
  	p->softirq_context = 0;
  #endif
fbb9ce953   Ingo Molnar   [PATCH] lockdep: ...
1051
1052
1053
1054
1055
  #ifdef CONFIG_LOCKDEP
  	p->lockdep_depth = 0; /* no locks held yet */
  	p->curr_chain_key = 0;
  	p->lockdep_recursion = 0;
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1056

23f78d4a0   Ingo Molnar   [PATCH] pi-futex:...
1057
  	rt_mutex_init_task(p);
408894ee4   Ingo Molnar   [PATCH] mutex sub...
1058
1059
1060
  #ifdef CONFIG_DEBUG_MUTEXES
  	p->blocked_on = NULL; /* not blocked yet */
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
  	p->tgid = p->pid;
  	if (clone_flags & CLONE_THREAD)
  		p->tgid = current->tgid;
  
  	if ((retval = security_task_alloc(p)))
  		goto bad_fork_cleanup_policy;
  	if ((retval = audit_alloc(p)))
  		goto bad_fork_cleanup_security;
  	/* copy all the process information */
  	if ((retval = copy_semundo(clone_flags, p)))
  		goto bad_fork_cleanup_audit;
  	if ((retval = copy_files(clone_flags, p)))
  		goto bad_fork_cleanup_semundo;
  	if ((retval = copy_fs(clone_flags, p)))
  		goto bad_fork_cleanup_files;
  	if ((retval = copy_sighand(clone_flags, p)))
  		goto bad_fork_cleanup_fs;
  	if ((retval = copy_signal(clone_flags, p)))
  		goto bad_fork_cleanup_sighand;
  	if ((retval = copy_mm(clone_flags, p)))
  		goto bad_fork_cleanup_signal;
  	if ((retval = copy_keys(clone_flags, p)))
  		goto bad_fork_cleanup_mm;
ab516013a   Serge E. Hallyn   [PATCH] namespace...
1084
  	if ((retval = copy_namespaces(clone_flags, p)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1085
1086
1087
  		goto bad_fork_cleanup_keys;
  	retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
  	if (retval)
1651e14e2   Serge E. Hallyn   [PATCH] namespace...
1088
  		goto bad_fork_cleanup_namespaces;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1089
1090
1091
1092
1093
1094
  
  	p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
  	/*
  	 * Clear TID on mm_release()?
  	 */
  	p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL;
8f17d3a50   Ingo Molnar   [PATCH] lightweig...
1095
1096
1097
1098
  	p->robust_list = NULL;
  #ifdef CONFIG_COMPAT
  	p->compat_robust_list = NULL;
  #endif
c87e2837b   Ingo Molnar   [PATCH] pi-futex:...
1099
1100
  	INIT_LIST_HEAD(&p->pi_state_list);
  	p->pi_state_cache = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1101
  	/*
f9a3879ab   GOTO Masanori   [PATCH] Fix sigal...
1102
1103
1104
1105
1106
1107
  	 * sigaltstack should be cleared when sharing the same VM
  	 */
  	if ((clone_flags & (CLONE_VM|CLONE_VFORK)) == CLONE_VM)
  		p->sas_ss_sp = p->sas_ss_size = 0;
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1108
1109
1110
1111
  	 * Syscall tracing should be turned off in the child regardless
  	 * of CLONE_PTRACE.
  	 */
  	clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);
ed75e8d58   Laurent Vivier   [PATCH] UML Suppo...
1112
1113
1114
  #ifdef TIF_SYSCALL_EMU
  	clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1115
1116
1117
  
  	/* Our parent execution domain becomes current domain
  	   These must match for thread signalling to apply */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1118
1119
1120
1121
1122
1123
  	p->parent_exec_id = p->self_exec_id;
  
  	/* ok, now we should be set up.. */
  	p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL);
  	p->pdeath_signal = 0;
  	p->exit_state = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1124
1125
1126
1127
1128
  	/*
  	 * Ok, make it visible to the rest of the system.
  	 * We dont wake it up yet.
  	 */
  	p->group_leader = p;
47e65328a   Oleg Nesterov   [PATCH] pids: kil...
1129
  	INIT_LIST_HEAD(&p->thread_group);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1130
1131
  	INIT_LIST_HEAD(&p->ptrace_children);
  	INIT_LIST_HEAD(&p->ptrace_list);
476d139c2   Nick Piggin   [PATCH] sched: co...
1132
1133
  	/* Perform scheduler related setup. Assign this task to a CPU. */
  	sched_fork(p, clone_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1134
1135
  	/* Need tasklist lock for parent etc handling! */
  	write_lock_irq(&tasklist_lock);
5b160f5ec   Oleg Nesterov   [PATCH] copy_proc...
1136
1137
  	/* for sys_ioprio_set(IOPRIO_WHO_PGRP) */
  	p->ioprio = current->ioprio;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1138
  	/*
476d139c2   Nick Piggin   [PATCH] sched: co...
1139
1140
1141
1142
1143
1144
1145
  	 * The task hasn't been attached yet, so its cpus_allowed mask will
  	 * not be changed, nor will its assigned CPU.
  	 *
  	 * The cpus_allowed mask of the parent may have changed after it was
  	 * copied first time - so re-copy it here, then check the child's CPU
  	 * to ensure it is on a valid CPU (and if not, just force it back to
  	 * parent's CPU). This avoids alot of nasty races.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1146
1147
  	 */
  	p->cpus_allowed = current->cpus_allowed;
26ff6ad97   Srivatsa Vaddagiri   [PATCH] CPU hotpl...
1148
1149
  	if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed) ||
  			!cpu_online(task_cpu(p))))
476d139c2   Nick Piggin   [PATCH] sched: co...
1150
  		set_task_cpu(p, smp_processor_id());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1151

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1152
1153
1154
1155
1156
1157
  	/* CLONE_PARENT re-uses the old parent */
  	if (clone_flags & (CLONE_PARENT|CLONE_THREAD))
  		p->real_parent = current->real_parent;
  	else
  		p->real_parent = current;
  	p->parent = p->real_parent;
3f17da699   Oleg Nesterov   [PATCH] fix kill_...
1158
  	spin_lock(&current->sighand->siglock);
4a2c7a783   Oleg Nesterov   [PATCH] make fork...
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
  
  	/*
  	 * Process group and session signals need to be delivered to just the
  	 * parent before the fork or both the parent and the child after the
  	 * fork. Restart if a signal comes in before we add the new process to
  	 * it's process group.
  	 * A fatal signal pending means that current will exit, so the new
  	 * thread can't slip out of an OOM kill (or normal SIGKILL).
   	 */
   	recalc_sigpending();
  	if (signal_pending(current)) {
  		spin_unlock(&current->sighand->siglock);
  		write_unlock_irq(&tasklist_lock);
  		retval = -ERESTARTNOINTR;
1651e14e2   Serge E. Hallyn   [PATCH] namespace...
1173
  		goto bad_fork_cleanup_namespaces;
4a2c7a783   Oleg Nesterov   [PATCH] make fork...
1174
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1175
  	if (clone_flags & CLONE_THREAD) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1176
  		p->group_leader = current->group_leader;
47e65328a   Oleg Nesterov   [PATCH] pids: kil...
1177
  		list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1178

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
  		if (!cputime_eq(current->signal->it_virt_expires,
  				cputime_zero) ||
  		    !cputime_eq(current->signal->it_prof_expires,
  				cputime_zero) ||
  		    current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY ||
  		    !list_empty(&current->signal->cpu_timers[0]) ||
  		    !list_empty(&current->signal->cpu_timers[1]) ||
  		    !list_empty(&current->signal->cpu_timers[2])) {
  			/*
  			 * Have child wake up on its first tick to check
  			 * for process CPU timers.
  			 */
  			p->it_prof_expires = jiffies_to_cputime(1);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1193
  	}
73b9ebfe1   Oleg Nesterov   [PATCH] pidhash: ...
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
  	if (likely(p->pid)) {
  		add_parent(p);
  		if (unlikely(p->ptrace & PT_PTRACED))
  			__ptrace_link(p, current->parent);
  
  		if (thread_group_leader(p)) {
  			p->signal->tty = current->signal->tty;
  			p->signal->pgrp = process_group(current);
  			p->signal->session = current->signal->session;
  			attach_pid(p, PIDTYPE_PGID, process_group(p));
  			attach_pid(p, PIDTYPE_SID, p->signal->session);
5e85d4abe   Eric W. Biederman   [PATCH] task: Mak...
1205
  			list_add_tail_rcu(&p->tasks, &init_task.tasks);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1206
  			__get_cpu_var(process_counts)++;
73b9ebfe1   Oleg Nesterov   [PATCH] pidhash: ...
1207
  		}
73b9ebfe1   Oleg Nesterov   [PATCH] pidhash: ...
1208
1209
  		attach_pid(p, PIDTYPE_PID, p->pid);
  		nr_threads++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1210
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1211
  	total_forks++;
3f17da699   Oleg Nesterov   [PATCH] fix kill_...
1212
  	spin_unlock(&current->sighand->siglock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1213
  	write_unlock_irq(&tasklist_lock);
c13cf856c   Andrew Morton   [PATCH] fork.c: p...
1214
  	proc_fork_connector(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1215
  	return p;
ab516013a   Serge E. Hallyn   [PATCH] namespace...
1216
1217
  bad_fork_cleanup_namespaces:
  	exit_task_namespaces(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1218
1219
1220
1221
1222
1223
  bad_fork_cleanup_keys:
  	exit_keys(p);
  bad_fork_cleanup_mm:
  	if (p->mm)
  		mmput(p->mm);
  bad_fork_cleanup_signal:
6b3934ef5   Oleg Nesterov   [PATCH] copy_proc...
1224
  	cleanup_signal(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1225
  bad_fork_cleanup_sighand:
a7e5328a0   Oleg Nesterov   [PATCH] cleanup _...
1226
  	__cleanup_sighand(p->sighand);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
  bad_fork_cleanup_fs:
  	exit_fs(p); /* blocking */
  bad_fork_cleanup_files:
  	exit_files(p); /* blocking */
  bad_fork_cleanup_semundo:
  	exit_sem(p);
  bad_fork_cleanup_audit:
  	audit_free(p);
  bad_fork_cleanup_security:
  	security_task_free(p);
  bad_fork_cleanup_policy:
  #ifdef CONFIG_NUMA
  	mpol_free(p->mempolicy);
b4b264184   Paul Jackson   [PATCH] cpuset: f...
1240
  bad_fork_cleanup_cpuset:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1241
  #endif
b4b264184   Paul Jackson   [PATCH] cpuset: f...
1242
  	cpuset_exit(p);
35df17c57   Shailabh Nagar   [PATCH] task dela...
1243
1244
  bad_fork_cleanup_delays_binfmt:
  	delayacct_tsk_free(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1245
1246
1247
  	if (p->binfmt)
  		module_put(p->binfmt->module);
  bad_fork_cleanup_put_domain:
a1261f546   Al Viro   [PATCH] m68k: int...
1248
  	module_put(task_thread_info(p)->exec_domain->module);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1249
1250
1251
1252
1253
1254
  bad_fork_cleanup_count:
  	put_group_info(p->group_info);
  	atomic_dec(&p->user->processes);
  	free_uid(p->user);
  bad_fork_free:
  	free_task(p);
fe7d37d1f   Oleg Nesterov   [PATCH] copy_proc...
1255
1256
  fork_out:
  	return ERR_PTR(retval);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1257
1258
1259
1260
1261
1262
1263
  }
  
  struct pt_regs * __devinit __attribute__((weak)) idle_regs(struct pt_regs *regs)
  {
  	memset(regs, 0, sizeof(struct pt_regs));
  	return regs;
  }
36c8b5868   Ingo Molnar   [PATCH] sched: cl...
1264
  struct task_struct * __devinit fork_idle(int cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1265
  {
36c8b5868   Ingo Molnar   [PATCH] sched: cl...
1266
  	struct task_struct *task;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1267
1268
1269
1270
1271
1272
  	struct pt_regs regs;
  
  	task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL, NULL, 0);
  	if (!task)
  		return ERR_PTR(-ENOMEM);
  	init_idle(task, cpu);
73b9ebfe1   Oleg Nesterov   [PATCH] pidhash: ...
1273

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
  	return task;
  }
  
  static inline int fork_traceflag (unsigned clone_flags)
  {
  	if (clone_flags & CLONE_UNTRACED)
  		return 0;
  	else if (clone_flags & CLONE_VFORK) {
  		if (current->ptrace & PT_TRACE_VFORK)
  			return PTRACE_EVENT_VFORK;
  	} else if ((clone_flags & CSIGNAL) != SIGCHLD) {
  		if (current->ptrace & PT_TRACE_CLONE)
  			return PTRACE_EVENT_CLONE;
  	} else if (current->ptrace & PT_TRACE_FORK)
  		return PTRACE_EVENT_FORK;
  
  	return 0;
  }
  
  /*
   *  Ok, this is the main fork-routine.
   *
   * It copies the process, and if successful kick-starts
   * it and waits for it to finish using the VM if required.
   */
  long do_fork(unsigned long clone_flags,
  	      unsigned long stack_start,
  	      struct pt_regs *regs,
  	      unsigned long stack_size,
  	      int __user *parent_tidptr,
  	      int __user *child_tidptr)
  {
  	struct task_struct *p;
  	int trace = 0;
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
1308
1309
  	struct pid *pid = alloc_pid();
  	long nr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1310

92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
1311
  	if (!pid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1312
  		return -EAGAIN;
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
1313
  	nr = pid->nr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1314
1315
1316
1317
1318
  	if (unlikely(current->ptrace)) {
  		trace = fork_traceflag (clone_flags);
  		if (trace)
  			clone_flags |= CLONE_PTRACE;
  	}
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
1319
  	p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, nr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
  	/*
  	 * Do this prior waking up the new thread - the thread pointer
  	 * might get invalid after that point, if the thread exits quickly.
  	 */
  	if (!IS_ERR(p)) {
  		struct completion vfork;
  
  		if (clone_flags & CLONE_VFORK) {
  			p->vfork_done = &vfork;
  			init_completion(&vfork);
  		}
  
  		if ((p->ptrace & PT_PTRACED) || (clone_flags & CLONE_STOPPED)) {
  			/*
  			 * We'll start up with an immediate SIGSTOP.
  			 */
  			sigaddset(&p->pending.signal, SIGSTOP);
  			set_tsk_thread_flag(p, TIF_SIGPENDING);
  		}
  
  		if (!(clone_flags & CLONE_STOPPED))
  			wake_up_new_task(p, clone_flags);
  		else
  			p->state = TASK_STOPPED;
  
  		if (unlikely (trace)) {
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
1346
  			current->ptrace_message = nr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1347
1348
1349
1350
1351
  			ptrace_notify ((trace << 8) | SIGTRAP);
  		}
  
  		if (clone_flags & CLONE_VFORK) {
  			wait_for_completion(&vfork);
9f59ce5d0   Chuck Ebbert   [PATCH] ptrace: m...
1352
1353
  			if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) {
  				current->ptrace_message = nr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1354
  				ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
9f59ce5d0   Chuck Ebbert   [PATCH] ptrace: m...
1355
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1356
1357
  		}
  	} else {
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
1358
1359
  		free_pid(pid);
  		nr = PTR_ERR(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1360
  	}
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
1361
  	return nr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1362
  }
5fd63b308   Ravikiran G Thirumalai   [PATCH] x86_64: I...
1363
1364
1365
  #ifndef ARCH_MIN_MMSTRUCT_ALIGN
  #define ARCH_MIN_MMSTRUCT_ALIGN 0
  #endif
aa1757f90   Oleg Nesterov   [PATCH] convert s...
1366
1367
1368
1369
1370
1371
1372
1373
  static void sighand_ctor(void *data, kmem_cache_t *cachep, unsigned long flags)
  {
  	struct sighand_struct *sighand = data;
  
  	if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
  					SLAB_CTOR_CONSTRUCTOR)
  		spin_lock_init(&sighand->siglock);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1374
1375
1376
1377
  void __init proc_caches_init(void)
  {
  	sighand_cachep = kmem_cache_create("sighand_cache",
  			sizeof(struct sighand_struct), 0,
aa1757f90   Oleg Nesterov   [PATCH] convert s...
1378
1379
  			SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU,
  			sighand_ctor, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
  	signal_cachep = kmem_cache_create("signal_cache",
  			sizeof(struct signal_struct), 0,
  			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
  	files_cachep = kmem_cache_create("files_cache", 
  			sizeof(struct files_struct), 0,
  			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
  	fs_cachep = kmem_cache_create("fs_cache", 
  			sizeof(struct fs_struct), 0,
  			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
  	vm_area_cachep = kmem_cache_create("vm_area_struct",
  			sizeof(struct vm_area_struct), 0,
  			SLAB_PANIC, NULL, NULL);
  	mm_cachep = kmem_cache_create("mm_struct",
5fd63b308   Ravikiran G Thirumalai   [PATCH] x86_64: I...
1393
  			sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1394
1395
  			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
  }
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
  
  
  /*
   * Check constraints on flags passed to the unshare system call and
   * force unsharing of additional process context as appropriate.
   */
  static inline void check_unshare_flags(unsigned long *flags_ptr)
  {
  	/*
  	 * If unsharing a thread from a thread group, must also
  	 * unshare vm.
  	 */
  	if (*flags_ptr & CLONE_THREAD)
  		*flags_ptr |= CLONE_VM;
  
  	/*
  	 * If unsharing vm, must also unshare signal handlers.
  	 */
  	if (*flags_ptr & CLONE_VM)
  		*flags_ptr |= CLONE_SIGHAND;
  
  	/*
  	 * If unsharing signal handlers and the task was created
  	 * using CLONE_THREAD, then must unshare the thread
  	 */
  	if ((*flags_ptr & CLONE_SIGHAND) &&
  	    (atomic_read(&current->signal->count) > 1))
  		*flags_ptr |= CLONE_THREAD;
  
  	/*
  	 * If unsharing namespace, must also unshare filesystem information.
  	 */
  	if (*flags_ptr & CLONE_NEWNS)
  		*flags_ptr |= CLONE_FS;
  }
  
  /*
   * Unsharing of tasks created with CLONE_THREAD is not supported yet
   */
  static int unshare_thread(unsigned long unshare_flags)
  {
  	if (unshare_flags & CLONE_THREAD)
  		return -EINVAL;
  
  	return 0;
  }
  
  /*
99d1419d9   JANAK DESAI   [PATCH] unshare s...
1444
   * Unshare the filesystem structure if it is being shared
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1445
1446
1447
1448
1449
1450
   */
  static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
  {
  	struct fs_struct *fs = current->fs;
  
  	if ((unshare_flags & CLONE_FS) &&
99d1419d9   JANAK DESAI   [PATCH] unshare s...
1451
1452
1453
1454
1455
  	    (fs && atomic_read(&fs->count) > 1)) {
  		*new_fsp = __copy_fs_struct(current->fs);
  		if (!*new_fsp)
  			return -ENOMEM;
  	}
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1456
1457
1458
1459
1460
  
  	return 0;
  }
  
  /*
741a29513   JANAK DESAI   [PATCH] unshare s...
1461
   * Unshare the namespace structure if it is being shared
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1462
   */
741a29513   JANAK DESAI   [PATCH] unshare s...
1463
  static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs)
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1464
  {
1651e14e2   Serge E. Hallyn   [PATCH] namespace...
1465
  	struct namespace *ns = current->nsproxy->namespace;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1466

1651e14e2   Serge E. Hallyn   [PATCH] namespace...
1467
  	if ((unshare_flags & CLONE_NEWNS) && ns) {
741a29513   JANAK DESAI   [PATCH] unshare s...
1468
1469
1470
1471
1472
1473
1474
  		if (!capable(CAP_SYS_ADMIN))
  			return -EPERM;
  
  		*new_nsp = dup_namespace(current, new_fs ? new_fs : current->fs);
  		if (!*new_nsp)
  			return -ENOMEM;
  	}
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
  
  	return 0;
  }
  
  /*
   * Unsharing of sighand for tasks created with CLONE_SIGHAND is not
   * supported yet
   */
  static int unshare_sighand(unsigned long unshare_flags, struct sighand_struct **new_sighp)
  {
  	struct sighand_struct *sigh = current->sighand;
  
  	if ((unshare_flags & CLONE_SIGHAND) &&
  	    (sigh && atomic_read(&sigh->count) > 1))
  		return -EINVAL;
  	else
  		return 0;
  }
  
  /*
a0a7ec308   JANAK DESAI   [PATCH] unshare s...
1495
   * Unshare vm if it is being shared
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1496
1497
1498
1499
1500
1501
   */
  static int unshare_vm(unsigned long unshare_flags, struct mm_struct **new_mmp)
  {
  	struct mm_struct *mm = current->mm;
  
  	if ((unshare_flags & CLONE_VM) &&
a0a7ec308   JANAK DESAI   [PATCH] unshare s...
1502
  	    (mm && atomic_read(&mm->mm_users) > 1)) {
2d61b8677   Oleg Nesterov   [PATCH] disable u...
1503
  		return -EINVAL;
a0a7ec308   JANAK DESAI   [PATCH] unshare s...
1504
  	}
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1505
1506
  
  	return 0;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1507
1508
1509
  }
  
  /*
a016f3389   JANAK DESAI   [PATCH] unshare s...
1510
   * Unshare file descriptor table if it is being shared
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1511
1512
1513
1514
   */
  static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp)
  {
  	struct files_struct *fd = current->files;
a016f3389   JANAK DESAI   [PATCH] unshare s...
1515
  	int error = 0;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1516
1517
  
  	if ((unshare_flags & CLONE_FILES) &&
a016f3389   JANAK DESAI   [PATCH] unshare s...
1518
1519
1520
1521
1522
  	    (fd && atomic_read(&fd->count) > 1)) {
  		*new_fdp = dup_fd(fd, &error);
  		if (!*new_fdp)
  			return error;
  	}
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
  
  	return 0;
  }
  
  /*
   * Unsharing of semundo for tasks created with CLONE_SYSVSEM is not
   * supported yet
   */
  static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **new_ulistp)
  {
  	if (unshare_flags & CLONE_SYSVSEM)
  		return -EINVAL;
  
  	return 0;
  }
73ea41302   Kirill Korotaev   [PATCH] IPC names...
1538
1539
1540
1541
1542
1543
1544
1545
1546
  #ifndef CONFIG_IPC_NS
  static inline int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns)
  {
  	if (flags & CLONE_NEWIPC)
  		return -EINVAL;
  
  	return 0;
  }
  #endif
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
  /*
   * unshare allows a process to 'unshare' part of the process
   * context which was originally shared using clone.  copy_*
   * functions used by do_fork() cannot be used here directly
   * because they modify an inactive task_struct that is being
   * constructed. Here we are modifying the current, active,
   * task_struct.
   */
  asmlinkage long sys_unshare(unsigned long unshare_flags)
  {
  	int err = 0;
  	struct fs_struct *fs, *new_fs = NULL;
  	struct namespace *ns, *new_ns = NULL;
  	struct sighand_struct *sigh, *new_sigh = NULL;
  	struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
  	struct files_struct *fd, *new_fd = NULL;
  	struct sem_undo_list *new_ulist = NULL;
c0b2fc316   Serge Hallyn   [PATCH] uts: copy...
1564
  	struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
071df104f   Serge E. Hallyn   [PATCH] namespace...
1565
  	struct uts_namespace *uts, *new_uts = NULL;
25b21cb2f   Kirill Korotaev   [PATCH] IPC names...
1566
  	struct ipc_namespace *ipc, *new_ipc = NULL;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1567
1568
  
  	check_unshare_flags(&unshare_flags);
06f9d4f94   Eric W. Biederman   [PATCH] unshare: ...
1569
1570
1571
  	/* Return -EINVAL for all unsupported flags */
  	err = -EINVAL;
  	if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
25b21cb2f   Kirill Korotaev   [PATCH] IPC names...
1572
1573
  				CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
  				CLONE_NEWUTS|CLONE_NEWIPC))
06f9d4f94   Eric W. Biederman   [PATCH] unshare: ...
1574
  		goto bad_unshare_out;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1575
1576
1577
1578
  	if ((err = unshare_thread(unshare_flags)))
  		goto bad_unshare_out;
  	if ((err = unshare_fs(unshare_flags, &new_fs)))
  		goto bad_unshare_cleanup_thread;
741a29513   JANAK DESAI   [PATCH] unshare s...
1579
  	if ((err = unshare_namespace(unshare_flags, &new_ns, new_fs)))
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1580
1581
1582
1583
1584
1585
1586
1587
1588
  		goto bad_unshare_cleanup_fs;
  	if ((err = unshare_sighand(unshare_flags, &new_sigh)))
  		goto bad_unshare_cleanup_ns;
  	if ((err = unshare_vm(unshare_flags, &new_mm)))
  		goto bad_unshare_cleanup_sigh;
  	if ((err = unshare_fd(unshare_flags, &new_fd)))
  		goto bad_unshare_cleanup_vm;
  	if ((err = unshare_semundo(unshare_flags, &new_ulist)))
  		goto bad_unshare_cleanup_fd;
071df104f   Serge E. Hallyn   [PATCH] namespace...
1589
1590
  	if ((err = unshare_utsname(unshare_flags, &new_uts)))
  		goto bad_unshare_cleanup_semundo;
25b21cb2f   Kirill Korotaev   [PATCH] IPC names...
1591
1592
  	if ((err = unshare_ipcs(unshare_flags, &new_ipc)))
  		goto bad_unshare_cleanup_uts;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1593

25b21cb2f   Kirill Korotaev   [PATCH] IPC names...
1594
  	if (new_ns || new_uts || new_ipc) {
ab516013a   Serge E. Hallyn   [PATCH] namespace...
1595
1596
1597
1598
  		old_nsproxy = current->nsproxy;
  		new_nsproxy = dup_namespaces(old_nsproxy);
  		if (!new_nsproxy) {
  			err = -ENOMEM;
25b21cb2f   Kirill Korotaev   [PATCH] IPC names...
1599
  			goto bad_unshare_cleanup_ipc;
ab516013a   Serge E. Hallyn   [PATCH] namespace...
1600
  		}
c0b2fc316   Serge Hallyn   [PATCH] uts: copy...
1601
1602
1603
  	}
  
  	if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist ||
25b21cb2f   Kirill Korotaev   [PATCH] IPC names...
1604
  				new_uts || new_ipc) {
ab516013a   Serge E. Hallyn   [PATCH] namespace...
1605

cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1606
  		task_lock(current);
c0b2fc316   Serge Hallyn   [PATCH] uts: copy...
1607
1608
1609
1610
1611
  
  		if (new_nsproxy) {
  			current->nsproxy = new_nsproxy;
  			new_nsproxy = old_nsproxy;
  		}
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1612
1613
1614
1615
1616
1617
1618
1619
  
  		if (new_fs) {
  			fs = current->fs;
  			current->fs = new_fs;
  			new_fs = fs;
  		}
  
  		if (new_ns) {
1651e14e2   Serge E. Hallyn   [PATCH] namespace...
1620
1621
  			ns = current->nsproxy->namespace;
  			current->nsproxy->namespace = new_ns;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1622
1623
1624
1625
1626
  			new_ns = ns;
  		}
  
  		if (new_sigh) {
  			sigh = current->sighand;
e0e8eb54d   Eric W. Biederman   [PATCH] unshare: ...
1627
  			rcu_assign_pointer(current->sighand, new_sigh);
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
  			new_sigh = sigh;
  		}
  
  		if (new_mm) {
  			mm = current->mm;
  			active_mm = current->active_mm;
  			current->mm = new_mm;
  			current->active_mm = new_mm;
  			activate_mm(active_mm, new_mm);
  			new_mm = mm;
  		}
  
  		if (new_fd) {
  			fd = current->files;
  			current->files = new_fd;
  			new_fd = fd;
  		}
071df104f   Serge E. Hallyn   [PATCH] namespace...
1645
1646
1647
1648
1649
  		if (new_uts) {
  			uts = current->nsproxy->uts_ns;
  			current->nsproxy->uts_ns = new_uts;
  			new_uts = uts;
  		}
25b21cb2f   Kirill Korotaev   [PATCH] IPC names...
1650
1651
1652
1653
1654
  		if (new_ipc) {
  			ipc = current->nsproxy->ipc_ns;
  			current->nsproxy->ipc_ns = new_ipc;
  			new_ipc = ipc;
  		}
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1655
1656
  		task_unlock(current);
  	}
c0b2fc316   Serge Hallyn   [PATCH] uts: copy...
1657
1658
  	if (new_nsproxy)
  		put_nsproxy(new_nsproxy);
25b21cb2f   Kirill Korotaev   [PATCH] IPC names...
1659
1660
1661
  bad_unshare_cleanup_ipc:
  	if (new_ipc)
  		put_ipc_ns(new_ipc);
071df104f   Serge E. Hallyn   [PATCH] namespace...
1662
1663
1664
  bad_unshare_cleanup_uts:
  	if (new_uts)
  		put_uts_ns(new_uts);
ab516013a   Serge E. Hallyn   [PATCH] namespace...
1665
  bad_unshare_cleanup_semundo:
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
  bad_unshare_cleanup_fd:
  	if (new_fd)
  		put_files_struct(new_fd);
  
  bad_unshare_cleanup_vm:
  	if (new_mm)
  		mmput(new_mm);
  
  bad_unshare_cleanup_sigh:
  	if (new_sigh)
  		if (atomic_dec_and_test(&new_sigh->count))
  			kmem_cache_free(sighand_cachep, new_sigh);
  
  bad_unshare_cleanup_ns:
  	if (new_ns)
  		put_namespace(new_ns);
  
  bad_unshare_cleanup_fs:
  	if (new_fs)
  		put_fs_struct(new_fs);
  
  bad_unshare_cleanup_thread:
  bad_unshare_out:
  	return err;
  }