Write path allocate pages using pagecache_get_page(). We should be able
to allocate huge pages there, if it's allowed. As usually, fallback to
small pages, if failed.

Signed-off-by: Kirill A. Shutemov <kirill.shute...@linux.intel.com>
---
 mm/filemap.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/mm/filemap.c b/mm/filemap.c
index b77bcf6843ee..05b42d3e5ed8 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1310,13 +1310,16 @@ repeat:
 
 no_page:
        if (!page && (fgp_flags & FGP_CREAT)) {
+               pgoff_t hoffset;
                int err;
                if ((fgp_flags & FGP_WRITE) && 
mapping_cap_account_dirty(mapping))
                        gfp_mask |= __GFP_WRITE;
                if (fgp_flags & FGP_NOFS)
                        gfp_mask &= ~__GFP_FS;
 
-               page = __page_cache_alloc(gfp_mask);
+               page = page_cache_alloc_huge(mapping, offset, gfp_mask);
+no_huge:       if (!page)
+                       page = __page_cache_alloc(gfp_mask);
                if (!page)
                        return NULL;
 
@@ -1327,14 +1330,25 @@ no_page:
                if (fgp_flags & FGP_ACCESSED)
                        __SetPageReferenced(page);
 
-               err = add_to_page_cache_lru(page, mapping, offset,
+               if (PageTransHuge(page))
+                       hoffset = round_down(offset, HPAGE_PMD_NR);
+               else
+                       hoffset = offset;
+
+               err = add_to_page_cache_lru(page, mapping, hoffset,
                                gfp_mask & GFP_RECLAIM_MASK);
                if (unlikely(err)) {
+                       if (PageTransHuge(page)) {
+                               put_page(page);
+                               page = NULL;
+                               goto no_huge;
+                       }
                        put_page(page);
                        page = NULL;
                        if (err == -EEXIST)
                                goto repeat;
                }
+               page += offset - hoffset;
        }
 
        return page;
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to