Re: [PATCH v4 01/10] ceph: fix error handling when the OSD client is stopping in ceph_submit_write()

From: Ilya Dryomov

Date: Wed Sep 02 2026 - 09:53:45 EST


On Mon, Aug 17, 2026 at 9:15 PM Tal Zussman <tz2294@xxxxxxxxxxxx> wrote:
>
> When ceph_inc_osd_stopping_blocker() fails, ceph_submit_write()
> redirties and unlocks the folios remaining in ceph_wbc->fbatch.
> However, none of those folios are locked at this point: locked folios
> were moved to ceph_wbc->pages[] and removed from the fbatch by
> ceph_process_folio_batch(). Unlocking them triggers
> VM_BUG_ON_FOLIO(!folio_test_locked(folio)) in folio_unlock(), or
> unlocks a folio locked by another task.
>
> This error path also returns -EIO without fully cleaning up the folios in
> ceph_wbc->pages[]: their references are never dropped, fscrypt bounce
> pages are never freed, the writeback congestion count is never
> decremented, and the pages array is leaked. ceph_wbc->locked_pages is
> also left non-zero, so ceph_writepages_start() loops back around and
> hits BUG_ON(ceph_wbc.locked_pages).
>
> Leave the fbatch folios alone, as ceph_writepages_start() drops their
> references when releasing the batch, and unwind ceph_wbc->pages[] the
> same way writepages_finish() would have. Abort writeback in
> ceph_writepages_start() instead of continuing, matching the handling
> of ceph_inc_osd_stopping_blocker() failure on entry, as the OSD
> client is being torn down and further writeback cannot make progress.
>
> An LLM was used to verify that the cleanup was comprehensive, and
> suggested aborting the writeback instead of continuing.
>
> Fixes: 1551ec61dc55 ("ceph: introduce ceph_submit_write() method")
> Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
> Link: https://sashiko.dev/#/patchset/20260804-remove-wait-on-page-writeback-v2-0-81f0ab065284%40columbia.edu?part=5
> Assisted-by: Claude:fable-5
> Signed-off-by: Tal Zussman <tz2294@xxxxxxxxxxxx>
> ---
> fs/ceph/addr.c | 36 ++++++++++++++++++++----------------
> 1 file changed, 20 insertions(+), 16 deletions(-)
>
> diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
> index 1f77aec8e960..d5a349daf4d0 100644
> --- a/fs/ceph/addr.c
> +++ b/fs/ceph/addr.c
> @@ -1482,27 +1482,28 @@ int ceph_submit_write(struct address_space *mapping,
> BUG_ON(len < ceph_fscrypt_page_offset(page) + thp_size(page) - offset);
>
> if (!ceph_inc_osd_stopping_blocker(fsc->mdsc)) {
> - for (i = 0; i < folio_batch_count(&ceph_wbc->fbatch); i++) {
> - struct folio *folio = ceph_wbc->fbatch.folios[i];
> -
> - if (!folio)
> - continue;
> -
> - page = &folio->page;
> - redirty_page_for_writepage(wbc, page);
> - unlock_page(page);
> - }
> -
> for (i = 0; i < ceph_wbc->locked_pages; i++) {
> - page = ceph_fscrypt_pagecache_page(ceph_wbc->pages[i]);
> + fscrypt_finalize_bounce_page(&ceph_wbc->pages[i]);

Hi Tal,

fscrypt_finalize_bounce_page() was removed in 7.3-rc1, so this one and
patch 8 need to be reworked now.

Thanks,

Ilya