git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge to kernel-2.6.20-1.2949.fc6.vs2.2.0.1
[linux-2.6.git]
/
mm
/
madvise.c
diff --git
a/mm/madvise.c
b/mm/madvise.c
index
4e19615
..
603c525
100644
(file)
--- a/
mm/madvise.c
+++ b/
mm/madvise.c
@@
-155,10
+155,14
@@
static long madvise_dontneed(struct vm_area_struct * vma,
* Other filesystems return -ENOSYS.
*/
static long madvise_remove(struct vm_area_struct *vma,
* Other filesystems return -ENOSYS.
*/
static long madvise_remove(struct vm_area_struct *vma,
+ struct vm_area_struct **prev,
unsigned long start, unsigned long end)
{
struct address_space *mapping;
unsigned long start, unsigned long end)
{
struct address_space *mapping;
- loff_t offset, endoff;
+ loff_t offset, endoff;
+ int error;
+
+ *prev = NULL; /* tell sys_madvise we drop mmap_sem */
if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB))
return -EINVAL;
if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB))
return -EINVAL;
@@
-177,7
+181,12
@@
static long madvise_remove(struct vm_area_struct *vma,
+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
endoff = (loff_t)(end - vma->vm_start - 1)
+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
endoff = (loff_t)(end - vma->vm_start - 1)
+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
- return vmtruncate_range(mapping->host, offset, endoff);
+
+ /* vmtruncate_range needs to take i_mutex and i_alloc_sem */
+ up_write(¤t->mm->mmap_sem);
+ error = vmtruncate_range(mapping->host, offset, endoff);
+ down_write(¤t->mm->mmap_sem);
+ return error;
}
static long
}
static long
@@
-199,7
+208,7
@@
madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
error = madvise_behavior(vma, prev, start, end, behavior);
break;
case MADV_REMOVE:
error = madvise_behavior(vma, prev, start, end, behavior);
break;
case MADV_REMOVE:
- error = madvise_remove(vma, start, end);
+ error = madvise_remove(vma,
prev,
start, end);
break;
case MADV_WILLNEED:
break;
case MADV_WILLNEED:
@@
-312,12
+321,15
@@
asmlinkage long sys_madvise(unsigned long start, size_t len_in, int behavior)
if (error)
goto out;
start = tmp;
if (error)
goto out;
start = tmp;
- if (start < prev->vm_end)
+ if (
prev &&
start < prev->vm_end)
start = prev->vm_end;
error = unmapped_error;
if (start >= end)
goto out;
start = prev->vm_end;
error = unmapped_error;
if (start >= end)
goto out;
- vma = prev->vm_next;
+ if (prev)
+ vma = prev->vm_next;
+ else /* madvise_remove dropped mmap_sem */
+ vma = find_vma(current->mm, start);
}
out:
up_write(¤t->mm->mmap_sem);
}
out:
up_write(¤t->mm->mmap_sem);