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: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
Reviewed-by: default avatarWilliam Kucharski <william.kucharski@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: default avatarMike Rapoport <rppt@linux.ibm.com>
Reviewed-by: default avatarDavid Howells <dhowells@redhat.com>
parent b47393f8
...@@ -524,3 +524,5 @@ Note that these methods are passed a pointer to the cache resource structure, ...@@ -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 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 there isn't a read request structure as well, such as writing dirty data to the
cache. cache.
.. kernel-doc:: include/linux/netfs.h
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
* Overload PG_private_2 to give us PG_fscache - this is used to indicate that * 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 * 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 PageFsCache(page) PagePrivate2((page))
#define SetPageFsCache(page) SetPagePrivate2((page)) #define SetPageFsCache(page) SetPagePrivate2((page))
#define ClearPageFsCache(page) ClearPagePrivate2((page)) #define ClearPageFsCache(page) ClearPagePrivate2((page))
...@@ -29,57 +30,77 @@ ...@@ -29,57 +30,77 @@
#define TestClearPageFsCache(page) TestClearPagePrivate2((page)) #define TestClearPageFsCache(page) TestClearPagePrivate2((page))
/** /**
* set_page_fscache - Set PG_fscache on a page and take a ref * folio_start_fscache - Start an fscache write on a folio.
* @page: The page. * @folio: The folio.
* *
* Set the PG_fscache (PG_private_2) flag on a page and take the reference * Call this function before writing a folio to a local cache. Starting a
* needed for the VM to handle its lifetime correctly. This sets the flag and * second write before the first one finishes is not allowed.
* 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_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 * folio_end_fscache - End an fscache write on a folio.
* @page: The page * @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 * Call this function after the folio has been written to the local cache.
* disk cache, thereby allowing writes to the cache for the same page to be * This will wake any sleepers waiting on this folio.
* serialised.
*/ */
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 * folio_wait_fscache - Wait for an fscache write on this folio to end.
* @page: The page to wait on * @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 * folio_wait_fscache_killable - Wait for an fscache write on this folio to end.
* @page: The page to wait on * @folio: The folio.
* *
* Wait for PG_fscache (aka PG_private_2) to be cleared on a page or until a * If this folio is currently being written to a local cache, wait
* fatal signal is received by the calling task. * 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: * Return:
* - 0 if successful. * - 0 if successful.
* - -EINTR if a fatal signal was encountered. * - -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) static inline int wait_on_page_fscache_killable(struct page *page)
{ {
return folio_wait_private_2_killable(page_folio(page)); return folio_wait_private_2_killable(page_folio(page));
......
...@@ -779,22 +779,6 @@ int __set_page_dirty_no_writeback(struct page *page); ...@@ -779,22 +779,6 @@ int __set_page_dirty_no_writeback(struct page *page);
void page_endio(struct page *page, bool is_write, int err); 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_end_private_2(struct folio *folio);
void folio_wait_private_2(struct folio *folio); void folio_wait_private_2(struct folio *folio);
int folio_wait_private_2_killable(struct folio *folio); int folio_wait_private_2_killable(struct folio *folio);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment