diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 20f3b1f33f0e..54d5318f8d3f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -2128,22 +2128,27 @@ page_not_uptodate: | |||
2128 | } | 2128 | } |
2129 | EXPORT_SYMBOL(filemap_fault); | 2129 | EXPORT_SYMBOL(filemap_fault); |
2130 | 2130 | ||
2131 | void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf) | 2131 | void filemap_map_pages(struct fault_env *fe, |
2132 | pgoff_t start_pgoff, pgoff_t end_pgoff) | ||
2132 | { | 2133 | { |
2133 | struct radix_tree_iter iter; | 2134 | struct radix_tree_iter iter; |
2134 | void **slot; | 2135 | void **slot; |
2135 | struct file *file = vma->vm_file; | 2136 | struct file *file = fe->vma->vm_file; |
2136 | struct address_space *mapping = file->f_mapping; | 2137 | struct address_space *mapping = file->f_mapping; |
2138 | pgoff_t last_pgoff = start_pgoff; | ||
2137 | loff_t size; | 2139 | loff_t size; |
2138 | struct page *page; | 2140 | struct page *page; |
2139 | unsigned long address = (unsigned long) vmf->virtual_address; | ||
2140 | unsigned long addr; | ||
2141 | pte_t *pte; | ||
2142 | 2141 | ||
2143 | rcu_read_lock(); | 2142 | rcu_read_lock(); |
2144 | radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, vmf->pgoff) { | 2143 | radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, |
2145 | if (iter.index > vmf->max_pgoff) | 2144 | start_pgoff) { |
2145 | if (iter.index > end_pgoff) | ||
2146 | break; | 2146 | break; |
2147 | fe->pte += iter.index - last_pgoff; | ||
2148 | fe->address += (iter.index - last_pgoff) << PAGE_SHIFT; | ||
2149 | last_pgoff = iter.index; | ||
2150 | if (!pte_none(*fe->pte)) | ||
2151 | goto next; | ||
2147 | repeat: | 2152 | repeat: |
2148 | page = radix_tree_deref_slot(slot); | 2153 | page = radix_tree_deref_slot(slot); |
2149 | if (unlikely(!page)) | 2154 | if (unlikely(!page)) |
@@ -2179,14 +2184,9 @@ repeat: | |||
2179 | if (page->index >= size >> PAGE_SHIFT) | 2184 | if (page->index >= size >> PAGE_SHIFT) |
2180 | goto unlock; | 2185 | goto unlock; |
2181 | 2186 | ||
2182 | pte = vmf->pte + page->index - vmf->pgoff; | ||
2183 | if (!pte_none(*pte)) | ||
2184 | goto unlock; | ||
2185 | |||
2186 | if (file->f_ra.mmap_miss > 0) | 2187 | if (file->f_ra.mmap_miss > 0) |
2187 | file->f_ra.mmap_miss--; | 2188 | file->f_ra.mmap_miss--; |
2188 | addr = address + (page->index - vmf->pgoff) * PAGE_SIZE; | 2189 | do_set_pte(fe, page); |
2189 | do_set_pte(vma, addr, page, pte, false, false); | ||
2190 | unlock_page(page); | 2190 | unlock_page(page); |
2191 | goto next; | 2191 | goto next; |
2192 | unlock: | 2192 | unlock: |
@@ -2194,7 +2194,7 @@ unlock: | |||
2194 | skip: | 2194 | skip: |
2195 | put_page(page); | 2195 | put_page(page); |
2196 | next: | 2196 | next: |
2197 | if (iter.index == vmf->max_pgoff) | 2197 | if (iter.index == end_pgoff) |
2198 | break; | 2198 | break; |
2199 | } | 2199 | } |
2200 | rcu_read_unlock(); | 2200 | rcu_read_unlock(); |