summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2026-08-05 17:35:48 +0200
committerTheodore Ts'o <tytso@mit.edu>2026-08-06 22:52:28 -0400
commit46e8e31771f4f1c5e1cdec37a889a6730e42e9f1 (patch)
tree4a63eabd01783d33d23ab01f0c78474eac37a4c4
parent25b2a7e8d420c49fc46f25b6f953603e4dae1dbf (diff)
ext4: fix transaction overflow during writeback
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 <jack@suse.cz> Link: https://patch.msgid.link/20260805153605.166545-5-jack@suse.cz Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--fs/ext4/inode.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 88aea2e2fa16..48ef9bb387c4 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2864,10 +2864,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)