Commit 750b4987b0cd4d408e54cb83a80a067cbe690feb
Committed by
Andi Kleen
1 parent
2a7684a23e
Exists in
master
and in
7 other branches
HWPOISON: Refactor truncate to allow direct truncating of page v2
Extract out truncate_inode_page() out of the truncate path so that it can be used by memory-failure.c [AK: description, headers, fix typos] v2: Some white space changes from Fengguang Wu Signed-off-by: Andi Kleen <ak@linux.intel.com>
Showing 2 changed files with 17 additions and 14 deletions Side-by-side Diff
include/linux/mm.h
... | ... | @@ -794,6 +794,8 @@ |
794 | 794 | extern int vmtruncate(struct inode * inode, loff_t offset); |
795 | 795 | extern int vmtruncate_range(struct inode * inode, loff_t offset, loff_t end); |
796 | 796 | |
797 | +int truncate_inode_page(struct address_space *mapping, struct page *page); | |
798 | + | |
797 | 799 | #ifdef CONFIG_MMU |
798 | 800 | extern int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, |
799 | 801 | unsigned long address, unsigned int flags); |
mm/truncate.c
... | ... | @@ -93,11 +93,11 @@ |
93 | 93 | * its lock, b) when a concurrent invalidate_mapping_pages got there first and |
94 | 94 | * c) when tmpfs swizzles a page between a tmpfs inode and swapper_space. |
95 | 95 | */ |
96 | -static void | |
96 | +static int | |
97 | 97 | truncate_complete_page(struct address_space *mapping, struct page *page) |
98 | 98 | { |
99 | 99 | if (page->mapping != mapping) |
100 | - return; | |
100 | + return -EIO; | |
101 | 101 | |
102 | 102 | if (page_has_private(page)) |
103 | 103 | do_invalidatepage(page, 0); |
... | ... | @@ -108,6 +108,7 @@ |
108 | 108 | remove_from_page_cache(page); |
109 | 109 | ClearPageMappedToDisk(page); |
110 | 110 | page_cache_release(page); /* pagecache ref */ |
111 | + return 0; | |
111 | 112 | } |
112 | 113 | |
113 | 114 | /* |
... | ... | @@ -135,6 +136,16 @@ |
135 | 136 | return ret; |
136 | 137 | } |
137 | 138 | |
139 | +int truncate_inode_page(struct address_space *mapping, struct page *page) | |
140 | +{ | |
141 | + if (page_mapped(page)) { | |
142 | + unmap_mapping_range(mapping, | |
143 | + (loff_t)page->index << PAGE_CACHE_SHIFT, | |
144 | + PAGE_CACHE_SIZE, 0); | |
145 | + } | |
146 | + return truncate_complete_page(mapping, page); | |
147 | +} | |
148 | + | |
138 | 149 | /** |
139 | 150 | * truncate_inode_pages - truncate range of pages specified by start & end byte offsets |
140 | 151 | * @mapping: mapping to truncate |
... | ... | @@ -196,12 +207,7 @@ |
196 | 207 | unlock_page(page); |
197 | 208 | continue; |
198 | 209 | } |
199 | - if (page_mapped(page)) { | |
200 | - unmap_mapping_range(mapping, | |
201 | - (loff_t)page_index<<PAGE_CACHE_SHIFT, | |
202 | - PAGE_CACHE_SIZE, 0); | |
203 | - } | |
204 | - truncate_complete_page(mapping, page); | |
210 | + truncate_inode_page(mapping, page); | |
205 | 211 | unlock_page(page); |
206 | 212 | } |
207 | 213 | pagevec_release(&pvec); |
208 | 214 | |
... | ... | @@ -238,15 +244,10 @@ |
238 | 244 | break; |
239 | 245 | lock_page(page); |
240 | 246 | wait_on_page_writeback(page); |
241 | - if (page_mapped(page)) { | |
242 | - unmap_mapping_range(mapping, | |
243 | - (loff_t)page->index<<PAGE_CACHE_SHIFT, | |
244 | - PAGE_CACHE_SIZE, 0); | |
245 | - } | |
247 | + truncate_inode_page(mapping, page); | |
246 | 248 | if (page->index > next) |
247 | 249 | next = page->index; |
248 | 250 | next++; |
249 | - truncate_complete_page(mapping, page); | |
250 | 251 | unlock_page(page); |
251 | 252 | } |
252 | 253 | pagevec_release(&pvec); |