From: Matthew Wilcox (Oracle) Date: Thu, 29 Oct 2020 18:07:47 +0000 (-0400) Subject: mm: Make page_index() THP-safe X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fnext;p=users%2Fwilly%2Fpagecache.git mm: Make page_index() THP-safe You can't dereference page->index for tail pages, so use the head's index to calculate the offset of this page in the file. Also move the function to pagemap.h since it's a pagecache function not used by the rest of the kernel. This also makes page_file_offset() work when called for tail pages. Signed-off-by: Matthew Wilcox (Oracle) --- diff --git a/include/linux/mm.h b/include/linux/mm.h index 0c7959ffc3b6e..63264601cdadf 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1555,19 +1555,6 @@ struct address_space *page_file_mapping(struct page *page) return page->mapping; } -extern pgoff_t __page_file_index(struct page *page); - -/* - * Return the pagecache index of the passed page. Regular pagecache pages - * use ->index whereas swapcache pages use swp_offset(->private) - */ -static inline pgoff_t page_index(struct page *page) -{ - if (unlikely(PageSwapCache(page))) - return __page_file_index(page); - return page->index; -} - bool page_mapped(struct page *page); struct address_space *page_mapping(struct page *page); struct address_space *page_mapping_file(struct page *page); diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 3d017559a1ed1..b46c4d222379f 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -449,6 +449,20 @@ static inline struct page *grab_cache_page_nowait(struct address_space *mapping, mapping_gfp_mask(mapping)); } +extern pgoff_t __page_file_index(struct page *page); + +/* + * Return the pagecache index of the passed page. Regular pagecache pages + * use ->index whereas swapcache pages use swp_offset(->private) + */ +static inline pgoff_t page_index(struct page *page) +{ + struct page *head = thp_head(page); + if (unlikely(PageSwapCache(page))) + return __page_file_index(page); + return head->index + (page - head); +} + /* Does this page contain this index? */ static inline bool thp_contains(struct page *head, pgoff_t index) {