diff options
Diffstat (limited to 'mm/madvise.c')
-rw-r--r-- | mm/madvise.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/mm/madvise.c b/mm/madvise.c index 1ccbba5b6674..deff1b64a08c 100644 --- a/mm/madvise.c +++ b/mm/madvise.c | |||
@@ -11,8 +11,10 @@ | |||
11 | #include <linux/mempolicy.h> | 11 | #include <linux/mempolicy.h> |
12 | #include <linux/page-isolation.h> | 12 | #include <linux/page-isolation.h> |
13 | #include <linux/hugetlb.h> | 13 | #include <linux/hugetlb.h> |
14 | #include <linux/falloc.h> | ||
14 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
15 | #include <linux/ksm.h> | 16 | #include <linux/ksm.h> |
17 | #include <linux/fs.h> | ||
16 | 18 | ||
17 | /* | 19 | /* |
18 | * Any behaviour which results in changes to the vma->vm_flags needs to | 20 | * Any behaviour which results in changes to the vma->vm_flags needs to |
@@ -200,8 +202,7 @@ static long madvise_remove(struct vm_area_struct *vma, | |||
200 | struct vm_area_struct **prev, | 202 | struct vm_area_struct **prev, |
201 | unsigned long start, unsigned long end) | 203 | unsigned long start, unsigned long end) |
202 | { | 204 | { |
203 | struct address_space *mapping; | 205 | loff_t offset; |
204 | loff_t offset, endoff; | ||
205 | int error; | 206 | int error; |
206 | 207 | ||
207 | *prev = NULL; /* tell sys_madvise we drop mmap_sem */ | 208 | *prev = NULL; /* tell sys_madvise we drop mmap_sem */ |
@@ -217,16 +218,14 @@ static long madvise_remove(struct vm_area_struct *vma, | |||
217 | if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE)) | 218 | if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE)) |
218 | return -EACCES; | 219 | return -EACCES; |
219 | 220 | ||
220 | mapping = vma->vm_file->f_mapping; | ||
221 | |||
222 | offset = (loff_t)(start - vma->vm_start) | 221 | offset = (loff_t)(start - vma->vm_start) |
223 | + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); | 222 | + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); |
224 | endoff = (loff_t)(end - vma->vm_start - 1) | ||
225 | + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); | ||
226 | 223 | ||
227 | /* vmtruncate_range needs to take i_mutex */ | 224 | /* filesystem's fallocate may need to take i_mutex */ |
228 | up_read(¤t->mm->mmap_sem); | 225 | up_read(¤t->mm->mmap_sem); |
229 | error = vmtruncate_range(mapping->host, offset, endoff); | 226 | error = do_fallocate(vma->vm_file, |
227 | FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, | ||
228 | offset, end - start); | ||
230 | down_read(¤t->mm->mmap_sem); | 229 | down_read(¤t->mm->mmap_sem); |
231 | return error; | 230 | return error; |
232 | } | 231 | } |