From: Jan Kara <jack@suse.cz>
To: Ted Tso <tytso@mit.edu>
Cc: <linux-ext4@vger.kernel.org>,
Baokun Li <libaokun@linux.alibaba.com>,
Zhang Yi <yi.zhang@huawei.com>,
Ojaswin Mujoo <ojaswin@linux.ibm.com>,
Ritesh Harjani <ritesh.list@gmail.com>, Jan Kara <jack@suse.cz>
Subject: [PATCH 1/3] ext4: Teach ext4_meta_trans_blocks() about number of allocated extents
Date: Wed, 5 Aug 2026 17:35:47 +0200 [thread overview]
Message-ID: <20260805153605.166545-4-jack@suse.cz> (raw)
In-Reply-To: <20260805153202.29814-1-jack@suse.cz>
So far ext4_meta_trans_blocks() expects that each extent counted in
@pextents will be allocated in the transaction we estimate credits for.
This is correct for the use in ext4_chunk_trans_blocks() and
ext4_chunk_trans_extent() however the use in atomic write path
(ext4_convert_unwritten_extents_atomic() and ext4_iomap_alloc() for
IOMAP_ATOMIC) unnecessarily overestimates the number of necessary
credits as neither of them allocates any data. Add argument to
ext4_meta_trans_blocks() for number of extents that are going to be
allocated in the transaction.
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/ext4/ext4.h | 2 +-
fs/ext4/extents.c | 2 +-
fs/ext4/inode.c | 32 +++++++++++++++++---------------
3 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index b37c136ea3ab..6e0cc9b845ae 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -3184,7 +3184,7 @@ extern int ext4_normal_submit_inode_data_buffers(struct jbd2_inode *jinode);
extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks);
extern int ext4_chunk_trans_extent(struct inode *inode, int nrblocks);
extern int ext4_meta_trans_blocks(struct inode *inode, int lblocks,
- int pextents);
+ int pextents, int alloc_extents);
extern int ext4_block_zero_eof(struct inode *inode, loff_t from, loff_t end);
extern int ext4_zero_partial_blocks(struct inode *inode, loff_t lstart,
loff_t length, bool *did_zero);
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 91c97af64b31..44ab246a3176 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4976,7 +4976,7 @@ int ext4_convert_unwritten_extents_atomic(handle_t *handle, struct inode *inode,
* it can tell if the extent in the cache is a split extent.
* But for now let's assume pextents as 2 always.
*/
- credits = ext4_meta_trans_blocks(inode, max_blocks, 2);
+ credits = ext4_meta_trans_blocks(inode, max_blocks, 2, 0);
}
if (credits) {
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index ce99807c5f5b..f324a54f1dae 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3693,9 +3693,11 @@ static int ext4_iomap_alloc(struct inode *inode, struct ext4_map_blocks *map,
if (ret < 0)
return ret;
if (map->m_len < orig_mlen) {
+ int bpg = EXT4_BLOCKS_PER_GROUP(inode->i_sb);
+
map->m_len = orig_mlen;
- dio_credits = ext4_meta_trans_blocks(inode, orig_mlen,
- map->m_len);
+ dio_credits = ext4_meta_trans_blocks(inode, map->m_len,
+ map->m_len, 0);
} else {
dio_credits = ext4_chunk_trans_blocks(inode,
map->m_len);
@@ -6307,17 +6309,17 @@ static int ext4_index_trans_blocks(struct inode *inode, int lblocks,
}
/*
- * Account for index blocks, block groups bitmaps and block group
- * descriptor blocks if modify datablocks and index blocks
- * worse case, the indexs blocks spread over different block groups
- *
- * If datablocks are discontiguous, they are possible to spread over
- * different block groups too. If they are contiguous, with flexbg,
- * they could still across block group boundary.
- *
- * Also account for superblock, inode, quota and xattr blocks
+ * Calculate number of credits needed in a transaction to:
+ * * Allocate data blocks from @alloc_extents different groups - note that
+ * with flexbg a single physical extent can span multiple groups but
+ * single mballoc request only returns extent within one group.
+ * * Allocate metatadata (extent tree blocks, indirect blocks) to store
+ * pointers to @pextents data extents having @lblocks in total.
+ * * Modify extent tree / indirect block tree, inode, superblock, quota
+ * tracking, xattr blocks
*/
-int ext4_meta_trans_blocks(struct inode *inode, int lblocks, int pextents)
+int ext4_meta_trans_blocks(struct inode *inode, int lblocks, int pextents,
+ int alloc_extents)
{
ext4_group_t groups, ngroups = ext4_get_groups_count(inode->i_sb);
int gdpblocks;
@@ -6334,7 +6336,7 @@ int ext4_meta_trans_blocks(struct inode *inode, int lblocks, int pextents)
* Now let's see how many group bitmaps and group descriptors need
* to account
*/
- groups = idxblocks + pextents;
+ groups = idxblocks + alloc_extents;
gdpblocks = groups;
if (groups > ngroups)
groups = ngroups;
@@ -6360,7 +6362,7 @@ int ext4_chunk_trans_extent(struct inode *inode, int nrblocks)
{
int ret;
- ret = ext4_meta_trans_blocks(inode, nrblocks, 1);
+ ret = ext4_meta_trans_blocks(inode, nrblocks, 1, 1);
/* Account for data blocks for journalled mode */
if (ext4_should_journal_data(inode))
ret += nrblocks;
@@ -6378,7 +6380,7 @@ int ext4_chunk_trans_extent(struct inode *inode, int nrblocks)
*/
int ext4_chunk_trans_blocks(struct inode *inode, int nrblocks)
{
- return ext4_meta_trans_blocks(inode, nrblocks, 1);
+ return ext4_meta_trans_blocks(inode, nrblocks, 1, 1);
}
/*
--
2.51.0
next prev parent reply other threads:[~2026-08-05 15:36 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-05 15:35 [PATCH 0/3] ext4: Fix credit estimates for extent tree modifications Jan Kara
2026-08-05 15:35 ` Jan Kara [this message]
2026-08-06 18:09 ` [PATCH 1/3] ext4: Teach ext4_meta_trans_blocks() about number of allocated extents Ojaswin Mujoo
2026-08-07 2:59 ` Zhang Yi
2026-08-07 5:59 ` Ojaswin Mujoo
2026-08-07 7:05 ` Zhang Yi
2026-08-07 7:28 ` Ojaswin Mujoo
2026-08-05 15:35 ` [PATCH 2/3] ext4: Fix transaction overflow during writeback Jan Kara
2026-08-07 3:36 ` Zhang Yi
2026-08-07 8:40 ` Ojaswin Mujoo
2026-08-05 15:35 ` [PATCH 3/3] ext4: Fix estimate extent index blocks in ext4_ext_index_trans_blocks() Jan Kara
2026-08-07 4:46 ` Zhang Yi
2026-08-07 6:37 ` Ojaswin Mujoo
2026-08-10 1:33 ` [PATCH 0/3] ext4: Fix credit estimates for extent tree modifications Theodore Ts'o
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260805153605.166545-4-jack@suse.cz \
--to=jack@suse.cz \
--cc=libaokun@linux.alibaba.com \
--cc=linux-ext4@vger.kernel.org \
--cc=ojaswin@linux.ibm.com \
--cc=ritesh.list@gmail.com \
--cc=tytso@mit.edu \
--cc=yi.zhang@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox