diff options
-rw-r--r-- | mm/madvise.c | 39 |
1 files changed, 13 insertions, 26 deletions
diff --git a/mm/madvise.c b/mm/madvise.c index 76eb4193acdd..66c31264f062 100644 --- a/mm/madvise.c +++ b/mm/madvise.c | |||
@@ -41,7 +41,7 @@ static long madvise_behavior(struct vm_area_struct * vma, | |||
41 | struct mm_struct * mm = vma->vm_mm; | 41 | struct mm_struct * mm = vma->vm_mm; |
42 | int error = 0; | 42 | int error = 0; |
43 | pgoff_t pgoff; | 43 | pgoff_t pgoff; |
44 | int new_flags = vma->vm_flags; | 44 | unsigned long new_flags = vma->vm_flags; |
45 | 45 | ||
46 | switch (behavior) { | 46 | switch (behavior) { |
47 | case MADV_NORMAL: | 47 | case MADV_NORMAL: |
@@ -57,6 +57,10 @@ static long madvise_behavior(struct vm_area_struct * vma, | |||
57 | new_flags |= VM_DONTCOPY; | 57 | new_flags |= VM_DONTCOPY; |
58 | break; | 58 | break; |
59 | case MADV_DOFORK: | 59 | case MADV_DOFORK: |
60 | if (vma->vm_flags & VM_IO) { | ||
61 | error = -EINVAL; | ||
62 | goto out; | ||
63 | } | ||
60 | new_flags &= ~VM_DONTCOPY; | 64 | new_flags &= ~VM_DONTCOPY; |
61 | break; | 65 | break; |
62 | } | 66 | } |
@@ -211,37 +215,16 @@ static long | |||
211 | madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, | 215 | madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, |
212 | unsigned long start, unsigned long end, int behavior) | 216 | unsigned long start, unsigned long end, int behavior) |
213 | { | 217 | { |
214 | long error; | ||
215 | |||
216 | switch (behavior) { | 218 | switch (behavior) { |
217 | case MADV_DOFORK: | ||
218 | if (vma->vm_flags & VM_IO) { | ||
219 | error = -EINVAL; | ||
220 | break; | ||
221 | } | ||
222 | case MADV_DONTFORK: | ||
223 | case MADV_NORMAL: | ||
224 | case MADV_SEQUENTIAL: | ||
225 | case MADV_RANDOM: | ||
226 | error = madvise_behavior(vma, prev, start, end, behavior); | ||
227 | break; | ||
228 | case MADV_REMOVE: | 219 | case MADV_REMOVE: |
229 | error = madvise_remove(vma, prev, start, end); | 220 | return madvise_remove(vma, prev, start, end); |
230 | break; | ||
231 | |||
232 | case MADV_WILLNEED: | 221 | case MADV_WILLNEED: |
233 | error = madvise_willneed(vma, prev, start, end); | 222 | return madvise_willneed(vma, prev, start, end); |
234 | break; | ||
235 | |||
236 | case MADV_DONTNEED: | 223 | case MADV_DONTNEED: |
237 | error = madvise_dontneed(vma, prev, start, end); | 224 | return madvise_dontneed(vma, prev, start, end); |
238 | break; | ||
239 | |||
240 | default: | 225 | default: |
241 | BUG(); | 226 | return madvise_behavior(vma, prev, start, end, behavior); |
242 | break; | ||
243 | } | 227 | } |
244 | return error; | ||
245 | } | 228 | } |
246 | 229 | ||
247 | static int | 230 | static int |
@@ -262,6 +245,7 @@ madvise_behavior_valid(int behavior) | |||
262 | return 0; | 245 | return 0; |
263 | } | 246 | } |
264 | } | 247 | } |
248 | |||
265 | /* | 249 | /* |
266 | * The madvise(2) system call. | 250 | * The madvise(2) system call. |
267 | * | 251 | * |
@@ -286,6 +270,9 @@ madvise_behavior_valid(int behavior) | |||
286 | * so the kernel can free resources associated with it. | 270 | * so the kernel can free resources associated with it. |
287 | * MADV_REMOVE - the application wants to free up the given range of | 271 | * MADV_REMOVE - the application wants to free up the given range of |
288 | * pages and associated backing store. | 272 | * pages and associated backing store. |
273 | * MADV_DONTFORK - omit this area from child's address space when forking: | ||
274 | * typically, to avoid COWing pages pinned by get_user_pages(). | ||
275 | * MADV_DOFORK - cancel MADV_DONTFORK: no longer omit this area when forking. | ||
289 | * | 276 | * |
290 | * return values: | 277 | * return values: |
291 | * zero - success | 278 | * zero - success |