Blame view

kernel/fork.c 42.1 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
  #include <linux/slab.h>
  #include <linux/init.h>
  #include <linux/unistd.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
18
  #include <linux/module.h>
  #include <linux/vmalloc.h>
  #include <linux/completion.h>
6b3286ed1   Kirill Korotaev   [PATCH] rename st...
19
  #include <linux/mnt_namespace.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
22
23
24
25
26
27
  #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...
28
  #include <linux/nsproxy.h>
c59ede7b7   Randy.Dunlap   [PATCH] move capa...
29
  #include <linux/capability.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  #include <linux/cpu.h>
b4f48b636   Paul Menage   Task Control Grou...
31
  #include <linux/cgroup.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
34
35
36
  #include <linux/security.h>
  #include <linux/swap.h>
  #include <linux/syscalls.h>
  #include <linux/jiffies.h>
  #include <linux/futex.h>
7c3ab7381   Andrew Morton   [PATCH] io-accoun...
37
  #include <linux/task_io_accounting_ops.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>
ba96a0c88   Rafael J. Wysocki   freezer: fix vfor...
47
  #include <linux/freezer.h>
ca74e92b4   Shailabh Nagar   [PATCH] per-task-...
48
  #include <linux/delayacct.h>
ad4ecbcba   Shailabh Nagar   [PATCH] delay acc...
49
  #include <linux/taskstats_kern.h>
0a4254058   Arjan van de Ven   [PATCH] Add the c...
50
  #include <linux/random.h>
522ed7767   Miloslav Trmac   Audit: add TTY in...
51
  #include <linux/tty.h>
6f4e64335   Pavel Emelyanov   pid namespaces: i...
52
  #include <linux/proc_fs.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  
  #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...
70
  __cacheline_aligned DEFINE_RWLOCK(tasklist_lock);  /* outer */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
  
  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))
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
86
  static struct kmem_cache *task_struct_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
89
  #endif
  
  /* SLAB cache for signal_struct structures (tsk->signal) */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
90
  static struct kmem_cache *signal_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
  
  /* SLAB cache for sighand_struct structures (tsk->sighand) */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
93
  struct kmem_cache *sighand_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
  
  /* SLAB cache for files_struct structures (tsk->files) */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
96
  struct kmem_cache *files_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
  
  /* SLAB cache for fs_struct structures (tsk->fs) */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
99
  struct kmem_cache *fs_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
  
  /* SLAB cache for vm_area_struct structures */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
102
  struct kmem_cache *vm_area_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
104
  
  /* SLAB cache for mm_struct structures (tsk->mm) */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
105
  static struct kmem_cache *mm_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
107
108
  
  void free_task(struct task_struct *tsk)
  {
3e26c149c   Peter Zijlstra   mm: dirty balanci...
109
  	prop_local_destroy_single(&tsk->dirties);
f7e4217b0   Roman Zippel   rename thread_inf...
110
  	free_thread_info(tsk->stack);
23f78d4a0   Ingo Molnar   [PATCH] pi-futex:...
111
  	rt_mutex_debug_task_free(tsk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
113
114
  	free_task_struct(tsk);
  }
  EXPORT_SYMBOL(free_task);
158d9ebd1   Andrew Morton   [PATCH] resurrect...
115
  void __put_task_struct(struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  {
270f722d4   Eugene Teo   Fix tsk->exit_sta...
117
  	WARN_ON(!tsk->exit_state);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
  	WARN_ON(atomic_read(&tsk->usage));
  	WARN_ON(tsk == current);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
  	security_task_free(tsk);
  	free_uid(tsk->user);
  	put_group_info(tsk->group_info);
35df17c57   Shailabh Nagar   [PATCH] task dela...
123
  	delayacct_tsk_free(tsk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  
  	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),
20c2df83d   Paul Mundt   mm: Remove slab d...
138
  			ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
  #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;
3e26c149c   Peter Zijlstra   mm: dirty balanci...
164
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
166
167
168
169
170
171
172
173
174
175
176
  
  	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
177
  	*tsk = *orig;
f7e4217b0   Roman Zippel   rename thread_inf...
178
  	tsk->stack = ti;
3e26c149c   Peter Zijlstra   mm: dirty balanci...
179
180
181
182
183
184
185
  
  	err = prop_local_init_single(&tsk->dirties);
  	if (err) {
  		free_thread_info(ti);
  		free_task_struct(tsk);
  		return NULL;
  	}
10ebffde3   Al Viro   [PATCH] m68k: int...
186
  	setup_thread_stack(tsk, orig);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
218
219
220
  	mm->locked_vm = 0;
  	mm->mmap = NULL;
  	mm->mmap_cache = NULL;
  	mm->free_area_cache = oldmm->mmap_base;
1363c3cd8   Wolfgang Wander   [PATCH] Avoiding ...
221
  	mm->cached_hole_size = ~0UL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
  	mm->map_count = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223
224
225
226
227
  	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...
228
  	for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
231
  		struct file *file;
  
  		if (mpnt->vm_flags & VM_DONTCOPY) {
3b6bfcdb1   Hugh Dickins   [PATCH] lower VM_...
232
233
  			long pages = vma_pages(mpnt);
  			mm->total_vm -= pages;
ab50b8ed8   Hugh Dickins   [PATCH] mm: vm_st...
234
  			vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
3b6bfcdb1   Hugh Dickins   [PATCH] lower VM_...
235
  								-pages);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
238
239
240
241
242
243
244
  			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;
  		}
e94b17660   Christoph Lameter   [PATCH] slab: rem...
245
  		tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246
247
248
249
250
251
252
253
254
255
256
257
258
259
  		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) {
f3a43f3f6   Josef "Jeff" Sipek   [PATCH] kernel: c...
260
  			struct inode *inode = file->f_path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
262
263
  			get_file(file);
  			if (tmp->vm_flags & VM_DENYWRITE)
  				atomic_dec(&inode->i_writecount);
23ff44402   Daniel Walker   whitespace fixes:...
264

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
268
269
270
271
272
273
274
  			/* 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...
275
  		 * Link in the new vma and copy the page table entries.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276
  		 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
278
279
280
281
282
283
284
  		*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: ...
285
  		retval = copy_page_range(mm, oldmm, mpnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
287
288
289
290
291
292
  
  		if (tmp->vm_ops && tmp->vm_ops->open)
  			tmp->vm_ops->open(tmp);
  
  		if (retval)
  			goto out;
  	}
d6dd61c83   Jeremy Fitzhardinge   [PATCH] x86: PARA...
293
294
  	/* a new mm has just been created */
  	arch_dup_mmap(oldmm, mm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
  	retval = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
  out:
7ee782325   Hugh Dickins   [PATCH] mm: dup_m...
297
  	up_write(&mm->mmap_sem);
fd3e42fcc   Hugh Dickins   [PATCH] mm: dup_m...
298
  	flush_tlb_mm(oldmm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
  	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 */
23ff44402   Daniel Walker   whitespace fixes:...
326
  __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327

e94b17660   Christoph Lameter   [PATCH] slab: rem...
328
  #define allocate_mm()	(kmem_cache_alloc(mm_cachep, GFP_KERNEL))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
330
331
332
333
334
335
336
337
338
  #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);
3cb4a0bb1   Kawai, Hidehiro   coredump masking:...
339
340
  	mm->flags = (current->mm) ? current->mm->flags
  				  : MMF_DUMP_FILTER_DEFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
342
  	mm->core_waiters = 0;
  	mm->nr_ptes = 0;
4294621f4   Hugh Dickins   [PATCH] mm: rss =...
343
  	set_mm_counter(mm, file_rss, 0);
404351e67   Hugh Dickins   [PATCH] mm: mm_in...
344
  	set_mm_counter(mm, anon_rss, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
346
347
  	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
348
  	mm->free_area_cache = TASK_UNMAPPED_BASE;
1363c3cd8   Wolfgang Wander   [PATCH] Avoiding ...
349
  	mm->cached_hole_size = ~0UL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
  
  	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...
392
  	might_sleep();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
455
456
457
  	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);
  	}
fec1d0115   Roland McGrath   [PATCH] Disable C...
458
459
460
461
462
463
464
465
466
467
  
  	/*
  	 * If we're exiting normally, clear a user-space tid field if
  	 * requested.  We leave this alone when dying by signal, to leave
  	 * the value intact in a core dump, and to save the unnecessary
  	 * trouble otherwise.  Userland only wants this done for a sys_exit.
  	 */
  	if (tsk->clear_child_tid
  	    && !(tsk->flags & PF_SIGNALED)
  	    && atomic_read(&mm->mm_users) > 1) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
468
469
470
471
472
473
474
475
476
477
478
  		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...
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
  /*
   * 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));
7602bdf2f   Ashwin Chaugule   [PATCH] new schem...
496
497
498
  	/* Initializing for Swap token stuff */
  	mm->token_priority = 0;
  	mm->last_interval = 0;
a0a7ec308   JANAK DESAI   [PATCH] unshare s...
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
  	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
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
  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
552
553
554
555
  		goto good_mm;
  	}
  
  	retval = -ENOMEM;
a0a7ec308   JANAK DESAI   [PATCH] unshare s...
556
  	mm = dup_mm(tsk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
557
558
  	if (!mm)
  		goto fail_nomem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
  good_mm:
7602bdf2f   Ashwin Chaugule   [PATCH] new schem...
560
561
562
  	/* Initializing for Swap token stuff */
  	mm->token_priority = 0;
  	mm->last_interval = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
564
565
  	tsk->mm = mm;
  	tsk->active_mm = mm;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566
567
  fail_nomem:
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
  }
a39bc5169   Alexey Dobriyan   Uninline fork.c/e...
569
  static struct fs_struct *__copy_fs_struct(struct fs_struct *old)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
  {
  	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);
a39bc5169   Alexey Dobriyan   Uninline fork.c/e...
600
  static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
601
602
603
604
605
606
607
608
609
610
  {
  	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...
611
  static int count_open_files(struct fdtable *fdt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
612
  {
bbea9f696   Vadim Lobanov   [PATCH] fdtable: ...
613
  	int size = fdt->max_fds;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
614
615
616
617
  	int i;
  
  	/* Find the last open fd */
  	for (i = size/(8*sizeof(long)); i > 0; ) {
badf16621   Dipankar Sarma   [PATCH] files: br...
618
  		if (fdt->open_fds->fds_bits[--i])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619
620
621
622
623
  			break;
  	}
  	i = (i+1) * 8 * sizeof(long);
  	return i;
  }
badf16621   Dipankar Sarma   [PATCH] files: br...
624
625
626
627
  static struct files_struct *alloc_files(void)
  {
  	struct files_struct *newf;
  	struct fdtable *fdt;
e94b17660   Christoph Lameter   [PATCH] slab: rem...
628
  	newf = kmem_cache_alloc(files_cachep, GFP_KERNEL);
badf16621   Dipankar Sarma   [PATCH] files: br...
629
630
631
632
633
634
  	if (!newf)
  		goto out;
  
  	atomic_set(&newf->count, 1);
  
  	spin_lock_init(&newf->file_lock);
0c9e63fd3   Eric Dumazet   [PATCH] Shrinks s...
635
  	newf->next_fd = 0;
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
636
  	fdt = &newf->fdtab;
badf16621   Dipankar Sarma   [PATCH] files: br...
637
  	fdt->max_fds = NR_OPEN_DEFAULT;
0c9e63fd3   Eric Dumazet   [PATCH] Shrinks s...
638
639
  	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...
640
  	fdt->fd = &newf->fd_array[0];
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
641
  	INIT_RCU_HEAD(&fdt->rcu);
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
642
643
  	fdt->next = NULL;
  	rcu_assign_pointer(newf->fdt, fdt);
badf16621   Dipankar Sarma   [PATCH] files: br...
644
645
646
  out:
  	return newf;
  }
a016f3389   JANAK DESAI   [PATCH] unshare s...
647
648
649
  /*
   * Allocate a new files structure and copy contents from the
   * passed in files structure.
6e6672604   Prasanna Meda   [PATCH] dup fd er...
650
   * errorp will be valid only when the returned files_struct is NULL.
a016f3389   JANAK DESAI   [PATCH] unshare s...
651
652
   */
  static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
653
  {
a016f3389   JANAK DESAI   [PATCH] unshare s...
654
  	struct files_struct *newf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
655
  	struct file **old_fds, **new_fds;
bbea9f696   Vadim Lobanov   [PATCH] fdtable: ...
656
  	int open_files, size, i;
badf16621   Dipankar Sarma   [PATCH] files: br...
657
  	struct fdtable *old_fdt, *new_fdt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658

6e6672604   Prasanna Meda   [PATCH] dup fd er...
659
  	*errorp = -ENOMEM;
badf16621   Dipankar Sarma   [PATCH] files: br...
660
661
  	newf = alloc_files();
  	if (!newf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
663
  	spin_lock(&oldf->file_lock);
badf16621   Dipankar Sarma   [PATCH] files: br...
664
665
  	old_fdt = files_fdtable(oldf);
  	new_fdt = files_fdtable(newf);
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
666
  	open_files = count_open_files(old_fdt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
667
668
  
  	/*
bbea9f696   Vadim Lobanov   [PATCH] fdtable: ...
669
670
  	 * Check whether we need to allocate a larger fd array and fd set.
  	 * Note: we're not a clone task, so the open count won't change.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
671
  	 */
badf16621   Dipankar Sarma   [PATCH] files: br...
672
673
  	if (open_files > new_fdt->max_fds) {
  		new_fdt->max_fds = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
675
  		spin_unlock(&oldf->file_lock);
  		spin_lock(&newf->file_lock);
a016f3389   JANAK DESAI   [PATCH] unshare s...
676
  		*errorp = expand_files(newf, open_files-1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
677
  		spin_unlock(&newf->file_lock);
a016f3389   JANAK DESAI   [PATCH] unshare s...
678
  		if (*errorp < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
679
  			goto out_release;
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
680
681
682
683
684
685
  		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
686
  		spin_lock(&oldf->file_lock);
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
687
  		old_fdt = files_fdtable(oldf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
688
  	}
badf16621   Dipankar Sarma   [PATCH] files: br...
689
690
  	old_fds = old_fdt->fd;
  	new_fds = new_fdt->fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691

f3d19c90f   Vadim Lobanov   [PATCH] fdtable: ...
692
693
694
695
  	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
696
697
698
699
700
701
702
703
704
705
706
707
  
  	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...
708
  			FD_CLR(open_files - i, new_fdt->open_fds);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
709
  		}
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
710
  		rcu_assign_pointer(*new_fds++, f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
711
712
713
714
  	}
  	spin_unlock(&oldf->file_lock);
  
  	/* compute the remainder to be cleared */
badf16621   Dipankar Sarma   [PATCH] files: br...
715
  	size = (new_fdt->max_fds - open_files) * sizeof(struct file *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716

23ff44402   Daniel Walker   whitespace fixes:...
717
718
  	/* This is long word aligned thus could use a optimized version */
  	memset(new_fds, 0, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
719

bbea9f696   Vadim Lobanov   [PATCH] fdtable: ...
720
721
  	if (new_fdt->max_fds > open_files) {
  		int left = (new_fdt->max_fds-open_files)/8;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
722
  		int start = open_files / (8 * sizeof(unsigned long));
badf16621   Dipankar Sarma   [PATCH] files: br...
723
724
  		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
725
  	}
a016f3389   JANAK DESAI   [PATCH] unshare s...
726
  	return newf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727
728
  
  out_release:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
729
  	kmem_cache_free(files_cachep, newf);
f3d19c90f   Vadim Lobanov   [PATCH] fdtable: ...
730
  out:
428622986   Kirill Korotaev   [PATCH] wrong err...
731
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
732
  }
a016f3389   JANAK DESAI   [PATCH] unshare s...
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
  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...
756
757
758
759
760
761
762
763
764
  	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
765
766
767
768
769
770
771
772
773
774
  /*
   *	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...
775
  	BUG_ON(!files);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
  
  	/* 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);
a39bc5169   Alexey Dobriyan   Uninline fork.c/e...
791
  static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
792
793
794
795
796
797
798
799
  {
  	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...
800
  	rcu_assign_pointer(tsk->sighand, sig);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
801
802
  	if (!sig)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
803
804
805
806
  	atomic_set(&sig->count, 1);
  	memcpy(sig->action, current->sighand->action, sizeof(sig->action));
  	return 0;
  }
a7e5328a0   Oleg Nesterov   [PATCH] cleanup _...
807
  void __cleanup_sighand(struct sighand_struct *sighand)
c81addc9d   Oleg Nesterov   [PATCH] rename __...
808
  {
c81addc9d   Oleg Nesterov   [PATCH] rename __...
809
810
811
  	if (atomic_dec_and_test(&sighand->count))
  		kmem_cache_free(sighand_cachep, sighand);
  }
a39bc5169   Alexey Dobriyan   Uninline fork.c/e...
812
  static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
  {
  	struct signal_struct *sig;
  	int ret;
  
  	if (clone_flags & CLONE_THREAD) {
  		atomic_inc(&current->signal->count);
  		atomic_inc(&current->signal->live);
  		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);
c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
843
  	hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
2ff678b8d   Thomas Gleixner   [PATCH] hrtimer: ...
844
  	sig->it_real_incr.tv64 = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
  	sig->real_timer.function = it_real_fn;
05cfb614d   Roman Zippel   [PATCH] hrtimers:...
846
  	sig->tsk = tsk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
847
848
849
850
851
  
  	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
852
  	sig->leader = 0;	/* session leadership doesn't inherit */
ab521dc0f   Eric W. Biederman   [PATCH] tty: upda...
853
  	sig->tty_old_pgrp = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
854
855
  
  	sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
9ac52315d   Laurent Vivier   sched: guest CPU ...
856
857
  	sig->gtime = cputime_zero;
  	sig->cgtime = cputime_zero;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858
859
  	sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
  	sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
6eaeeaba3   Eric Dumazet   getrusage(): fill...
860
  	sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
172ba844a   Balbir Singh   sched: update del...
861
  	sig->sum_sched_runtime = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
862
863
864
  	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...
865
  	taskstats_tgid_init(sig);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
866
867
868
869
870
871
872
873
874
875
876
877
878
  
  	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...
879
  	acct_init_pacct(&sig->pacct);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
880

522ed7767   Miloslav Trmac   Audit: add TTY in...
881
  	tty_audit_fork(sig);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
882
883
  	return 0;
  }
6b3934ef5   Oleg Nesterov   [PATCH] copy_proc...
884
885
886
887
888
  void __cleanup_signal(struct signal_struct *sig)
  {
  	exit_thread_group_keys(sig);
  	kmem_cache_free(signal_cachep, sig);
  }
a39bc5169   Alexey Dobriyan   Uninline fork.c/e...
889
  static void cleanup_signal(struct task_struct *tsk)
6b3934ef5   Oleg Nesterov   [PATCH] copy_proc...
890
891
892
893
894
895
896
897
  {
  	struct signal_struct *sig = tsk->signal;
  
  	atomic_dec(&sig->live);
  
  	if (atomic_dec_and_test(&sig->count))
  		__cleanup_signal(sig);
  }
a39bc5169   Alexey Dobriyan   Uninline fork.c/e...
898
  static void copy_flags(unsigned long clone_flags, struct task_struct *p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
899
900
  {
  	unsigned long new_flags = p->flags;
831441862   Rafael J. Wysocki   Freezer: make ker...
901
  	new_flags &= ~PF_SUPERPRIV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
903
904
905
  	new_flags |= PF_FORKNOEXEC;
  	if (!(clone_flags & CLONE_PTRACE))
  		p->ptrace = 0;
  	p->flags = new_flags;
2e1318956   Rafael J. Wysocki   freezer: prevent ...
906
  	clear_freeze_flag(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
907
908
909
910
911
  }
  
  asmlinkage long sys_set_tid_address(int __user *tidptr)
  {
  	current->clear_child_tid = tidptr;
b488893a3   Pavel Emelyanov   pid namespaces: c...
912
  	return task_pid_vnr(current);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
913
  }
a39bc5169   Alexey Dobriyan   Uninline fork.c/e...
914
  static void rt_mutex_init_task(struct task_struct *p)
23f78d4a0   Ingo Molnar   [PATCH] pi-futex:...
915
  {
23f78d4a0   Ingo Molnar   [PATCH] pi-futex:...
916
  	spin_lock_init(&p->pi_lock);
e29e175b0   Zilvinas Valinskas   [PATCH] initialis...
917
  #ifdef CONFIG_RT_MUTEXES
23f78d4a0   Ingo Molnar   [PATCH] pi-futex:...
918
919
  	plist_head_init(&p->pi_waiters, &p->pi_lock);
  	p->pi_blocked_on = NULL;
23f78d4a0   Ingo Molnar   [PATCH] pi-futex:...
920
921
  #endif
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
922
923
924
925
926
927
928
929
  /*
   * 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...
930
931
932
933
  static struct task_struct *copy_process(unsigned long clone_flags,
  					unsigned long stack_start,
  					struct pt_regs *regs,
  					unsigned long stack_size,
36c8b5868   Ingo Molnar   [PATCH] sched: cl...
934
  					int __user *child_tidptr,
85868995d   Sukadev Bhattiprolu   Use struct pid pa...
935
  					struct pid *pid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
936
937
  {
  	int retval;
a24efe62d   Mariusz Kozlowski   kernel/fork.c: re...
938
  	struct task_struct *p;
b4f48b636   Paul Menage   Task Control Grou...
939
  	int cgroup_callbacks_done = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
  
  	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;
bea493a03   Peter Zijlstra   [PATCH] rt-mutex:...
967
  	rt_mutex_init_task(p);
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
968
969
970
971
  #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
972
973
974
975
  	retval = -EAGAIN;
  	if (atomic_read(&p->user->processes) >=
  			p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
  		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
acce292c8   Cedric Le Goater   user namespace: a...
976
  		    p->user != current->nsproxy->user_ns->root_user)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
977
978
979
980
981
982
983
984
985
986
987
988
989
990
  			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...
991
  	if (!try_module_get(task_thread_info(p)->exec_domain->module))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
992
993
994
995
996
997
  		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-...
998
  	delayacct_tsk_init(p);	/* Must remain after dup_task_struct() */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
999
  	copy_flags(clone_flags, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1000
1001
1002
1003
  	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
1004
1005
1006
1007
1008
1009
  
  	clear_tsk_thread_flag(p, TIF_SIGPENDING);
  	init_sigpending(&p->pending);
  
  	p->utime = cputime_zero;
  	p->stime = cputime_zero;
9ac52315d   Laurent Vivier   sched: guest CPU ...
1010
  	p->gtime = cputime_zero;
c66f08be7   Michael Neuling   Add scaled time t...
1011
1012
  	p->utimescaled = cputime_zero;
  	p->stimescaled = cputime_zero;
73a2bcb0e   Peter Zijlstra   sched: keep utime...
1013
  	p->prev_utime = cputime_zero;
9301899be   Balbir Singh   sched: fix /proc/...
1014
  	p->prev_stime = cputime_zero;
172ba844a   Balbir Singh   sched: update del...
1015

4b98d11b4   Alexey Dobriyan   [PATCH] ifdef ->r...
1016
  #ifdef CONFIG_TASK_XACCT
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1017
1018
1019
1020
  	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 */
4b98d11b4   Alexey Dobriyan   [PATCH] ifdef ->r...
1021
  #endif
7c3ab7381   Andrew Morton   [PATCH] io-accoun...
1022
  	task_io_accounting_init(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1023
  	acct_clear_integrals(p);
23ff44402   Daniel Walker   whitespace fixes:...
1024
  	p->it_virt_expires = cputime_zero;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1025
  	p->it_prof_expires = cputime_zero;
23ff44402   Daniel Walker   whitespace fixes:...
1026
1027
1028
1029
  	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]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1030
1031
1032
  
  	p->lock_depth = -1;		/* -1 = no lock */
  	do_posix_clock_monotonic_gettime(&p->start_time);
924b42d5a   Tomas Janousek   Use boot based ti...
1033
1034
  	p->real_start_time = p->start_time;
  	monotonic_to_bootbased(&p->real_start_time);
57c521ce6   Alexey Dobriyan   ifdef struct task...
1035
  #ifdef CONFIG_SECURITY
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1036
  	p->security = NULL;
57c521ce6   Alexey Dobriyan   ifdef struct task...
1037
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1038
  	p->io_context = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1039
  	p->audit_context = NULL;
b4f48b636   Paul Menage   Task Control Grou...
1040
  	cgroup_fork(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1041
1042
1043
1044
1045
  #ifdef CONFIG_NUMA
   	p->mempolicy = mpol_copy(p->mempolicy);
   	if (IS_ERR(p->mempolicy)) {
   		retval = PTR_ERR(p->mempolicy);
   		p->mempolicy = NULL;
b4f48b636   Paul Menage   Task Control Grou...
1046
   		goto bad_fork_cleanup_cgroup;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1047
   	}
c61afb181   Paul Jackson   [PATCH] cpuset me...
1048
  	mpol_fix_fork_child_flag(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1049
  #endif
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
1050
1051
  #ifdef CONFIG_TRACE_IRQFLAGS
  	p->irq_events = 0;
b36e4758d   Russell King   [ARM] Fix kernel/...
1052
1053
1054
  #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
  	p->hardirqs_enabled = 1;
  #else
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
1055
  	p->hardirqs_enabled = 0;
b36e4758d   Russell King   [ARM] Fix kernel/...
1056
  #endif
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
  	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: ...
1069
1070
1071
1072
1073
  #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
1074

408894ee4   Ingo Molnar   [PATCH] mutex sub...
1075
1076
1077
  #ifdef CONFIG_DEBUG_MUTEXES
  	p->blocked_on = NULL; /* not blocked yet */
  #endif
3c90e6e99   Srivatsa Vaddagiri   sched: fix copy_n...
1078
1079
  	/* Perform scheduler related setup. Assign this task to a CPU. */
  	sched_fork(p, clone_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
  	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...
1099
  	if ((retval = copy_namespaces(clone_flags, p)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1100
1101
1102
  		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...
1103
  		goto bad_fork_cleanup_namespaces;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1104

425fb2b4b   Pavel Emelyanov   pid namespaces: m...
1105
1106
1107
1108
1109
  	if (pid != &init_struct_pid) {
  		retval = -ENOMEM;
  		pid = alloc_pid(task_active_pid_ns(p));
  		if (!pid)
  			goto bad_fork_cleanup_namespaces;
6f4e64335   Pavel Emelyanov   pid namespaces: i...
1110
1111
1112
1113
1114
1115
  
  		if (clone_flags & CLONE_NEWPID) {
  			retval = pid_ns_prepare_proc(task_active_pid_ns(p));
  			if (retval < 0)
  				goto bad_fork_free_pid;
  		}
425fb2b4b   Pavel Emelyanov   pid namespaces: m...
1116
1117
1118
1119
1120
1121
  	}
  
  	p->pid = pid_nr(pid);
  	p->tgid = p->pid;
  	if (clone_flags & CLONE_THREAD)
  		p->tgid = current->tgid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1122
1123
1124
1125
1126
  	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;
42b2dd0a0   Alexey Dobriyan   Shrink task_struc...
1127
  #ifdef CONFIG_FUTEX
8f17d3a50   Ingo Molnar   [PATCH] lightweig...
1128
1129
1130
1131
  	p->robust_list = NULL;
  #ifdef CONFIG_COMPAT
  	p->compat_robust_list = NULL;
  #endif
c87e2837b   Ingo Molnar   [PATCH] pi-futex:...
1132
1133
  	INIT_LIST_HEAD(&p->pi_state_list);
  	p->pi_state_cache = NULL;
42b2dd0a0   Alexey Dobriyan   Shrink task_struc...
1134
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1135
  	/*
f9a3879ab   GOTO Masanori   [PATCH] Fix sigal...
1136
1137
1138
1139
1140
1141
  	 * 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
1142
1143
1144
1145
  	 * 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...
1146
1147
1148
  #ifdef TIF_SYSCALL_EMU
  	clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1149
1150
1151
  
  	/* Our parent execution domain becomes current domain
  	   These must match for thread signalling to apply */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1152
1153
1154
1155
1156
1157
  	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
1158
1159
1160
1161
1162
  	/*
  	 * 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...
1163
  	INIT_LIST_HEAD(&p->thread_group);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1164
1165
  	INIT_LIST_HEAD(&p->ptrace_children);
  	INIT_LIST_HEAD(&p->ptrace_list);
b4f48b636   Paul Menage   Task Control Grou...
1166
1167
1168
1169
1170
  	/* Now that the task is set up, run cgroup callbacks if
  	 * necessary. We need to run them before the task is visible
  	 * on the tasklist. */
  	cgroup_fork_callbacks(p);
  	cgroup_callbacks_done = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1171
1172
  	/* Need tasklist lock for parent etc handling! */
  	write_lock_irq(&tasklist_lock);
5b160f5ec   Oleg Nesterov   [PATCH] copy_proc...
1173
1174
  	/* for sys_ioprio_set(IOPRIO_WHO_PGRP) */
  	p->ioprio = current->ioprio;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1175
  	/*
476d139c2   Nick Piggin   [PATCH] sched: co...
1176
1177
1178
1179
1180
1181
1182
  	 * 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
1183
1184
  	 */
  	p->cpus_allowed = current->cpus_allowed;
26ff6ad97   Srivatsa Vaddagiri   [PATCH] CPU hotpl...
1185
1186
  	if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed) ||
  			!cpu_online(task_cpu(p))))
476d139c2   Nick Piggin   [PATCH] sched: co...
1187
  		set_task_cpu(p, smp_processor_id());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1188

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1189
1190
1191
1192
1193
1194
  	/* 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_...
1195
  	spin_lock(&current->sighand->siglock);
4a2c7a783   Oleg Nesterov   [PATCH] make fork...
1196
1197
1198
1199
1200
1201
1202
1203
1204
  
  	/*
  	 * 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).
   	 */
23ff44402   Daniel Walker   whitespace fixes:...
1205
  	recalc_sigpending();
4a2c7a783   Oleg Nesterov   [PATCH] make fork...
1206
1207
1208
1209
  	if (signal_pending(current)) {
  		spin_unlock(&current->sighand->siglock);
  		write_unlock_irq(&tasklist_lock);
  		retval = -ERESTARTNOINTR;
425fb2b4b   Pavel Emelyanov   pid namespaces: m...
1210
  		goto bad_fork_free_pid;
4a2c7a783   Oleg Nesterov   [PATCH] make fork...
1211
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1212
  	if (clone_flags & CLONE_THREAD) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1213
  		p->group_leader = current->group_leader;
47e65328a   Oleg Nesterov   [PATCH] pids: kil...
1214
  		list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1215

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
  		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
1230
  	}
73b9ebfe1   Oleg Nesterov   [PATCH] pidhash: ...
1231
1232
1233
1234
1235
1236
  	if (likely(p->pid)) {
  		add_parent(p);
  		if (unlikely(p->ptrace & PT_PTRACED))
  			__ptrace_link(p, current->parent);
  
  		if (thread_group_leader(p)) {
30e49c263   Pavel Emelyanov   pid namespaces: a...
1237
1238
1239
  			if (clone_flags & CLONE_NEWPID) {
  				p->nsproxy->pid_ns->child_reaper = p;
  				p->signal->tty = NULL;
9a2e70572   Pavel Emelyanov   Isolate the expli...
1240
  				set_task_pgrp(p, p->pid);
30e49c263   Pavel Emelyanov   pid namespaces: a...
1241
1242
1243
1244
1245
  				set_task_session(p, p->pid);
  				attach_pid(p, PIDTYPE_PGID, pid);
  				attach_pid(p, PIDTYPE_SID, pid);
  			} else {
  				p->signal->tty = current->signal->tty;
9a2e70572   Pavel Emelyanov   Isolate the expli...
1246
  				set_task_pgrp(p, task_pgrp_nr(current));
30e49c263   Pavel Emelyanov   pid namespaces: a...
1247
1248
1249
1250
1251
1252
  				set_task_session(p, task_session_nr(current));
  				attach_pid(p, PIDTYPE_PGID,
  						task_pgrp(current));
  				attach_pid(p, PIDTYPE_SID,
  						task_session(current));
  			}
73b9ebfe1   Oleg Nesterov   [PATCH] pidhash: ...
1253

5e85d4abe   Eric W. Biederman   [PATCH] task: Mak...
1254
  			list_add_tail_rcu(&p->tasks, &init_task.tasks);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1255
  			__get_cpu_var(process_counts)++;
73b9ebfe1   Oleg Nesterov   [PATCH] pidhash: ...
1256
  		}
85868995d   Sukadev Bhattiprolu   Use struct pid pa...
1257
  		attach_pid(p, PIDTYPE_PID, pid);
73b9ebfe1   Oleg Nesterov   [PATCH] pidhash: ...
1258
  		nr_threads++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1259
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1260
  	total_forks++;
3f17da699   Oleg Nesterov   [PATCH] fix kill_...
1261
  	spin_unlock(&current->sighand->siglock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1262
  	write_unlock_irq(&tasklist_lock);
c13cf856c   Andrew Morton   [PATCH] fork.c: p...
1263
  	proc_fork_connector(p);
817929ec2   Paul Menage   Task Control Grou...
1264
  	cgroup_post_fork(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1265
  	return p;
425fb2b4b   Pavel Emelyanov   pid namespaces: m...
1266
1267
1268
  bad_fork_free_pid:
  	if (pid != &init_struct_pid)
  		free_pid(pid);
ab516013a   Serge E. Hallyn   [PATCH] namespace...
1269
  bad_fork_cleanup_namespaces:
444f378b2   Linus Torvalds   Revert "[PATCH] n...
1270
  	exit_task_namespaces(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1271
1272
1273
1274
1275
1276
  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...
1277
  	cleanup_signal(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1278
  bad_fork_cleanup_sighand:
a7e5328a0   Oleg Nesterov   [PATCH] cleanup _...
1279
  	__cleanup_sighand(p->sighand);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
  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);
b4f48b636   Paul Menage   Task Control Grou...
1293
  bad_fork_cleanup_cgroup:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1294
  #endif
b4f48b636   Paul Menage   Task Control Grou...
1295
  	cgroup_exit(p, cgroup_callbacks_done);
35df17c57   Shailabh Nagar   [PATCH] task dela...
1296
  	delayacct_tsk_free(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1297
1298
1299
  	if (p->binfmt)
  		module_put(p->binfmt->module);
  bad_fork_cleanup_put_domain:
a1261f546   Al Viro   [PATCH] m68k: int...
1300
  	module_put(task_thread_info(p)->exec_domain->module);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1301
1302
1303
1304
1305
1306
  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...
1307
1308
  fork_out:
  	return ERR_PTR(retval);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1309
  }
f95d47caa   Jeremy Fitzhardinge   [PATCH] i386: Use...
1310
  noinline struct pt_regs * __devinit __attribute__((weak)) idle_regs(struct pt_regs *regs)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1311
1312
1313
1314
  {
  	memset(regs, 0, sizeof(struct pt_regs));
  	return regs;
  }
9abcf40b1   Al Viro   [PATCH] fork_idle...
1315
  struct task_struct * __cpuinit fork_idle(int cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1316
  {
36c8b5868   Ingo Molnar   [PATCH] sched: cl...
1317
  	struct task_struct *task;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1318
  	struct pt_regs regs;
30e49c263   Pavel Emelyanov   pid namespaces: a...
1319
  	task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL,
85868995d   Sukadev Bhattiprolu   Use struct pid pa...
1320
  				&init_struct_pid);
753ca4f31   Akinobu Mita   [PATCH] fix copy_...
1321
1322
  	if (!IS_ERR(task))
  		init_idle(task, cpu);
73b9ebfe1   Oleg Nesterov   [PATCH] pidhash: ...
1323

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1324
1325
  	return task;
  }
a39bc5169   Alexey Dobriyan   Uninline fork.c/e...
1326
  static int fork_traceflag(unsigned clone_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
  {
  	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: ...
1357
  	long nr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1358

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1359
1360
1361
1362
1363
  	if (unlikely(current->ptrace)) {
  		trace = fork_traceflag (clone_flags);
  		if (trace)
  			clone_flags |= CLONE_PTRACE;
  	}
a6f5e0637   Sukadev Bhattiprolu   pid namespaces: m...
1364
  	p = copy_process(clone_flags, stack_start, regs, stack_size,
30e49c263   Pavel Emelyanov   pid namespaces: a...
1365
  			child_tidptr, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1366
1367
1368
1369
1370
1371
  	/*
  	 * 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;
30e49c263   Pavel Emelyanov   pid namespaces: a...
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
  		/*
  		 * this is enough to call pid_nr_ns here, but this if
  		 * improves optimisation of regular fork()
  		 */
  		nr = (clone_flags & CLONE_NEWPID) ?
  			task_pid_nr_ns(p, current->nsproxy->pid_ns) :
  				task_pid_vnr(p);
  
  		if (clone_flags & CLONE_PARENT_SETTID)
  			put_user(nr, parent_tidptr);
a6f5e0637   Sukadev Bhattiprolu   pid namespaces: m...
1382

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
  		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: ...
1402
  			current->ptrace_message = nr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1403
1404
1405
1406
  			ptrace_notify ((trace << 8) | SIGTRAP);
  		}
  
  		if (clone_flags & CLONE_VFORK) {
ba96a0c88   Rafael J. Wysocki   freezer: fix vfor...
1407
  			freezer_do_not_count();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1408
  			wait_for_completion(&vfork);
ba96a0c88   Rafael J. Wysocki   freezer: fix vfor...
1409
  			freezer_count();
9f59ce5d0   Chuck Ebbert   [PATCH] ptrace: m...
1410
1411
  			if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) {
  				current->ptrace_message = nr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1412
  				ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
9f59ce5d0   Chuck Ebbert   [PATCH] ptrace: m...
1413
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1414
1415
  		}
  	} else {
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
1416
  		nr = PTR_ERR(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1417
  	}
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
1418
  	return nr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1419
  }
5fd63b308   Ravikiran G Thirumalai   [PATCH] x86_64: I...
1420
1421
1422
  #ifndef ARCH_MIN_MMSTRUCT_ALIGN
  #define ARCH_MIN_MMSTRUCT_ALIGN 0
  #endif
4ba9b9d0b   Christoph Lameter   Slab API: remove ...
1423
  static void sighand_ctor(struct kmem_cache *cachep, void *data)
aa1757f90   Oleg Nesterov   [PATCH] convert s...
1424
1425
  {
  	struct sighand_struct *sighand = data;
a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
1426
  	spin_lock_init(&sighand->siglock);
b8fceee17   Davide Libenzi   signalfd simplifi...
1427
  	init_waitqueue_head(&sighand->signalfd_wqh);
aa1757f90   Oleg Nesterov   [PATCH] convert s...
1428
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1429
1430
1431
1432
  void __init proc_caches_init(void)
  {
  	sighand_cachep = kmem_cache_create("sighand_cache",
  			sizeof(struct sighand_struct), 0,
aa1757f90   Oleg Nesterov   [PATCH] convert s...
1433
  			SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU,
20c2df83d   Paul Mundt   mm: Remove slab d...
1434
  			sighand_ctor);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1435
1436
  	signal_cachep = kmem_cache_create("signal_cache",
  			sizeof(struct signal_struct), 0,
20c2df83d   Paul Mundt   mm: Remove slab d...
1437
1438
  			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
  	files_cachep = kmem_cache_create("files_cache",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1439
  			sizeof(struct files_struct), 0,
20c2df83d   Paul Mundt   mm: Remove slab d...
1440
1441
  			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
  	fs_cachep = kmem_cache_create("fs_cache",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1442
  			sizeof(struct fs_struct), 0,
20c2df83d   Paul Mundt   mm: Remove slab d...
1443
  			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444
1445
  	vm_area_cachep = kmem_cache_create("vm_area_struct",
  			sizeof(struct vm_area_struct), 0,
20c2df83d   Paul Mundt   mm: Remove slab d...
1446
  			SLAB_PANIC, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1447
  	mm_cachep = kmem_cache_create("mm_struct",
5fd63b308   Ravikiran G Thirumalai   [PATCH] x86_64: I...
1448
  			sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
20c2df83d   Paul Mundt   mm: Remove slab d...
1449
  			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1450
  }
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1451

cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1452
1453
1454
1455
  /*
   * Check constraints on flags passed to the unshare system call and
   * force unsharing of additional process context as appropriate.
   */
a39bc5169   Alexey Dobriyan   Uninline fork.c/e...
1456
  static void check_unshare_flags(unsigned long *flags_ptr)
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
  {
  	/*
  	 * 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...
1498
   * Unshare the filesystem structure if it is being shared
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1499
1500
1501
1502
1503
1504
   */
  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...
1505
1506
1507
1508
1509
  	    (fs && atomic_read(&fs->count) > 1)) {
  		*new_fsp = __copy_fs_struct(current->fs);
  		if (!*new_fsp)
  			return -ENOMEM;
  	}
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1510
1511
1512
1513
1514
  
  	return 0;
  }
  
  /*
dae3c5a0b   Oleg Nesterov   [PATCH] sys_unsha...
1515
   * Unsharing of sighand is not supported yet
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1516
1517
1518
1519
   */
  static int unshare_sighand(unsigned long unshare_flags, struct sighand_struct **new_sighp)
  {
  	struct sighand_struct *sigh = current->sighand;
dae3c5a0b   Oleg Nesterov   [PATCH] sys_unsha...
1520
  	if ((unshare_flags & CLONE_SIGHAND) && atomic_read(&sigh->count) > 1)
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1521
1522
1523
1524
1525
1526
  		return -EINVAL;
  	else
  		return 0;
  }
  
  /*
a0a7ec308   JANAK DESAI   [PATCH] unshare s...
1527
   * Unshare vm if it is being shared
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1528
1529
1530
1531
1532
1533
   */
  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...
1534
  	    (mm && atomic_read(&mm->mm_users) > 1)) {
2d61b8677   Oleg Nesterov   [PATCH] disable u...
1535
  		return -EINVAL;
a0a7ec308   JANAK DESAI   [PATCH] unshare s...
1536
  	}
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1537
1538
  
  	return 0;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1539
1540
1541
  }
  
  /*
a016f3389   JANAK DESAI   [PATCH] unshare s...
1542
   * Unshare file descriptor table if it is being shared
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1543
1544
1545
1546
   */
  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...
1547
  	int error = 0;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1548
1549
  
  	if ((unshare_flags & CLONE_FILES) &&
a016f3389   JANAK DESAI   [PATCH] unshare s...
1550
1551
1552
1553
1554
  	    (fd && atomic_read(&fd->count) > 1)) {
  		*new_fdp = dup_fd(fd, &error);
  		if (!*new_fdp)
  			return error;
  	}
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
  
  	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;
  }
  
  /*
   * 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;
dae3c5a0b   Oleg Nesterov   [PATCH] sys_unsha...
1583
  	struct sighand_struct *new_sigh = NULL;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1584
1585
1586
  	struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
  	struct files_struct *fd, *new_fd = NULL;
  	struct sem_undo_list *new_ulist = NULL;
cf7b708c8   Pavel Emelyanov   Make access to ta...
1587
  	struct nsproxy *new_nsproxy = NULL;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1588
1589
  
  	check_unshare_flags(&unshare_flags);
06f9d4f94   Eric W. Biederman   [PATCH] unshare: ...
1590
1591
1592
  	/* 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...
1593
  				CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
9dd776b6d   Eric W. Biederman   [NET]: Add networ...
1594
1595
  				CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWUSER|
  				CLONE_NEWNET))
06f9d4f94   Eric W. Biederman   [PATCH] unshare: ...
1596
  		goto bad_unshare_out;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1597
1598
1599
1600
  	if ((err = unshare_thread(unshare_flags)))
  		goto bad_unshare_out;
  	if ((err = unshare_fs(unshare_flags, &new_fs)))
  		goto bad_unshare_cleanup_thread;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1601
  	if ((err = unshare_sighand(unshare_flags, &new_sigh)))
e3222c4ec   Badari Pulavarty   Merge sys_clone()...
1602
  		goto bad_unshare_cleanup_fs;
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1603
1604
1605
1606
1607
1608
  	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;
e3222c4ec   Badari Pulavarty   Merge sys_clone()...
1609
1610
  	if ((err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy,
  			new_fs)))
071df104f   Serge E. Hallyn   [PATCH] namespace...
1611
  		goto bad_unshare_cleanup_semundo;
c0b2fc316   Serge Hallyn   [PATCH] uts: copy...
1612

e3222c4ec   Badari Pulavarty   Merge sys_clone()...
1613
  	if (new_fs ||  new_mm || new_fd || new_ulist || new_nsproxy) {
ab516013a   Serge E. Hallyn   [PATCH] namespace...
1614

c0b2fc316   Serge Hallyn   [PATCH] uts: copy...
1615
  		if (new_nsproxy) {
cf7b708c8   Pavel Emelyanov   Make access to ta...
1616
1617
  			switch_task_namespaces(current, new_nsproxy);
  			new_nsproxy = NULL;
c0b2fc316   Serge Hallyn   [PATCH] uts: copy...
1618
  		}
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1619

cf7b708c8   Pavel Emelyanov   Make access to ta...
1620
  		task_lock(current);
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1621
1622
1623
1624
1625
  		if (new_fs) {
  			fs = current->fs;
  			current->fs = new_fs;
  			new_fs = fs;
  		}
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
  		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;
  		}
  
  		task_unlock(current);
  	}
c0b2fc316   Serge Hallyn   [PATCH] uts: copy...
1643
  	if (new_nsproxy)
444f378b2   Linus Torvalds   Revert "[PATCH] n...
1644
  		put_nsproxy(new_nsproxy);
c0b2fc316   Serge Hallyn   [PATCH] uts: copy...
1645

ab516013a   Serge E. Hallyn   [PATCH] namespace...
1646
  bad_unshare_cleanup_semundo:
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
  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);
cf2e340f4   JANAK DESAI   [PATCH] unshare s...
1659
1660
1661
1662
1663
1664
1665
1666
  bad_unshare_cleanup_fs:
  	if (new_fs)
  		put_fs_struct(new_fs);
  
  bad_unshare_cleanup_thread:
  bad_unshare_out:
  	return err;
  }