diff options
Diffstat (limited to 'mm/filemap_xip.c')
-rw-r--r-- | mm/filemap_xip.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index 8c199f537732..9354ee279b13 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c | |||
@@ -174,6 +174,7 @@ __xip_unmap (struct address_space * mapping, | |||
174 | unsigned long address; | 174 | unsigned long address; |
175 | pte_t *pte; | 175 | pte_t *pte; |
176 | pte_t pteval; | 176 | pte_t pteval; |
177 | struct page *page = ZERO_PAGE(address); | ||
177 | 178 | ||
178 | spin_lock(&mapping->i_mmap_lock); | 179 | spin_lock(&mapping->i_mmap_lock); |
179 | vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { | 180 | vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { |
@@ -185,15 +186,17 @@ __xip_unmap (struct address_space * mapping, | |||
185 | * We need the page_table_lock to protect us from page faults, | 186 | * We need the page_table_lock to protect us from page faults, |
186 | * munmap, fork, etc... | 187 | * munmap, fork, etc... |
187 | */ | 188 | */ |
188 | pte = page_check_address(ZERO_PAGE(address), mm, | 189 | pte = page_check_address(page, mm, address); |
189 | address); | ||
190 | if (!IS_ERR(pte)) { | 190 | if (!IS_ERR(pte)) { |
191 | /* Nuke the page table entry. */ | 191 | /* Nuke the page table entry. */ |
192 | flush_cache_page(vma, address, pte_pfn(*pte)); | 192 | flush_cache_page(vma, address, pte_pfn(*pte)); |
193 | pteval = ptep_clear_flush(vma, address, pte); | 193 | pteval = ptep_clear_flush(vma, address, pte); |
194 | page_remove_rmap(page); | ||
195 | dec_mm_counter(mm, file_rss); | ||
194 | BUG_ON(pte_dirty(pteval)); | 196 | BUG_ON(pte_dirty(pteval)); |
195 | pte_unmap(pte); | 197 | pte_unmap(pte); |
196 | spin_unlock(&mm->page_table_lock); | 198 | spin_unlock(&mm->page_table_lock); |
199 | page_cache_release(page); | ||
197 | } | 200 | } |
198 | } | 201 | } |
199 | spin_unlock(&mapping->i_mmap_lock); | 202 | spin_unlock(&mapping->i_mmap_lock); |
@@ -228,7 +231,7 @@ xip_file_nopage(struct vm_area_struct * area, | |||
228 | 231 | ||
229 | page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0); | 232 | page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0); |
230 | if (!IS_ERR(page)) { | 233 | if (!IS_ERR(page)) { |
231 | return page; | 234 | goto out; |
232 | } | 235 | } |
233 | if (PTR_ERR(page) != -ENODATA) | 236 | if (PTR_ERR(page) != -ENODATA) |
234 | return NULL; | 237 | return NULL; |
@@ -249,6 +252,8 @@ xip_file_nopage(struct vm_area_struct * area, | |||
249 | page = ZERO_PAGE(address); | 252 | page = ZERO_PAGE(address); |
250 | } | 253 | } |
251 | 254 | ||
255 | out: | ||
256 | page_cache_get(page); | ||
252 | return page; | 257 | return page; |
253 | } | 258 | } |
254 | 259 | ||