Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote: > The PG_fscache bit waiting functions are completely crazy. The comment > about "this will wake up others" is actively wrong, and the waiting > function looks insane, because you're mixing the two names for > "fscache" which makes the code look totally incomprehensible. Why > would we wait for PF_fscache, when PG_private_2 was set? Yes, I know > why, but the code looks entirely nonsensical. How about the attached change to make it more coherent and fix the doc comment? David --- commit 9a28f7e68602193ce020a41f855f71cc55f693b9 Author: David Howells <dhowells@xxxxxxxxxx> Date: Wed Feb 10 10:53:02 2021 +0000 netfs: Rename unlock_page_fscache() and wait_on_page_fscache() Rename unlock_page_fscache() to unlock_page_private_2() and wait_on_page_fscache() to wait_on_page_private_2() and change the references to PG_fscache to PG_private_2 also. This makes these functions look more generic and doesn't mix the terminology. Fix the kdoc comment as the wake up mechanism doesn't wake up all the sleepers. Note the example usage case for the functions in conjunction with the cache also. Alias the functions in linux/netfs.h. Reported-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Signed-off-by: David Howells <dhowells@xxxxxxxxxx> diff --git a/include/linux/netfs.h b/include/linux/netfs.h index 2ffdef1ded91..d4cb6e6f704c 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -24,6 +24,8 @@ #define ClearPageFsCache(page) ClearPagePrivate2((page)) #define TestSetPageFsCache(page) TestSetPagePrivate2((page)) #define TestClearPageFsCache(page) TestClearPagePrivate2((page)) +#define wait_on_page_fscache(page) wait_on_page_private_2((page)) +#define unlock_page_fscache(page) unlock_page_private_2((page)) enum netfs_read_source { NETFS_FILL_WITH_ZEROES, diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 4935ad6171c1..a88ccc9ab0b1 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -591,7 +591,7 @@ extern int __lock_page_async(struct page *page, struct wait_page_queue *wait); extern int __lock_page_or_retry(struct page *page, struct mm_struct *mm, unsigned int flags); extern void unlock_page(struct page *page); -extern void unlock_page_fscache(struct page *page); +extern void unlock_page_private_2(struct page *page); /* * Return true if the page was successfully locked @@ -683,16 +683,17 @@ static inline int wait_on_page_locked_killable(struct page *page) } /** - * wait_on_page_fscache - Wait for PG_fscache to be cleared on a page + * wait_on_page_private_2 - Wait for PG_private_2 to be cleared on a page * @page: The page * - * Wait for the fscache mark to be removed from a page, usually signifying the - * completion of a write from that page to the cache. + * Wait for the PG_private_2 page bit to be removed from a page. This is, for + * example, used to handle a netfs page being written to a local disk cache, + * thereby allowing writes to the cache for the same page to be serialised. */ -static inline void wait_on_page_fscache(struct page *page) +static inline void wait_on_page_private_2(struct page *page) { if (PagePrivate2(page)) - wait_on_page_bit(compound_head(page), PG_fscache); + wait_on_page_bit(compound_head(page), PG_private_2); } extern void put_and_wait_on_page_locked(struct page *page); diff --git a/mm/filemap.c b/mm/filemap.c index 91fcae006d64..7d321152d579 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1467,22 +1467,24 @@ void unlock_page(struct page *page) EXPORT_SYMBOL(unlock_page); /** - * unlock_page_fscache - Unlock a page pinned with PG_fscache + * unlock_page_private_2 - Unlock a page that's locked with PG_private_2 * @page: The page * - * Unlocks the page and wakes up sleepers in wait_on_page_fscache(). Also - * wakes those waiting for the lock and writeback bits because the wakeup - * mechanism is shared. But that's OK - those sleepers will just go back to - * sleep. + * Unlocks a page that's locked with PG_private_2 and wakes up sleepers in + * wait_on_page_private_2(). + * + * 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. */ -void unlock_page_fscache(struct page *page) +void unlock_page_private_2(struct page *page) { page = compound_head(page); VM_BUG_ON_PAGE(!PagePrivate2(page), page); - clear_bit_unlock(PG_fscache, &page->flags); - wake_up_page_bit(page, PG_fscache); + clear_bit_unlock(PG_private_2, &page->flags); + wake_up_page_bit(page, PG_private_2); } -EXPORT_SYMBOL(unlock_page_fscache); +EXPORT_SYMBOL(unlock_page_private_2); /** * end_page_writeback - end writeback against a page