|
@@ -41,7 +41,7 @@ static long madvise_behavior(struct vm_area_struct * vma,
|
|
|
struct mm_struct * mm = vma->vm_mm;
|
|
|
int error = 0;
|
|
|
pgoff_t pgoff;
|
|
|
- int new_flags = vma->vm_flags;
|
|
|
+ unsigned long new_flags = vma->vm_flags;
|
|
|
|
|
|
switch (behavior) {
|
|
|
case MADV_NORMAL:
|
|
@@ -57,6 +57,10 @@ static long madvise_behavior(struct vm_area_struct * vma,
|
|
|
new_flags |= VM_DONTCOPY;
|
|
|
break;
|
|
|
case MADV_DOFORK:
|
|
|
+ if (vma->vm_flags & VM_IO) {
|
|
|
+ error = -EINVAL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
new_flags &= ~VM_DONTCOPY;
|
|
|
break;
|
|
|
}
|
|
@@ -211,37 +215,16 @@ static long
|
|
|
madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
|
|
|
unsigned long start, unsigned long end, int behavior)
|
|
|
{
|
|
|
- long error;
|
|
|
-
|
|
|
switch (behavior) {
|
|
|
- case MADV_DOFORK:
|
|
|
- if (vma->vm_flags & VM_IO) {
|
|
|
- error = -EINVAL;
|
|
|
- break;
|
|
|
- }
|
|
|
- case MADV_DONTFORK:
|
|
|
- case MADV_NORMAL:
|
|
|
- case MADV_SEQUENTIAL:
|
|
|
- case MADV_RANDOM:
|
|
|
- error = madvise_behavior(vma, prev, start, end, behavior);
|
|
|
- break;
|
|
|
case MADV_REMOVE:
|
|
|
- error = madvise_remove(vma, prev, start, end);
|
|
|
- break;
|
|
|
-
|
|
|
+ return madvise_remove(vma, prev, start, end);
|
|
|
case MADV_WILLNEED:
|
|
|
- error = madvise_willneed(vma, prev, start, end);
|
|
|
- break;
|
|
|
-
|
|
|
+ return madvise_willneed(vma, prev, start, end);
|
|
|
case MADV_DONTNEED:
|
|
|
- error = madvise_dontneed(vma, prev, start, end);
|
|
|
- break;
|
|
|
-
|
|
|
+ return madvise_dontneed(vma, prev, start, end);
|
|
|
default:
|
|
|
- BUG();
|
|
|
- break;
|
|
|
+ return madvise_behavior(vma, prev, start, end, behavior);
|
|
|
}
|
|
|
- return error;
|
|
|
}
|
|
|
|
|
|
static int
|
|
@@ -262,6 +245,7 @@ madvise_behavior_valid(int behavior)
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
/*
|
|
|
* The madvise(2) system call.
|
|
|
*
|
|
@@ -286,6 +270,9 @@ madvise_behavior_valid(int behavior)
|
|
|
* so the kernel can free resources associated with it.
|
|
|
* MADV_REMOVE - the application wants to free up the given range of
|
|
|
* pages and associated backing store.
|
|
|
+ * MADV_DONTFORK - omit this area from child's address space when forking:
|
|
|
+ * typically, to avoid COWing pages pinned by get_user_pages().
|
|
|
+ * MADV_DOFORK - cancel MADV_DONTFORK: no longer omit this area when forking.
|
|
|
*
|
|
|
* return values:
|
|
|
* zero - success
|