Commit 6abbaa5b authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle)
Browse files

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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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
+48 −27
Original line number Diff line number Diff line
@@ -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
 *
 * 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));
+0 −16
Original line number Diff line number Diff line
@@ -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);