aboutsummaryrefslogtreecommitdiffstats
path: root/mm/madvise.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/madvise.c')
-rw-r--r--mm/madvise.c39
1 files changed, 13 insertions, 26 deletions
diff --git a/mm/madvise.c b/mm/madvise.c
index 76eb4193acd..66c31264f06 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
211madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, 215madvise_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
247static int 230static 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