#include <linux/mman.h>
#include <linux/pagemap.h>
#include <linux/syscalls.h>
-
+#include <linux/hugetlb.h>
/*
* We can potentially split a vm area into separate
unsigned long end, int behavior)
{
struct mm_struct * mm = vma->vm_mm;
- int error;
+ int error = 0;
if (start != vma->vm_start) {
error = split_vma(mm, vma, start, 1);
if (error)
- return -EAGAIN;
+ goto out;
}
if (end != vma->vm_end) {
error = split_vma(mm, vma, end, 0);
if (error)
- return -EAGAIN;
+ goto out;
}
/*
break;
}
- return 0;
+out:
+ if (error == -ENOMEM)
+ error = -EAGAIN;
+ return error;
}
/*
static long madvise_dontneed(struct vm_area_struct * vma,
unsigned long start, unsigned long end)
{
- if (vma->vm_flags & VM_LOCKED)
+ if ((vma->vm_flags & VM_LOCKED) || is_vm_hugetlb_page(vma))
return -EINVAL;
if (unlikely(vma->vm_flags & VM_NONLINEAR)) {
goto out;
if (start != vma->vm_start) {
- if (split_vma(mm, vma, start, 1)) {
- ret = -EAGAIN;
+ ret = split_vma(mm, vma, start, 1);
+ if (ret)
goto out;
- }
}
if (end != vma->vm_end) {
- if (split_vma(mm, vma, end, 0)) {
- ret = -EAGAIN;
+ ret = split_vma(mm, vma, end, 0);
+ if (ret)
goto out;
- }
}
/*
vma->vm_mm->locked_vm -= pages;
out:
+ if (ret == -ENOMEM)
+ ret = -EAGAIN;
return ret;
}
struct mempolicy *pol;
struct vm_area_struct *new;
+ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
+ return -EINVAL;
+
if (mm->map_count >= sysctl_max_map_count)
return -ENOMEM;
* places tmp vma above, and higher split_vma places tmp vma below.
*/
if (start > mpnt->vm_start) {
- if (is_vm_hugetlb_page(mpnt) && (start & ~HPAGE_MASK))
- return -EINVAL;
- if (split_vma(mm, mpnt, start, 0))
- return -ENOMEM;
+ 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) {
- if (is_vm_hugetlb_page(last) && (end & ~HPAGE_MASK))
- return -EINVAL;
- if (split_vma(mm, last, end, 1))
- return -ENOMEM;
+ int error = split_vma(mm, last, end, 1);
+ if (error)
+ return error;
}
mpnt = prev? prev->vm_next: mm->mmap;