diff options
Diffstat (limited to 'mm/fremap.c')
-rw-r--r-- | mm/fremap.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/mm/fremap.c b/mm/fremap.c index 5f50d736a037..c395b1abf082 100644 --- a/mm/fremap.c +++ b/mm/fremap.c | |||
@@ -181,6 +181,25 @@ asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size, | |||
181 | goto retry; | 181 | goto retry; |
182 | } | 182 | } |
183 | mapping = vma->vm_file->f_mapping; | 183 | mapping = vma->vm_file->f_mapping; |
184 | /* | ||
185 | * page_mkclean doesn't work on nonlinear vmas, so if | ||
186 | * dirty pages need to be accounted, emulate with linear | ||
187 | * vmas. | ||
188 | */ | ||
189 | if (mapping_cap_account_dirty(mapping)) { | ||
190 | unsigned long addr; | ||
191 | |||
192 | flags &= MAP_NONBLOCK; | ||
193 | addr = mmap_region(vma->vm_file, start, size, | ||
194 | flags, vma->vm_flags, pgoff, 1); | ||
195 | if (IS_ERR_VALUE(addr)) { | ||
196 | err = addr; | ||
197 | } else { | ||
198 | BUG_ON(addr != start); | ||
199 | err = 0; | ||
200 | } | ||
201 | goto out; | ||
202 | } | ||
184 | spin_lock(&mapping->i_mmap_lock); | 203 | spin_lock(&mapping->i_mmap_lock); |
185 | flush_dcache_mmap_lock(mapping); | 204 | flush_dcache_mmap_lock(mapping); |
186 | vma->vm_flags |= VM_NONLINEAR; | 205 | vma->vm_flags |= VM_NONLINEAR; |