Skip to content

Commit b104bd8

Browse files
jankaraopsiff
authored andcommitted
ext4: fix calculation of credits for extent tree modification
commit 32a93f5 upstream. Luis and David are reporting that after running generic/750 test for 90+ hours on 2k ext4 filesystem, they are able to trigger a warning in jbd2_journal_dirty_metadata() complaining that there are not enough credits in the running transaction started in ext4_do_writepages(). Indeed the code in ext4_do_writepages() is racy and the extent tree can change between the time we compute credits necessary for extent tree computation and the time we actually modify the extent tree. Thus it may happen that the number of credits actually needed is higher. Modify ext4_ext_index_trans_blocks() to count with the worst case of maximum tree depth. This can reduce the possible number of writers that can operate in the system in parallel (because the credit estimates now won't fit in one transaction) but for reasonably sized journals this shouldn't really be an issue. So just go with a safe and simple fix. Link: https://lore.kernel.org/all/20250415013641.f2ppw6wov4kn4wq2@offworld Reported-by: Davidlohr Bueso <dave@stgolabs.net> Reported-by: Luis Chamberlain <mcgrof@kernel.org> Tested-by: kdevops@lists.linux.dev Signed-off-by: Jan Kara <jack@suse.cz> Reviewed-by: Zhang Yi <yi.zhang@huawei.com> Link: https://patch.msgid.link/20250429175535.23125-2-jack@suse.cz Signed-off-by: Theodore Ts'o <tytso@mit.edu> Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> (cherry picked from commit 223091c9897cf6d33bbb139b5bcabb80ba4df378)
1 parent 345e555 commit b104bd8

1 file changed

Lines changed: 6 additions & 5 deletions

File tree

fs/ext4/extents.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2374,18 +2374,19 @@ int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks,
23742374
int ext4_ext_index_trans_blocks(struct inode *inode, int extents)
23752375
{
23762376
int index;
2377-
int depth;
23782377

23792378
/* If we are converting the inline data, only one is needed here. */
23802379
if (ext4_has_inline_data(inode))
23812380
return 1;
23822381

2383-
depth = ext_depth(inode);
2384-
2382+
/*
2383+
* Extent tree can change between the time we estimate credits and
2384+
* the time we actually modify the tree. Assume the worst case.
2385+
*/
23852386
if (extents <= 1)
2386-
index = depth * 2;
2387+
index = EXT4_MAX_EXTENT_DEPTH * 2;
23872388
else
2388-
index = depth * 3;
2389+
index = EXT4_MAX_EXTENT_DEPTH * 3;
23892390

23902391
return index;
23912392
}

0 commit comments

Comments
 (0)