diff options
author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2016-07-26 18:26:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-26 19:19:19 -0400 |
commit | fc127da085c26beb89f83ad804cf73422c3b6855 (patch) | |
tree | 34d98b005382b45a463f7f17a1ba3d35094a0935 | |
parent | 83929372f629001568d43069a63376e13bfc497b (diff) |
truncate: handle file thp
For shmem/tmpfs we only need to tweak truncate_inode_page() and
invalidate_mapping_pages().
truncate_inode_pages_range() and invalidate_inode_pages2_range() are
adjusted to use page_to_pgoff().
Link: http://lkml.kernel.org/r/1466021202-61880-26-git-send-email-kirill.shutemov@linux.intel.com
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | mm/truncate.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/mm/truncate.c b/mm/truncate.c index 4064f8f53daa..a01cce450a26 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -155,10 +155,14 @@ invalidate_complete_page(struct address_space *mapping, struct page *page) | |||
155 | 155 | ||
156 | int truncate_inode_page(struct address_space *mapping, struct page *page) | 156 | int truncate_inode_page(struct address_space *mapping, struct page *page) |
157 | { | 157 | { |
158 | loff_t holelen; | ||
159 | VM_BUG_ON_PAGE(PageTail(page), page); | ||
160 | |||
161 | holelen = PageTransHuge(page) ? HPAGE_PMD_SIZE : PAGE_SIZE; | ||
158 | if (page_mapped(page)) { | 162 | if (page_mapped(page)) { |
159 | unmap_mapping_range(mapping, | 163 | unmap_mapping_range(mapping, |
160 | (loff_t)page->index << PAGE_SHIFT, | 164 | (loff_t)page->index << PAGE_SHIFT, |
161 | PAGE_SIZE, 0); | 165 | holelen, 0); |
162 | } | 166 | } |
163 | return truncate_complete_page(mapping, page); | 167 | return truncate_complete_page(mapping, page); |
164 | } | 168 | } |
@@ -279,7 +283,7 @@ void truncate_inode_pages_range(struct address_space *mapping, | |||
279 | 283 | ||
280 | if (!trylock_page(page)) | 284 | if (!trylock_page(page)) |
281 | continue; | 285 | continue; |
282 | WARN_ON(page->index != index); | 286 | WARN_ON(page_to_pgoff(page) != index); |
283 | if (PageWriteback(page)) { | 287 | if (PageWriteback(page)) { |
284 | unlock_page(page); | 288 | unlock_page(page); |
285 | continue; | 289 | continue; |
@@ -367,7 +371,7 @@ void truncate_inode_pages_range(struct address_space *mapping, | |||
367 | } | 371 | } |
368 | 372 | ||
369 | lock_page(page); | 373 | lock_page(page); |
370 | WARN_ON(page->index != index); | 374 | WARN_ON(page_to_pgoff(page) != index); |
371 | wait_on_page_writeback(page); | 375 | wait_on_page_writeback(page); |
372 | truncate_inode_page(mapping, page); | 376 | truncate_inode_page(mapping, page); |
373 | unlock_page(page); | 377 | unlock_page(page); |
@@ -487,7 +491,21 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, | |||
487 | 491 | ||
488 | if (!trylock_page(page)) | 492 | if (!trylock_page(page)) |
489 | continue; | 493 | continue; |
490 | WARN_ON(page->index != index); | 494 | |
495 | WARN_ON(page_to_pgoff(page) != index); | ||
496 | |||
497 | /* Middle of THP: skip */ | ||
498 | if (PageTransTail(page)) { | ||
499 | unlock_page(page); | ||
500 | continue; | ||
501 | } else if (PageTransHuge(page)) { | ||
502 | index += HPAGE_PMD_NR - 1; | ||
503 | i += HPAGE_PMD_NR - 1; | ||
504 | /* 'end' is in the middle of THP */ | ||
505 | if (index == round_down(end, HPAGE_PMD_NR)) | ||
506 | continue; | ||
507 | } | ||
508 | |||
491 | ret = invalidate_inode_page(page); | 509 | ret = invalidate_inode_page(page); |
492 | unlock_page(page); | 510 | unlock_page(page); |
493 | /* | 511 | /* |
@@ -594,7 +612,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping, | |||
594 | } | 612 | } |
595 | 613 | ||
596 | lock_page(page); | 614 | lock_page(page); |
597 | WARN_ON(page->index != index); | 615 | WARN_ON(page_to_pgoff(page) != index); |
598 | if (page->mapping != mapping) { | 616 | if (page->mapping != mapping) { |
599 | unlock_page(page); | 617 | unlock_page(page); |
600 | continue; | 618 | continue; |