aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c27
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 /*