[PATCH RFC 04/11] folio_wait: move folio_wait_writeback() family to mm/folio_wait.c
Tal Zussman <[email protected]>
| Newsgroups | org.kernel.vger.io-uring,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
folio_wait_writeback(), folio_wait_writeback_killable() and folio_wait_stable() are thin wrappers around folio_wait_bit() and folio_wait_bit_killable() on PG_writeback. Move them to mm/folio_wait.c, next to the rest of the folio bit-wait infrastructure. The legacy wait_on_page_writeback() wrapper stays in folio-compat.c, as its days are numbered, and it will be deleted once the remaining callers are converted. Signed-off-by: Tal Zussman <[email protected]> --- include/linux/folio_wait.h | 4 +++ include/linux/pagemap.h | 3 --- mm/folio_wait.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ mm/page-writeback.c | 66 --------------------------------------------- 4 files changed, 71 insertions(+), 69 deletions(-) diff --git a/include/linux/folio_wait.h b/include/linux/folio_wait.h index 80ddf1ffcae4..4a5cb2fcf046 100644 --- a/include/linux/folio_wait.h +++ b/include/linux/folio_wait.h @@ -178,4 +178,8 @@ 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); +void folio_wait_writeback(struct folio *folio); +int folio_wait_writeback_killable(struct folio *folio); +void folio_wait_stable(struct folio *folio); + #endif /* _LINUX_FOLIO_WAIT_H */ diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 7f65c2b0097b..84ccb682cca8 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -1074,13 +1074,10 @@ static inline pgoff_t linear_page_index(const struct vm_area_struct *vma, } void wait_on_page_writeback(struct page *page); -void folio_wait_writeback(struct folio *folio); -int folio_wait_writeback_killable(struct folio *folio); void end_page_writeback(struct page *page); void folio_end_writeback(struct folio *folio); void folio_end_writeback_no_dropbehind(struct folio *folio); void folio_end_dropbehind(struct folio *folio); -void folio_wait_stable(struct folio *folio); void __folio_mark_dirty(struct folio *folio, struct address_space *, int warn); void folio_account_cleaned(struct folio *folio, struct bdi_writeback *wb); void __folio_cancel_dirty(struct folio *folio); diff --git a/mm/folio_wait.c b/mm/folio_wait.c index 06156e138c09..9d3328717bb3 100644 --- a/mm/folio_wait.c +++ b/mm/folio_wait.c @@ -15,6 +15,7 @@ #include <linux/delayacct.h> #include <linux/psi.h> #include <linux/migrate.h> +#include <trace/events/writeback.h> #include "internal.h" @@ -572,6 +573,72 @@ int folio_wait_private_2_killable(struct folio *folio) } EXPORT_SYMBOL(folio_wait_private_2_killable); +/** + * folio_wait_writeback - Wait for a folio to finish writeback. + * @folio: The folio to wait for. + * + * If the folio is currently being written back to storage, wait for the + * I/O to complete. + * + * Context: Sleeps. Must be called in process context and with + * no spinlocks held. Caller should hold a reference on the folio. + * If the folio is not locked, writeback may start again after writeback + * has finished. + */ +void folio_wait_writeback(struct folio *folio) +{ + while (folio_test_writeback(folio)) { + trace_folio_wait_writeback(folio, folio_mapping(folio)); + folio_wait_bit(folio, PG_writeback); + } +} +EXPORT_SYMBOL_GPL(folio_wait_writeback); + +/** + * folio_wait_writeback_killable - Wait for a folio to finish writeback. + * @folio: The folio to wait for. + * + * If the folio is currently being written back to storage, wait for the + * I/O to complete or a fatal signal to arrive. + * + * Context: Sleeps. Must be called in process context and with + * no spinlocks held. Caller should hold a reference on the folio. + * If the folio is not locked, writeback may start again after writeback + * has finished. + * Return: 0 on success, -EINTR if we get a fatal signal while waiting. + */ +int folio_wait_writeback_killable(struct folio *folio) +{ + while (folio_test_writeback(folio)) { + trace_folio_wait_writeback(folio, folio_mapping(folio)); + if (folio_wait_bit_killable(folio, PG_writeback)) + return -EINTR; + } + + return 0; +} +EXPORT_SYMBOL_GPL(folio_wait_writeback_killable); + +/** + * folio_wait_stable() - wait for writeback to finish, if necessary. + * @folio: The folio to wait on. + * + * This function determines if the given folio is related to a backing + * device that requires folio contents to be held stable during writeback. + * If so, then it will wait for any pending writeback to complete. + * + * Context: Sleeps. Must be called in process context and with + * no spinlocks held. Caller should hold a reference on the folio. + * If the folio is not locked, writeback may start again after writeback + * has finished. + */ +void folio_wait_stable(struct folio *folio) +{ + if (mapping_stable_writes(folio_mapping(folio))) + folio_wait_writeback(folio); +} +EXPORT_SYMBOL_GPL(folio_wait_stable); + /** * __folio_lock - Get a lock on the folio, assuming we need to sleep to get it. * @folio: The folio to lock diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 833f743f309f..50f548bbb375 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -3042,69 +3042,3 @@ void __folio_start_writeback(struct folio *folio, bool keep_write) VM_BUG_ON_FOLIO(access_ret != 0, folio); } EXPORT_SYMBOL(__folio_start_writeback); - -/** - * folio_wait_writeback - Wait for a folio to finish writeback. - * @folio: The folio to wait for. - * - * If the folio is currently being written back to storage, wait for the - * I/O to complete. - * - * Context: Sleeps. Must be called in process context and with - * no spinlocks held. Caller should hold a reference on the folio. - * If the folio is not locked, writeback may start again after writeback - * has finished. - */ -void folio_wait_writeback(struct folio *folio) -{ - while (folio_test_writeback(folio)) { - trace_folio_wait_writeback(folio, folio_mapping(folio)); - folio_wait_bit(folio, PG_writeback); - } -} -EXPORT_SYMBOL_GPL(folio_wait_writeback); - -/** - * folio_wait_writeback_killable - Wait for a folio to finish writeback. - * @folio: The folio to wait for. - * - * If the folio is currently being written back to storage, wait for the - * I/O to complete or a fatal signal to arrive. - * - * Context: Sleeps. Must be called in process context and with - * no spinlocks held. Caller should hold a reference on the folio. - * If the folio is not locked, writeback may start again after writeback - * has finished. - * Return: 0 on success, -EINTR if we get a fatal signal while waiting. - */ -int folio_wait_writeback_killable(struct folio *folio) -{ - while (folio_test_writeback(folio)) { - trace_folio_wait_writeback(folio, folio_mapping(folio)); - if (folio_wait_bit_killable(folio, PG_writeback)) - return -EINTR; - } - - return 0; -} -EXPORT_SYMBOL_GPL(folio_wait_writeback_killable); - -/** - * folio_wait_stable() - wait for writeback to finish, if necessary. - * @folio: The folio to wait on. - * - * This function determines if the given folio is related to a backing - * device that requires folio contents to be held stable during writeback. - * If so, then it will wait for any pending writeback to complete. - * - * Context: Sleeps. Must be called in process context and with - * no spinlocks held. Caller should hold a reference on the folio. - * If the folio is not locked, writeback may start again after writeback - * has finished. - */ -void folio_wait_stable(struct folio *folio) -{ - if (mapping_stable_writes(folio_mapping(folio))) - folio_wait_writeback(folio); -} -EXPORT_SYMBOL_GPL(folio_wait_stable); -- 2.39.5