[PATCH v3 02/12] ceph: wait for pending fscache write in write_folio_nounlock()

From: Tal Zussman

Date: Mon Aug 10 2026 - 10:31:11 EST


write_folio_nounlock() marks the folio with PG_private_2 via
ceph_set_page_fscache() and starts an async write to the cache via
ceph_fscache_write_to_cache(). PG_private_2 is only cleared once that
write completes.

If the OSD write fails, the error paths return without waiting for the
cache write. On retry, ceph_find_incompatible() would wait for
writeback, but not for PG_private_2, before calling
write_folio_nounlock() again, which would trip the VM_BUG_ON_FOLIO() in
folio_start_private_2().

Wait for any pending cache write before starting writeback on the folio.
Add ceph_folio_wait_fscache(), a wrapper for folio_wait_private_2(), and
use it.

Fixes: 1702e7973410 ("ceph: add fscache writeback support")
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Link: https://sashiko.dev/#/patchset/20260804-remove-wait-on-page-writeback-v2-0-81f0ab065284%40columbia.edu?part=7
Signed-off-by: Tal Zussman <tz2294@xxxxxxxxxxxx>
---
fs/ceph/addr.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 8cd24f66c981..de0113b23940 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -559,6 +559,11 @@ static void ceph_set_page_fscache(struct page *page)
folio_start_private_2(page_folio(page)); /* [DEPRECATED] */
}

+static void ceph_folio_wait_fscache(struct folio *folio)
+{
+ folio_wait_private_2(folio); /* [DEPRECATED] */
+}
+
static void ceph_fscache_write_terminated(void *priv, ssize_t error)
{
struct inode *inode = priv;
@@ -580,6 +585,10 @@ static inline void ceph_set_page_fscache(struct page *page)
{
}

+static inline void ceph_folio_wait_fscache(struct folio *folio)
+{
+}
+
static inline void ceph_fscache_write_to_cache(struct inode *inode, u64 off, u64 len, bool caching)
{
}
@@ -803,6 +812,9 @@ static int write_folio_nounlock(struct folio *folio,
if (wlen < len)
len = wlen;

+ /* wait for a cache write left pending by a previously failed attempt */
+ ceph_folio_wait_fscache(folio);
+
folio_start_writeback(folio);
if (caching)
ceph_set_page_fscache(&folio->page);

--
2.39.5