diff options
-rw-r--r-- | include/linux/mm.h | 25 | ||||
-rw-r--r-- | include/linux/pagemap.h | 5 | ||||
-rw-r--r-- | include/linux/swap.h | 1 | ||||
-rw-r--r-- | mm/swapfile.c | 26 |
4 files changed, 57 insertions, 0 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 7c6dfd2faa69..7cdac1676b59 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -805,6 +805,17 @@ static inline void *page_rmapping(struct page *page) | |||
805 | return (void *)((unsigned long)page->mapping & ~PAGE_MAPPING_FLAGS); | 805 | return (void *)((unsigned long)page->mapping & ~PAGE_MAPPING_FLAGS); |
806 | } | 806 | } |
807 | 807 | ||
808 | extern struct address_space *__page_file_mapping(struct page *); | ||
809 | |||
810 | static inline | ||
811 | struct address_space *page_file_mapping(struct page *page) | ||
812 | { | ||
813 | if (unlikely(PageSwapCache(page))) | ||
814 | return __page_file_mapping(page); | ||
815 | |||
816 | return page->mapping; | ||
817 | } | ||
818 | |||
808 | static inline int PageAnon(struct page *page) | 819 | static inline int PageAnon(struct page *page) |
809 | { | 820 | { |
810 | return ((unsigned long)page->mapping & PAGE_MAPPING_ANON) != 0; | 821 | return ((unsigned long)page->mapping & PAGE_MAPPING_ANON) != 0; |
@@ -821,6 +832,20 @@ static inline pgoff_t page_index(struct page *page) | |||
821 | return page->index; | 832 | return page->index; |
822 | } | 833 | } |
823 | 834 | ||
835 | extern pgoff_t __page_file_index(struct page *page); | ||
836 | |||
837 | /* | ||
838 | * Return the file index of the page. Regular pagecache pages use ->index | ||
839 | * whereas swapcache pages use swp_offset(->private) | ||
840 | */ | ||
841 | static inline pgoff_t page_file_index(struct page *page) | ||
842 | { | ||
843 | if (unlikely(PageSwapCache(page))) | ||
844 | return __page_file_index(page); | ||
845 | |||
846 | return page->index; | ||
847 | } | ||
848 | |||
824 | /* | 849 | /* |
825 | * Return true if this page is mapped into pagetables. | 850 | * Return true if this page is mapped into pagetables. |
826 | */ | 851 | */ |
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 7cfad3bbb0cc..e42c762f0dc7 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h | |||
@@ -286,6 +286,11 @@ static inline loff_t page_offset(struct page *page) | |||
286 | return ((loff_t)page->index) << PAGE_CACHE_SHIFT; | 286 | return ((loff_t)page->index) << PAGE_CACHE_SHIFT; |
287 | } | 287 | } |
288 | 288 | ||
289 | static inline loff_t page_file_offset(struct page *page) | ||
290 | { | ||
291 | return ((loff_t)page_file_index(page)) << PAGE_CACHE_SHIFT; | ||
292 | } | ||
293 | |||
289 | extern pgoff_t linear_hugepage_index(struct vm_area_struct *vma, | 294 | extern pgoff_t linear_hugepage_index(struct vm_area_struct *vma, |
290 | unsigned long address); | 295 | unsigned long address); |
291 | 296 | ||
diff --git a/include/linux/swap.h b/include/linux/swap.h index 9a16bb1cefd1..e62425ded2ed 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
@@ -356,6 +356,7 @@ extern unsigned int count_swap_pages(int, int); | |||
356 | extern sector_t map_swap_page(struct page *, struct block_device **); | 356 | extern sector_t map_swap_page(struct page *, struct block_device **); |
357 | extern sector_t swapdev_block(int, pgoff_t); | 357 | extern sector_t swapdev_block(int, pgoff_t); |
358 | extern int page_swapcount(struct page *); | 358 | extern int page_swapcount(struct page *); |
359 | extern struct swap_info_struct *page_swap_info(struct page *); | ||
359 | extern int reuse_swap_page(struct page *); | 360 | extern int reuse_swap_page(struct page *); |
360 | extern int try_to_free_swap(struct page *); | 361 | extern int try_to_free_swap(struct page *); |
361 | struct backing_dev_info; | 362 | struct backing_dev_info; |
diff --git a/mm/swapfile.c b/mm/swapfile.c index 71373d03fcee..f89af5ba2eb2 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/oom.h> | 33 | #include <linux/oom.h> |
34 | #include <linux/frontswap.h> | 34 | #include <linux/frontswap.h> |
35 | #include <linux/swapfile.h> | 35 | #include <linux/swapfile.h> |
36 | #include <linux/export.h> | ||
36 | 37 | ||
37 | #include <asm/pgtable.h> | 38 | #include <asm/pgtable.h> |
38 | #include <asm/tlbflush.h> | 39 | #include <asm/tlbflush.h> |
@@ -2285,6 +2286,31 @@ int swapcache_prepare(swp_entry_t entry) | |||
2285 | return __swap_duplicate(entry, SWAP_HAS_CACHE); | 2286 | return __swap_duplicate(entry, SWAP_HAS_CACHE); |
2286 | } | 2287 | } |
2287 | 2288 | ||
2289 | struct swap_info_struct *page_swap_info(struct page *page) | ||
2290 | { | ||
2291 | swp_entry_t swap = { .val = page_private(page) }; | ||
2292 | BUG_ON(!PageSwapCache(page)); | ||
2293 | return swap_info[swp_type(swap)]; | ||
2294 | } | ||
2295 | |||
2296 | /* | ||
2297 | * out-of-line __page_file_ methods to avoid include hell. | ||
2298 | */ | ||
2299 | struct address_space *__page_file_mapping(struct page *page) | ||
2300 | { | ||
2301 | VM_BUG_ON(!PageSwapCache(page)); | ||
2302 | return page_swap_info(page)->swap_file->f_mapping; | ||
2303 | } | ||
2304 | EXPORT_SYMBOL_GPL(__page_file_mapping); | ||
2305 | |||
2306 | pgoff_t __page_file_index(struct page *page) | ||
2307 | { | ||
2308 | swp_entry_t swap = { .val = page_private(page) }; | ||
2309 | VM_BUG_ON(!PageSwapCache(page)); | ||
2310 | return swp_offset(swap); | ||
2311 | } | ||
2312 | EXPORT_SYMBOL_GPL(__page_file_index); | ||
2313 | |||
2288 | /* | 2314 | /* |
2289 | * add_swap_count_continuation - called when a swap count is duplicated | 2315 | * add_swap_count_continuation - called when a swap count is duplicated |
2290 | * beyond SWAP_MAP_MAX, it allocates a new page and links that to the entry's | 2316 | * beyond SWAP_MAP_MAX, it allocates a new page and links that to the entry's |