spin_unlock(&mm->page_table_lock); 
int do_munmap(struct mm_struct *mm, unsigned long start, size_t len){	unsigned long end;	struct vm_area_struct *mpnt, *prev, *last;	if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)		return -EINVAL;	if ((len = PAGE_ALIGN(len)) == 0)		return -EINVAL;	/* Find the first overlapping VMA */	mpnt = find_vma_prev(mm, start, &prev);	if (!mpnt)		return 0;	/* we have  start < mpnt->vm_end  */	/* if it doesn't overlap, we have nothing.. */	end = start + len;	if (mpnt->vm_start >= end)		return 0;	/*	 * If we need to split any vma, do it now to save pain later.	 *	 * Note: mremap's move_vma VM_ACCOUNT handling assumes a partially	 * unmapped vm_area_struct will remain in use: so lower split_vma	 * places tmp vma above, and higher split_vma places tmp vma below.	 */	if (start > mpnt->vm_start) {		int error = split_vma(mm, mpnt, start, 0);		if (error)			return error;		prev = mpnt;	}	/* Does it split the last one? */	last = find_vma(mm, end);	if (last && end > last->vm_start) {		int error = split_vma(mm, last, end, 1);		if (error)			return error;	}	mpnt = prev? prev->vm_next: mm->mmap;	/*	 * Remove the vma's, and unmap the actual pages	 */	detach_vmas_to_be_unmapped(mm, mpnt, prev, end);	spin_lock(&mm->page_table_lock);	unmap_region(mm, mpnt, prev, start, end);	spin_unlock(&mm->page_table_lock);	/* Fix up all other VM information */	unmap_vma_list(mm, mpnt);	return 0;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/e0da382c92626ad1d7f4b7527d19b80104d67a83/mmap.c/buggy/mm/mmap.c