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 031/138] fs/netfs: Add folio fscache functions
    Date
    Match the page writeback functions by adding
    folio_start_fscache(), folio_end_fscache(), folio_wait_fscache() and
    folio_wait_fscache_killable(). Remove set_page_private_2(). Also rewrite
    the kernel-doc to describe when to use the function rather than what the
    function does, and include the kernel-doc in the appropriate rst file.
    Saves 31 bytes of text in netfs_rreq_unlock() due to set_page_fscache()
    calling page_folio() once instead of three times.

    Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
    Acked-by: Vlastimil Babka <vbabka@suse.cz>
    Reviewed-by: William Kucharski <william.kucharski@oracle.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
    ---
    Documentation/filesystems/netfs_library.rst | 2 +
    include/linux/netfs.h | 75 +++++++++++++--------
    include/linux/pagemap.h | 16 -----
    3 files changed, 50 insertions(+), 43 deletions(-)

    diff --git a/Documentation/filesystems/netfs_library.rst b/Documentation/filesystems/netfs_library.rst
    index 57a641847818..bb68d39f03b7 100644
    --- a/Documentation/filesystems/netfs_library.rst
    +++ b/Documentation/filesystems/netfs_library.rst
    @@ -524,3 +524,5 @@ Note that these methods are passed a pointer to the cache resource structure,
    not the read request structure as they could be used in other situations where
    there isn't a read request structure as well, such as writing dirty data to the
    cache.
    +
    +.. kernel-doc:: include/linux/netfs.h
    diff --git a/include/linux/netfs.h b/include/linux/netfs.h
    index fad8c6209edd..e03ed7fc3aef 100644
    --- a/include/linux/netfs.h
    +++ b/include/linux/netfs.h
    @@ -22,6 +22,7 @@
    * Overload PG_private_2 to give us PG_fscache - this is used to indicate that
    * a page is currently backed by a local disk cache
    */
    +#define folio_test_fscache(folio) folio_test_private_2(folio)
    #define PageFsCache(page) PagePrivate2((page))
    #define SetPageFsCache(page) SetPagePrivate2((page))
    #define ClearPageFsCache(page) ClearPagePrivate2((page))
    @@ -29,57 +30,77 @@
    #define TestClearPageFsCache(page) TestClearPagePrivate2((page))

    /**
    - * set_page_fscache - Set PG_fscache on a page and take a ref
    - * @page: The page.
    + * folio_start_fscache - Start an fscache write on a folio.
    + * @folio: The folio.
    *
    - * Set the PG_fscache (PG_private_2) flag on a page and take the reference
    - * needed for the VM to handle its lifetime correctly. This sets the flag and
    - * takes the reference unconditionally, so care must be taken not to set the
    - * flag again if it's already set.
    + * Call this function before writing a folio to a local cache. Starting a
    + * second write before the first one finishes is not allowed.
    */
    -static inline void set_page_fscache(struct page *page)
    +static inline void folio_start_fscache(struct folio *folio)
    {
    - set_page_private_2(page);
    + VM_BUG_ON_FOLIO(folio_test_private_2(folio), folio);
    + folio_get(folio);
    + folio_set_private_2_flag(folio);
    }

    /**
    - * end_page_fscache - Clear PG_fscache and release any waiters
    - * @page: The page
    - *
    - * Clear the PG_fscache (PG_private_2) bit on a page and wake up any sleepers
    - * waiting for this. The page ref held for PG_private_2 being set is released.
    + * folio_end_fscache - End an fscache write on a folio.
    + * @folio: The folio.
    *
    - * This is, for example, used when a netfs page is being written to a local
    - * disk cache, thereby allowing writes to the cache for the same page to be
    - * serialised.
    + * Call this function after the folio has been written to the local cache.
    + * This will wake any sleepers waiting on this folio.
    */
    -static inline void end_page_fscache(struct page *page)
    +static inline void folio_end_fscache(struct folio *folio)
    {
    - folio_end_private_2(page_folio(page));
    + folio_end_private_2(folio);
    }

    /**
    - * wait_on_page_fscache - Wait for PG_fscache to be cleared on a page
    - * @page: The page to wait on
    + * folio_wait_fscache - Wait for an fscache write on this folio to end.
    + * @folio: The folio.
    *
    - * Wait for PG_fscache (aka PG_private_2) to be cleared on a page.
    + * If this folio is currently being written to a local cache, wait for
    + * the write to finish. Another write may start after this one finishes,
    + * unless the caller holds the folio lock.
    */
    -static inline void wait_on_page_fscache(struct page *page)
    +static inline void folio_wait_fscache(struct folio *folio)
    {
    - folio_wait_private_2(page_folio(page));
    + folio_wait_private_2(folio);
    }

    /**
    - * wait_on_page_fscache_killable - Wait for PG_fscache to be cleared on a page
    - * @page: The page to wait on
    + * folio_wait_fscache_killable - Wait for an fscache write on this folio to end.
    + * @folio: The folio.
    *
    - * Wait for PG_fscache (aka PG_private_2) to be cleared on a page or until a
    - * fatal signal is received by the calling task.
    + * If this folio is currently being written to a local cache, wait
    + * for the write to finish or for a fatal signal to be received.
    + * Another write may start after this one finishes, unless the caller
    + * holds the folio lock.
    *
    * Return:
    * - 0 if successful.
    * - -EINTR if a fatal signal was encountered.
    */
    +static inline int folio_wait_fscache_killable(struct folio *folio)
    +{
    + return folio_wait_private_2_killable(folio);
    +}
    +
    +static inline void set_page_fscache(struct page *page)
    +{
    + folio_start_fscache(page_folio(page));
    +}
    +
    +static inline void end_page_fscache(struct page *page)
    +{
    + folio_end_private_2(page_folio(page));
    +}
    +
    +static inline void wait_on_page_fscache(struct page *page)
    +{
    + folio_wait_private_2(page_folio(page));
    +}
    +
    static inline int wait_on_page_fscache_killable(struct page *page)
    {
    return folio_wait_private_2_killable(page_folio(page));
    diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
    index edf58a581bce..08f40e004d97 100644
    --- a/include/linux/pagemap.h
    +++ b/include/linux/pagemap.h
    @@ -780,22 +780,6 @@ int __set_page_dirty_no_writeback(struct page *page);

    void page_endio(struct page *page, bool is_write, int err);

    -/**
    - * set_page_private_2 - Set PG_private_2 on a page and take a ref
    - * @page: The page.
    - *
    - * Set the PG_private_2 flag on a page and take the reference needed for the VM
    - * to handle its lifetime correctly. This sets the flag and takes the
    - * reference unconditionally, so care must be taken not to set the flag again
    - * if it's already set.
    - */
    -static inline void set_page_private_2(struct page *page)
    -{
    - page = compound_head(page);
    - get_page(page);
    - SetPagePrivate2(page);
    -}
    -
    void folio_end_private_2(struct folio *folio);
    void folio_wait_private_2(struct folio *folio);
    int folio_wait_private_2_killable(struct folio *folio);
    --
    2.30.2
    \
     
     \ /
      Last update: 2021-07-15 06:05    [W:2.349 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site