Skip to content

Commit ad1876b

Browse files
zhangyi089tytso
authored andcommitted
ext4: pass allocate range as loff_t to ext4_alloc_file_blocks()
Change ext4_alloc_file_blocks() to accept offset and len in byte granularity instead of block granularity. This allows callers to pass byte offsets and lengths directly, and this prepares for moving the ext4_zero_partial_blocks() call from the while(len) loop for unaligned append writes, where it only needs to be invoked once before doing block allocation. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260327102939.1095257-8-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent d3609a7 commit ad1876b

1 file changed

Lines changed: 22 additions & 31 deletions

File tree

fs/ext4/extents.c

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4571,30 +4571,30 @@ int ext4_ext_truncate(handle_t *handle, struct inode *inode)
45714571
return err;
45724572
}
45734573

4574-
static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
4575-
ext4_lblk_t len, loff_t new_size,
4576-
int flags)
4574+
static int ext4_alloc_file_blocks(struct file *file, loff_t offset, loff_t len,
4575+
loff_t new_size, int flags)
45774576
{
45784577
struct inode *inode = file_inode(file);
45794578
handle_t *handle;
45804579
int ret = 0, ret2 = 0, ret3 = 0;
45814580
int retries = 0;
45824581
int depth = 0;
4582+
ext4_lblk_t len_lblk;
45834583
struct ext4_map_blocks map;
45844584
unsigned int credits;
45854585
loff_t epos, old_size = i_size_read(inode);
45864586
unsigned int blkbits = inode->i_blkbits;
45874587
bool alloc_zero = false;
45884588

45894589
BUG_ON(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS));
4590-
map.m_lblk = offset;
4591-
map.m_len = len;
4590+
map.m_lblk = offset >> blkbits;
4591+
map.m_len = len_lblk = EXT4_MAX_BLOCKS(len, offset, blkbits);
45924592
/*
45934593
* Don't normalize the request if it can fit in one extent so
45944594
* that it doesn't get unnecessarily split into multiple
45954595
* extents.
45964596
*/
4597-
if (len <= EXT_UNWRITTEN_MAX_LEN)
4597+
if (len_lblk <= EXT_UNWRITTEN_MAX_LEN)
45984598
flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
45994599

46004600
/*
@@ -4611,16 +4611,16 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
46114611
/*
46124612
* credits to insert 1 extent into extent tree
46134613
*/
4614-
credits = ext4_chunk_trans_blocks(inode, len);
4614+
credits = ext4_chunk_trans_blocks(inode, len_lblk);
46154615
depth = ext_depth(inode);
46164616

46174617
retry:
4618-
while (len) {
4618+
while (len_lblk) {
46194619
/*
46204620
* Recalculate credits when extent tree depth changes.
46214621
*/
46224622
if (depth != ext_depth(inode)) {
4623-
credits = ext4_chunk_trans_blocks(inode, len);
4623+
credits = ext4_chunk_trans_blocks(inode, len_lblk);
46244624
depth = ext_depth(inode);
46254625
}
46264626

@@ -4677,7 +4677,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
46774677
}
46784678

46794679
map.m_lblk += ret;
4680-
map.m_len = len = len - ret;
4680+
map.m_len = len_lblk = len_lblk - ret;
46814681
}
46824682
if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
46834683
goto retry;
@@ -4694,11 +4694,9 @@ static long ext4_zero_range(struct file *file, loff_t offset,
46944694
{
46954695
struct inode *inode = file_inode(file);
46964696
handle_t *handle = NULL;
4697-
loff_t new_size = 0;
4697+
loff_t align_start, align_end, new_size = 0;
46984698
loff_t end = offset + len;
4699-
ext4_lblk_t start_lblk, end_lblk;
47004699
unsigned int blocksize = i_blocksize(inode);
4701-
unsigned int blkbits = inode->i_blkbits;
47024700
int ret, flags, credits;
47034701

47044702
trace_ext4_zero_range(inode, offset, len, mode);
@@ -4719,11 +4717,8 @@ static long ext4_zero_range(struct file *file, loff_t offset,
47194717
flags = EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT;
47204718
/* Preallocate the range including the unaligned edges */
47214719
if (!IS_ALIGNED(offset | end, blocksize)) {
4722-
ext4_lblk_t alloc_lblk = offset >> blkbits;
4723-
ext4_lblk_t len_lblk = EXT4_MAX_BLOCKS(len, offset, blkbits);
4724-
4725-
ret = ext4_alloc_file_blocks(file, alloc_lblk, len_lblk,
4726-
new_size, flags);
4720+
ret = ext4_alloc_file_blocks(file, offset, len, new_size,
4721+
flags);
47274722
if (ret)
47284723
return ret;
47294724
}
@@ -4738,18 +4733,17 @@ static long ext4_zero_range(struct file *file, loff_t offset,
47384733
return ret;
47394734

47404735
/* Zero range excluding the unaligned edges */
4741-
start_lblk = EXT4_B_TO_LBLK(inode, offset);
4742-
end_lblk = end >> blkbits;
4743-
if (end_lblk > start_lblk) {
4744-
ext4_lblk_t zero_blks = end_lblk - start_lblk;
4745-
4736+
align_start = round_up(offset, blocksize);
4737+
align_end = round_down(end, blocksize);
4738+
if (align_end > align_start) {
47464739
if (mode & FALLOC_FL_WRITE_ZEROES)
47474740
flags = EXT4_GET_BLOCKS_CREATE_ZERO | EXT4_EX_NOCACHE;
47484741
else
47494742
flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN |
47504743
EXT4_EX_NOCACHE);
4751-
ret = ext4_alloc_file_blocks(file, start_lblk, zero_blks,
4752-
new_size, flags);
4744+
ret = ext4_alloc_file_blocks(file, align_start,
4745+
align_end - align_start, new_size,
4746+
flags);
47534747
if (ret)
47544748
return ret;
47554749
}
@@ -4797,15 +4791,11 @@ static long ext4_do_fallocate(struct file *file, loff_t offset,
47974791
struct inode *inode = file_inode(file);
47984792
loff_t end = offset + len;
47994793
loff_t new_size = 0;
4800-
ext4_lblk_t start_lblk, len_lblk;
48014794
int ret;
48024795

48034796
trace_ext4_fallocate_enter(inode, offset, len, mode);
48044797
WARN_ON_ONCE(!inode_is_locked(inode));
48054798

4806-
start_lblk = offset >> inode->i_blkbits;
4807-
len_lblk = EXT4_MAX_BLOCKS(len, offset, inode->i_blkbits);
4808-
48094799
/* We only support preallocation for extent-based files only. */
48104800
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
48114801
ret = -EOPNOTSUPP;
@@ -4820,7 +4810,7 @@ static long ext4_do_fallocate(struct file *file, loff_t offset,
48204810
goto out;
48214811
}
48224812

4823-
ret = ext4_alloc_file_blocks(file, start_lblk, len_lblk, new_size,
4813+
ret = ext4_alloc_file_blocks(file, offset, len, new_size,
48244814
EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT);
48254815
if (ret)
48264816
goto out;
@@ -4830,7 +4820,8 @@ static long ext4_do_fallocate(struct file *file, loff_t offset,
48304820
EXT4_I(inode)->i_sync_tid);
48314821
}
48324822
out:
4833-
trace_ext4_fallocate_exit(inode, offset, len_lblk, ret);
4823+
trace_ext4_fallocate_exit(inode, offset,
4824+
EXT4_MAX_BLOCKS(len, offset, inode->i_blkbits), ret);
48344825
return ret;
48354826
}
48364827

0 commit comments

Comments
 (0)