diff options
Diffstat (limited to 'mm/madvise.c')
-rw-r--r-- | mm/madvise.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/mm/madvise.c b/mm/madvise.c index 2b7cf0400a21..ae0ae3ea299a 100644 --- a/mm/madvise.c +++ b/mm/madvise.c | |||
@@ -140,6 +140,36 @@ static long madvise_dontneed(struct vm_area_struct * vma, | |||
140 | return 0; | 140 | return 0; |
141 | } | 141 | } |
142 | 142 | ||
143 | /* | ||
144 | * Application wants to free up the pages and associated backing store. | ||
145 | * This is effectively punching a hole into the middle of a file. | ||
146 | * | ||
147 | * NOTE: Currently, only shmfs/tmpfs is supported for this operation. | ||
148 | * Other filesystems return -ENOSYS. | ||
149 | */ | ||
150 | static long madvise_remove(struct vm_area_struct *vma, | ||
151 | unsigned long start, unsigned long end) | ||
152 | { | ||
153 | struct address_space *mapping; | ||
154 | loff_t offset, endoff; | ||
155 | |||
156 | if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB)) | ||
157 | return -EINVAL; | ||
158 | |||
159 | if (!vma->vm_file || !vma->vm_file->f_mapping | ||
160 | || !vma->vm_file->f_mapping->host) { | ||
161 | return -EINVAL; | ||
162 | } | ||
163 | |||
164 | mapping = vma->vm_file->f_mapping; | ||
165 | |||
166 | offset = (loff_t)(start - vma->vm_start) | ||
167 | + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); | ||
168 | endoff = (loff_t)(end - vma->vm_start - 1) | ||
169 | + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); | ||
170 | return vmtruncate_range(mapping->host, offset, endoff); | ||
171 | } | ||
172 | |||
143 | static long | 173 | static long |
144 | madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, | 174 | madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, |
145 | unsigned long start, unsigned long end, int behavior) | 175 | unsigned long start, unsigned long end, int behavior) |
@@ -152,6 +182,9 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, | |||
152 | case MADV_RANDOM: | 182 | case MADV_RANDOM: |
153 | error = madvise_behavior(vma, prev, start, end, behavior); | 183 | error = madvise_behavior(vma, prev, start, end, behavior); |
154 | break; | 184 | break; |
185 | case MADV_REMOVE: | ||
186 | error = madvise_remove(vma, start, end); | ||
187 | break; | ||
155 | 188 | ||
156 | case MADV_WILLNEED: | 189 | case MADV_WILLNEED: |
157 | error = madvise_willneed(vma, prev, start, end); | 190 | error = madvise_willneed(vma, prev, start, end); |
@@ -190,6 +223,8 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, | |||
190 | * some pages ahead. | 223 | * some pages ahead. |
191 | * MADV_DONTNEED - the application is finished with the given range, | 224 | * MADV_DONTNEED - the application is finished with the given range, |
192 | * so the kernel can free resources associated with it. | 225 | * so the kernel can free resources associated with it. |
226 | * MADV_REMOVE - the application wants to free up the given range of | ||
227 | * pages and associated backing store. | ||
193 | * | 228 | * |
194 | * return values: | 229 | * return values: |
195 | * zero - success | 230 | * zero - success |