fs/netfs: Add folio fscache functions

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>
Acked-by: Mike Rapoport <rppt@linux.ibm.com>
Reviewed-by: David Howells <dhowells@redhat.com>
This commit is contained in:
Matthew Wilcox (Oracle) 2021-04-27 14:24:30 -04:00
parent b47393f844
commit 6abbaa5b01
3 changed files with 50 additions and 43 deletions

View file

@ -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

View file

@ -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(folio);
}
/**
* end_page_fscache - Clear PG_fscache and release any waiters
* @page: The page
* folio_end_fscache - End an fscache write on a folio.
* @folio: The folio.
*
* 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.
*
* 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));

View file

@ -779,22 +779,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);