Re: [PATCH 2/3] ext4: Fix transaction overflow during writeback
Zhang Yi <[email protected]> Fri, 7 Aug 2026 11:36:37 +0800
| Newsgroups | org.kernel.vger.linux-ext4 |
|---|---|
| Message-ID | <[email protected]> |
On 8/5/2026 11:35 PM, Jan Kara wrote:
> Commit 95ad8ee45cdb ("ext4: correct the reserved credits for extent
> conversion") was correct to note that we need to reserve enough credits
> for all extents possibly underlying a large folio. However it was too
> eager to reduce the number of reserved credits. Extent conversion may
> not only need to touch several leaf extent blocks, it may also need to
> split extents - for example a single large unwritten extent may need to
> be split into many small written ones in case of sparse folio dirtying.
> This can thus result not only in extent leaf modifications but also in a
> need to allocate new extent tree nodes. As a result the reserved
> transaction credits were not sufficient in some corner cases. Use
> ext4_meta_trans_blocks() for correct upper bound credit estimate.
>
> Fixes: 95ad8ee45cdb ("ext4: correct the reserved credits for extent conversion")
> Signed-off-by: Jan Kara <[email protected]>
Indeed, I overlooked that the newly allocated index blocks will modify
bitmaps and group descriptor blocks. Given that the folio length is
capped at 2048 filesystem blocks, calling ext4_meta_trans_blocks(bpf, 0)
shouldn't result in an overly large credits calculation. So,
Reviewed-by: Zhang Yi <[email protected]>
> ---
> fs/ext4/inode.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index f324a54f1dae..ddce319e53c5 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -2852,10 +2852,10 @@ static int ext4_do_writepages(struct mpage_da_data *mpd)
> if (ext4_should_dioread_nolock(inode)) {
> int bpf = ext4_journal_blocks_per_folio(inode);
> /*
> - * We may need to convert up to one extent per block in
> - * the folio and we may dirty the inode.
> + * We may need to convert up to one extent per block in the
> + * folio.
> */
> - rsv_blocks = 1 + ext4_ext_index_trans_blocks(inode, bpf);
> + rsv_blocks = ext4_meta_trans_blocks(inode, bpf, bpf, 0);
> }
>
> if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)