diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index f6083561dfe0..495da2e9a8b4 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <linux/jiffies.h> | 40 | #include <linux/jiffies.h> |
| 41 | #include <linux/tracehook.h> | 41 | #include <linux/tracehook.h> |
| 42 | #include <linux/futex.h> | 42 | #include <linux/futex.h> |
| 43 | #include <linux/compat.h> | ||
| 43 | #include <linux/task_io_accounting_ops.h> | 44 | #include <linux/task_io_accounting_ops.h> |
| 44 | #include <linux/rcupdate.h> | 45 | #include <linux/rcupdate.h> |
| 45 | #include <linux/ptrace.h> | 46 | #include <linux/ptrace.h> |
| @@ -314,17 +315,20 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
| 314 | file = tmp->vm_file; | 315 | file = tmp->vm_file; |
| 315 | if (file) { | 316 | if (file) { |
| 316 | struct inode *inode = file->f_path.dentry->d_inode; | 317 | struct inode *inode = file->f_path.dentry->d_inode; |
| 318 | struct address_space *mapping = file->f_mapping; | ||
| 319 | |||
| 317 | get_file(file); | 320 | get_file(file); |
| 318 | if (tmp->vm_flags & VM_DENYWRITE) | 321 | if (tmp->vm_flags & VM_DENYWRITE) |
| 319 | atomic_dec(&inode->i_writecount); | 322 | atomic_dec(&inode->i_writecount); |
| 320 | 323 | spin_lock(&mapping->i_mmap_lock); | |
| 321 | /* insert tmp into the share list, just after mpnt */ | 324 | if (tmp->vm_flags & VM_SHARED) |
| 322 | spin_lock(&file->f_mapping->i_mmap_lock); | 325 | mapping->i_mmap_writable++; |
| 323 | tmp->vm_truncate_count = mpnt->vm_truncate_count; | 326 | tmp->vm_truncate_count = mpnt->vm_truncate_count; |
| 324 | flush_dcache_mmap_lock(file->f_mapping); | 327 | flush_dcache_mmap_lock(mapping); |
| 328 | /* insert tmp into the share list, just after mpnt */ | ||
| 325 | vma_prio_tree_add(tmp, mpnt); | 329 | vma_prio_tree_add(tmp, mpnt); |
| 326 | flush_dcache_mmap_unlock(file->f_mapping); | 330 | flush_dcache_mmap_unlock(mapping); |
| 327 | spin_unlock(&file->f_mapping->i_mmap_lock); | 331 | spin_unlock(&mapping->i_mmap_lock); |
| 328 | } | 332 | } |
| 329 | 333 | ||
| 330 | /* | 334 | /* |
| @@ -519,6 +523,16 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) | |||
| 519 | { | 523 | { |
| 520 | struct completion *vfork_done = tsk->vfork_done; | 524 | struct completion *vfork_done = tsk->vfork_done; |
| 521 | 525 | ||
| 526 | /* Get rid of any futexes when releasing the mm */ | ||
| 527 | #ifdef CONFIG_FUTEX | ||
| 528 | if (unlikely(tsk->robust_list)) | ||
| 529 | exit_robust_list(tsk); | ||
| 530 | #ifdef CONFIG_COMPAT | ||
| 531 | if (unlikely(tsk->compat_robust_list)) | ||
| 532 | compat_exit_robust_list(tsk); | ||
| 533 | #endif | ||
| 534 | #endif | ||
| 535 | |||
| 522 | /* Get rid of any cached register state */ | 536 | /* Get rid of any cached register state */ |
| 523 | deactivate_mm(tsk, mm); | 537 | deactivate_mm(tsk, mm); |
| 524 | 538 | ||
| @@ -1387,6 +1401,7 @@ long do_fork(unsigned long clone_flags, | |||
| 1387 | init_completion(&vfork); | 1401 | init_completion(&vfork); |
| 1388 | } | 1402 | } |
| 1389 | 1403 | ||
| 1404 | audit_finish_fork(p); | ||
| 1390 | tracehook_report_clone(trace, regs, clone_flags, nr, p); | 1405 | tracehook_report_clone(trace, regs, clone_flags, nr, p); |
| 1391 | 1406 | ||
| 1392 | /* | 1407 | /* |
