diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 17 | 
1 files changed, 10 insertions, 7 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 98b450876f93..b7e9d60a675d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -300,7 +300,7 @@ out:  #ifdef CONFIG_MMU  static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)  { -	struct vm_area_struct *mpnt, *tmp, **pprev; +	struct vm_area_struct *mpnt, *tmp, *prev, **pprev;  	struct rb_node **rb_link, *rb_parent;  	int retval;  	unsigned long charge; @@ -328,6 +328,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)  	if (retval)  		goto out; +	prev = NULL;  	for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {  		struct file *file; @@ -359,7 +360,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)  			goto fail_nomem_anon_vma_fork;  		tmp->vm_flags &= ~VM_LOCKED;  		tmp->vm_mm = mm; -		tmp->vm_next = NULL; +		tmp->vm_next = tmp->vm_prev = NULL;  		file = tmp->vm_file;  		if (file) {  			struct inode *inode = file->f_path.dentry->d_inode; @@ -392,6 +393,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)  		 */  		*pprev = tmp;  		pprev = &tmp->vm_next; +		tmp->vm_prev = prev; +		prev = tmp;  		__vma_link_rb(mm, tmp, rb_link, rb_parent);  		rb_link = &tmp->vm_rb.rb_right; @@ -752,13 +755,13 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)  	struct fs_struct *fs = current->fs;  	if (clone_flags & CLONE_FS) {  		/* tsk->fs is already what we want */ -		write_lock(&fs->lock); +		spin_lock(&fs->lock);  		if (fs->in_exec) { -			write_unlock(&fs->lock); +			spin_unlock(&fs->lock);  			return -EAGAIN;  		}  		fs->users++; -		write_unlock(&fs->lock); +		spin_unlock(&fs->lock);  		return 0;  	}  	tsk->fs = copy_fs_struct(fs); @@ -1676,13 +1679,13 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)  		if (new_fs) {  			fs = current->fs; -			write_lock(&fs->lock); +			spin_lock(&fs->lock);  			current->fs = new_fs;  			if (--fs->users)  				new_fs = NULL;  			else  				new_fs = fs; -			write_unlock(&fs->lock); +			spin_unlock(&fs->lock);  		}  		if (new_mm) {  | 
