diff options
author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2016-11-30 18:54:19 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-11-30 19:32:52 -0500 |
commit | 5cbc198ae08d84bd416b672ad8bd1222acd0855c (patch) | |
tree | 985d1c3e96076aaca0f485d26f04b9957f920013 /mm/truncate.c | |
parent | 828347f8f9a558cf1af2faa46387a26564f2ac3e (diff) |
mm: fix false-positive WARN_ON() in truncate/invalidate for hugetlb
Hugetlb pages have ->index in size of the huge pages (PMD_SIZE or
PUD_SIZE), not in PAGE_SIZE as other types of pages. This means we
cannot user page_to_pgoff() to check whether we've got the right page
for the radix-tree index.
Let's introduce page_to_index() which would return radix-tree index for
given page.
We will be able to get rid of this once hugetlb will be switched to
multi-order entries.
Fixes: fc127da085c2 ("truncate: handle file thp")
Link: http://lkml.kernel.org/r/20161123093053.mjbnvn5zwxw5e6lk@black.fi.intel.com
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Reported-by: Doug Nelson <doug.nelson@intel.com>
Tested-by: Doug Nelson <doug.nelson@intel.com>
Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: <stable@vger.kernel.org> [4.8+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/truncate.c')
-rw-r--r-- | mm/truncate.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/mm/truncate.c b/mm/truncate.c index a01cce450a26..8d8c62d89e6d 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -283,7 +283,7 @@ void truncate_inode_pages_range(struct address_space *mapping, | |||
283 | 283 | ||
284 | if (!trylock_page(page)) | 284 | if (!trylock_page(page)) |
285 | continue; | 285 | continue; |
286 | WARN_ON(page_to_pgoff(page) != index); | 286 | WARN_ON(page_to_index(page) != index); |
287 | if (PageWriteback(page)) { | 287 | if (PageWriteback(page)) { |
288 | unlock_page(page); | 288 | unlock_page(page); |
289 | continue; | 289 | continue; |
@@ -371,7 +371,7 @@ void truncate_inode_pages_range(struct address_space *mapping, | |||
371 | } | 371 | } |
372 | 372 | ||
373 | lock_page(page); | 373 | lock_page(page); |
374 | WARN_ON(page_to_pgoff(page) != index); | 374 | WARN_ON(page_to_index(page) != index); |
375 | wait_on_page_writeback(page); | 375 | wait_on_page_writeback(page); |
376 | truncate_inode_page(mapping, page); | 376 | truncate_inode_page(mapping, page); |
377 | unlock_page(page); | 377 | unlock_page(page); |
@@ -492,7 +492,7 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, | |||
492 | if (!trylock_page(page)) | 492 | if (!trylock_page(page)) |
493 | continue; | 493 | continue; |
494 | 494 | ||
495 | WARN_ON(page_to_pgoff(page) != index); | 495 | WARN_ON(page_to_index(page) != index); |
496 | 496 | ||
497 | /* Middle of THP: skip */ | 497 | /* Middle of THP: skip */ |
498 | if (PageTransTail(page)) { | 498 | if (PageTransTail(page)) { |
@@ -612,7 +612,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping, | |||
612 | } | 612 | } |
613 | 613 | ||
614 | lock_page(page); | 614 | lock_page(page); |
615 | WARN_ON(page_to_pgoff(page) != index); | 615 | WARN_ON(page_to_index(page) != index); |
616 | if (page->mapping != mapping) { | 616 | if (page->mapping != mapping) { |
617 | unlock_page(page); | 617 | unlock_page(page); |
618 | continue; | 618 | continue; |