diff options
author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2025-09-06 12:48:15 -0400 |
---|---|---|
committer | Anna Schumaker <anna.schumaker@oracle.com> | 2025-09-23 13:29:50 -0400 |
commit | 010054a530aa266ee1711dfbe23fc06b6eb0fa48 (patch) | |
tree | 7357f722c36e118ae31dfce2b2a843808fe97d6f | |
parent | 24bbd533f596a4544e17579e9f622918680e7bff (diff) |
filemap: Add a version of folio_end_writeback that ignores dropbehind
Filesystems such as NFS may need to defer dropbehind until after their
2-stage writes are done. This adds a helper
folio_end_writeback_no_dropbehind() that allows them to release the
writeback flag without immediately dropping the folio.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
-rw-r--r-- | include/linux/pagemap.h | 1 | ||||
-rw-r--r-- | mm/filemap.c | 29 |
2 files changed, 24 insertions, 6 deletions
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 201b7c6f6441..5b26465358ce 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -1221,6 +1221,7 @@ 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); diff --git a/mm/filemap.c b/mm/filemap.c index 66cec689bec4..d12bbb4c9d8a 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1628,14 +1628,15 @@ void folio_end_dropbehind(struct folio *folio) EXPORT_SYMBOL_GPL(folio_end_dropbehind); /** - * folio_end_writeback - End writeback against a folio. + * folio_end_writeback_no_dropbehind - End writeback against a folio. * @folio: The folio. * * The folio must actually be under writeback. + * This call is intended for filesystems that need to defer dropbehind. * * Context: May be called from process or interrupt context. */ -void folio_end_writeback(struct folio *folio) +void folio_end_writeback_no_dropbehind(struct folio *folio) { VM_BUG_ON_FOLIO(!folio_test_writeback(folio), folio); @@ -1651,6 +1652,25 @@ void folio_end_writeback(struct folio *folio) folio_rotate_reclaimable(folio); } + if (__folio_end_writeback(folio)) + folio_wake_bit(folio, PG_writeback); + + acct_reclaim_writeback(folio); +} +EXPORT_SYMBOL_GPL(folio_end_writeback_no_dropbehind); + +/** + * folio_end_writeback - End writeback against a folio. + * @folio: The folio. + * + * The folio must actually be under writeback. + * + * Context: May be called from process or interrupt context. + */ +void folio_end_writeback(struct folio *folio) +{ + VM_BUG_ON_FOLIO(!folio_test_writeback(folio), folio); + /* * Writeback does not hold a folio reference of its own, relying * on truncation to wait for the clearing of PG_writeback. @@ -1658,11 +1678,8 @@ void folio_end_writeback(struct folio *folio) * reused before the folio_wake_bit(). */ folio_get(folio); - if (__folio_end_writeback(folio)) - folio_wake_bit(folio, PG_writeback); - + folio_end_writeback_no_dropbehind(folio); folio_end_dropbehind(folio); - acct_reclaim_writeback(folio); folio_put(folio); } EXPORT_SYMBOL(folio_end_writeback); |