mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
ext4: teach ext4_meta_trans_blocks() about number of allocated extents
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> Link: https://patch.msgid.link/20260805153605.166545-4-jack@suse.cz Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
8f3901fbb4
commit
25b2a7e8d4
|
|
@ -3196,7 +3196,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);
|
||||
|
||||
#define EXT4_PARTIAL_ZERO_START 0x1
|
||||
|
|
|
|||
|
|
@ -5063,7 +5063,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) {
|
||||
|
|
|
|||
|
|
@ -3709,8 +3709,8 @@ static int ext4_iomap_alloc(struct inode *inode, struct ext4_map_blocks *map,
|
|||
return ret;
|
||||
if (map->m_len < orig_mlen) {
|
||||
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);
|
||||
|
|
@ -6394,17 +6394,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;
|
||||
|
|
@ -6421,7 +6421,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;
|
||||
|
|
@ -6447,7 +6447,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;
|
||||
|
|
@ -6465,7 +6465,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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user