lkml.org 
[lkml]   [2021]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v14 089/138] mm/filemap: Add FGP_STABLE
    Date
    Allow filemap_get_folio() to wait for writeback to complete (if the
    filesystem wants that behaviour). This is the folio equivalent of
    grab_cache_page_write_begin(), which is moved into the folio-compat
    file as a reminder to migrate all the code using it. This paves the
    way for getting rid of AOP_FLAG_NOFS once grab_cache_page_write_begin()
    is removed.

    Kernel grows by 11 bytes. filemap_get_folio() grows by 33 bytes but
    grab_cache_page_write_begin() shrinks by 22 bytes to make up for it.

    Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
    ---
    include/linux/pagemap.h | 1 +
    mm/filemap.c | 25 +++----------------------
    mm/folio-compat.c | 13 +++++++++++++
    3 files changed, 17 insertions(+), 22 deletions(-)

    diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
    index b24933eced18..83c1a798265f 100644
    --- a/include/linux/pagemap.h
    +++ b/include/linux/pagemap.h
    @@ -301,6 +301,7 @@ pgoff_t page_cache_prev_miss(struct address_space *mapping,
    #define FGP_FOR_MMAP 0x00000040
    #define FGP_HEAD 0x00000080
    #define FGP_ENTRY 0x00000100
    +#define FGP_STABLE 0x00000200

    struct folio *__filemap_get_folio(struct address_space *mapping, pgoff_t index,
    int fgp_flags, gfp_t gfp);
    diff --git a/mm/filemap.c b/mm/filemap.c
    index 061e285aae21..0434c5a55fec 100644
    --- a/mm/filemap.c
    +++ b/mm/filemap.c
    @@ -1817,6 +1817,7 @@ static void *mapping_get_entry(struct address_space *mapping, pgoff_t index)
    * * %FGP_WRITE - The page will be written to by the caller.
    * * %FGP_NOFS - __GFP_FS will get cleared in gfp.
    * * %FGP_NOWAIT - Don't get blocked by page lock.
    + * * %FGP_STABLE - Wait for the folio to be stable (finished writeback)
    *
    * If %FGP_LOCK or %FGP_CREAT are specified then the function may sleep even
    * if the %GFP flags specified for %FGP_CREAT are atomic.
    @@ -1867,6 +1868,8 @@ struct folio *__filemap_get_folio(struct address_space *mapping, pgoff_t index,
    folio_clear_idle(folio);
    }

    + if (fgp_flags & FGP_STABLE)
    + folio_wait_stable(folio);
    no_page:
    if (!folio && (fgp_flags & FGP_CREAT)) {
    int err;
    @@ -3590,28 +3593,6 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from)
    }
    EXPORT_SYMBOL(generic_file_direct_write);

    -/*
    - * Find or create a page at the given pagecache position. Return the locked
    - * page. This function is specifically for buffered writes.
    - */
    -struct page *grab_cache_page_write_begin(struct address_space *mapping,
    - pgoff_t index, unsigned flags)
    -{
    - struct page *page;
    - int fgp_flags = FGP_LOCK|FGP_WRITE|FGP_CREAT;
    -
    - if (flags & AOP_FLAG_NOFS)
    - fgp_flags |= FGP_NOFS;
    -
    - page = pagecache_get_page(mapping, index, fgp_flags,
    - mapping_gfp_mask(mapping));
    - if (page)
    - wait_for_stable_page(page);
    -
    - return page;
    -}
    -EXPORT_SYMBOL(grab_cache_page_write_begin);
    -
    ssize_t generic_perform_write(struct file *file,
    struct iov_iter *i, loff_t pos)
    {
    diff --git a/mm/folio-compat.c b/mm/folio-compat.c
    index e833e680e944..5b6ae1da314e 100644
    --- a/mm/folio-compat.c
    +++ b/mm/folio-compat.c
    @@ -116,6 +116,7 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
    }
    EXPORT_SYMBOL(add_to_page_cache_lru);

    +noinline
    struct page *pagecache_get_page(struct address_space *mapping, pgoff_t index,
    int fgp_flags, gfp_t gfp)
    {
    @@ -127,3 +128,15 @@ struct page *pagecache_get_page(struct address_space *mapping, pgoff_t index,
    return folio_file_page(folio, index);
    }
    EXPORT_SYMBOL(pagecache_get_page);
    +
    +struct page *grab_cache_page_write_begin(struct address_space *mapping,
    + pgoff_t index, unsigned flags)
    +{
    + unsigned fgp_flags = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE;
    +
    + if (flags & AOP_FLAG_NOFS)
    + fgp_flags |= FGP_NOFS;
    + return pagecache_get_page(mapping, index, fgp_flags,
    + mapping_gfp_mask(mapping));
    +}
    +EXPORT_SYMBOL(grab_cache_page_write_begin);
    --
    2.30.2
    \
     
     \ /
      Last update: 2021-07-15 06:49    [W:4.028 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site