Re: [PATCH] ext4: cancel dirty accounting for folios without buffers
From: Jan Kara
Date: Wed Jun 24 2026 - 08:33:18 EST
On Tue 23-06-26 17:49:47, Zhu Jia wrote:
> Since commit cc5095747edf ("ext4: don't BUG if someone dirty pages
> without asking ext4 first"), mpage_prepare_extent_to_map() handles dirty
> folios without buffer heads by warning, clearing PG_dirty, and skipping
> them. ext4 cannot write these folios because there are no buffer heads to
> map and submit.
>
> That recovery leaves dirty accounting behind: folio_clear_dirty() clears
> PG_dirty but does not undo the accounting charged when the folio was
> dirtied. We have seen this in production as Dirty/nr_dirty staying high
> while Writeback/nr_writeback and device write IO stayed near zero, with
> many writer tasks blocked in balance_dirty_pages() throttling. Thus the
> warning-and-skip recovery can still become a dirty-throttle DoS.
>
> Use folio_cancel_dirty() so dropping PG_dirty also cancels the dirty
> accounting.
>
> Fixes: cc5095747edf ("ext4: don't BUG if someone dirty pages without asking ext4 first")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Zhu Jia <zhujia.zj@xxxxxxxxxxxxx>
Good point. Feel free to add:
Reviewed-by: Jan Kara <jack@xxxxxxx>
Honza
> ---
> fs/ext4/inode.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index c2c2d6ac7f3d1..7ea280e70c06e 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -2715,7 +2715,13 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
> */
> if (!folio_buffers(folio)) {
> ext4_warning_inode(mpd->inode, "page %lu does not have buffers attached", folio->index);
> - folio_clear_dirty(folio);
> + /*
> + * folio_cancel_dirty() pairs the dropped dirty
> + * state with dirty accounting, but leaves stale
> + * PAGECACHE_TAG_DIRTY/TOWRITE tags behind. Later
> + * writeback may rescan this clean folio.
> + */
> + folio_cancel_dirty(folio);
> folio_unlock(folio);
> continue;
> }
> --
> 2.20.1
--
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR