Merge tag 'linux-watchdog-5.10-rc1' of git://www.linux-watchdog.org/linux-watchdog
[linux-2.6-microblaze.git] / mm / swap_state.c
index c16eebb..ee46582 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/vmalloc.h>
 #include <linux/swap_slots.h>
 #include <linux/huge_mm.h>
+#include <linux/shmem_fs.h>
 #include "internal.h"
 
 /*
@@ -245,7 +246,7 @@ int add_to_swap(struct page *page)
                goto fail;
        /*
         * Normally the page will be dirtied in unmap because its pte should be
-        * dirty. A special case is MADV_FREE page. The page'e pte could have
+        * dirty. A special case is MADV_FREE page. The page's pte could have
         * dirty bit cleared but the page's SwapBacked bit is still set because
         * clearing the dirty bit and SwapBacked bit has no lock protected. For
         * such page, unmap will not set dirty bit for it, so page reclaim will
@@ -414,6 +415,39 @@ struct page *lookup_swap_cache(swp_entry_t entry, struct vm_area_struct *vma,
        return page;
 }
 
+/**
+ * find_get_incore_page - Find and get a page from the page or swap caches.
+ * @mapping: The address_space to search.
+ * @index: The page cache index.
+ *
+ * This differs from find_get_page() in that it will also look for the
+ * page in the swap cache.
+ *
+ * Return: The found page or %NULL.
+ */
+struct page *find_get_incore_page(struct address_space *mapping, pgoff_t index)
+{
+       swp_entry_t swp;
+       struct swap_info_struct *si;
+       struct page *page = find_get_entry(mapping, index);
+
+       if (!page)
+               return page;
+       if (!xa_is_value(page))
+               return find_subpage(page, index);
+       if (!shmem_mapping(mapping))
+               return NULL;
+
+       swp = radix_to_swp_entry(page);
+       /* Prevent swapoff from happening to us */
+       si = get_swap_device(swp);
+       if (!si)
+               return NULL;
+       page = find_get_page(swap_address_space(swp), swp_offset(swp));
+       put_swap_device(si);
+       return page;
+}
+
 struct page *__read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
                        struct vm_area_struct *vma, unsigned long addr,
                        bool *new_page_allocated)
@@ -631,7 +665,7 @@ struct page *swap_cluster_readahead(swp_entry_t entry, gfp_t gfp_mask,
                goto skip;
 
        /* Test swap type to make sure the dereference is safe */
-       if (likely(si->flags & (SWP_BLKDEV | SWP_FS))) {
+       if (likely(si->flags & (SWP_BLKDEV | SWP_FS_OPS))) {
                struct inode *inode = si->swap_file->f_mapping->host;
                if (inode_read_congested(inode))
                        goto skip;