On 2024/4/29 18:06, Jan Kara wrote: > On Wed 10-04-24 11:42:02, Zhang Yi wrote: >> From: Zhang Yi <yi.zhang@xxxxxxxxxx> >> >> Rename ext4_insert_delayed_block() to ext4_insert_delayed_blocks(), >> pass length parameter to make it insert multi delalloc blocks once a >> time. For non-bigalloc case, just reserve len blocks and insert delalloc >> extent. For bigalloc case, we can ensure the middle clusters are not >> allocated, but need to check whether the start and end clusters are >> delayed/allocated, if not, we should reserve more space for the start >> and/or end block(s). >> >> Signed-off-by: Zhang Yi <yi.zhang@xxxxxxxxxx> > > Thanks for the patch. Some comments below. > >> --- >> fs/ext4/inode.c | 51 ++++++++++++++++++++++++++++++++++--------------- >> 1 file changed, 36 insertions(+), 15 deletions(-) >> >> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c >> index 46c34baa848a..08e2692b7286 100644 >> --- a/fs/ext4/inode.c >> +++ b/fs/ext4/inode.c >> @@ -1678,24 +1678,28 @@ static int ext4_da_check_clu_allocated(struct inode *inode, ext4_lblk_t lblk, >> } >> >> /* >> - * ext4_insert_delayed_block - adds a delayed block to the extents status >> - * tree, incrementing the reserved cluster/block >> - * count or making a pending reservation >> - * where needed >> + * ext4_insert_delayed_blocks - adds a multiple delayed blocks to the extents >> + * status tree, incrementing the reserved >> + * cluster/block count or making pending >> + * reservations where needed >> * >> * @inode - file containing the newly added block >> - * @lblk - logical block to be added >> + * @lblk - start logical block to be added >> + * @len - length of blocks to be added >> * >> * Returns 0 on success, negative error code on failure. >> */ >> -static int ext4_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk) >> +static int ext4_insert_delayed_blocks(struct inode *inode, ext4_lblk_t lblk, >> + ext4_lblk_t len) >> { >> struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); >> - int ret; >> - bool allocated = false; >> + int resv_clu, ret; > ^^^ this variable is in prinple the length of the extent. Thus > it should be ext4_lblk_t type. > >> + bool lclu_allocated = false; >> + bool end_allocated = false; >> + ext4_lblk_t end = lblk + len - 1; >> >> /* >> - * If the cluster containing lblk is shared with a delayed, >> + * If the cluster containing lblk or end is shared with a delayed, >> * written, or unwritten extent in a bigalloc file system, it's >> * already been accounted for and does not need to be reserved. >> * A pending reservation must be made for the cluster if it's >> @@ -1706,21 +1710,38 @@ static int ext4_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk) >> * extents status tree doesn't get a match. >> */ >> if (sbi->s_cluster_ratio == 1) { >> - ret = ext4_da_reserve_space(inode, 1); >> + ret = ext4_da_reserve_space(inode, len); >> if (ret != 0) /* ENOSPC */ >> return ret; >> } else { /* bigalloc */ >> - ret = ext4_da_check_clu_allocated(inode, lblk, &allocated); >> + resv_clu = EXT4_B2C(sbi, end) - EXT4_B2C(sbi, lblk) - 1; >> + if (resv_clu < 0) >> + resv_clu = 0; > > Here resv_clu going negative is strange I'm not sure the math is 100% > correct in all the cases. I think it would be more logical as: > > resv_clu = EXT4_B2C(sbi, end) - EXT4_B2C(sbi, lblk) + 1; >> and then update resv_clu below as: > >> + >> + ret = ext4_da_check_clu_allocated(inode, lblk, &lclu_allocated); >> if (ret < 0) >> return ret; >> - if (ret > 0) { >> - ret = ext4_da_reserve_space(inode, 1); >> + if (ret > 0) >> + resv_clu++; > > Here we would do: > if (ret == 0) > resv_clu--; > >> + >> + if (EXT4_B2C(sbi, lblk) != EXT4_B2C(sbi, end)) { >> + ret = ext4_da_check_clu_allocated(inode, end, >> + &end_allocated); >> + if (ret < 0) >> + return ret; >> + if (ret > 0) >> + resv_clu++; > > And similarly here: > if (ret == 0) > resv_clu--; Oh, yes, it is definitely more logical than mine. Thanks for taking time to review this series, other changelog and comments suggestions in this series are looks fine to me, I will use them. Besides, Ritesh improved my changelog in patch 2, I will keep your reviewed tag if you don't have different opinions. Thanks, Yi. > >> + } >> + >> + if (resv_clu) { >> + ret = ext4_da_reserve_space(inode, resv_clu); >> if (ret != 0) /* ENOSPC */ >> return ret; >> } >> } >> >> - ext4_es_insert_delayed_extent(inode, lblk, 1, allocated, false); >> + ext4_es_insert_delayed_extent(inode, lblk, len, lclu_allocated, >> + end_allocated); >> return 0; >> } >> >> @@ -1823,7 +1844,7 @@ static int ext4_da_map_blocks(struct inode *inode, struct ext4_map_blocks *map, >> } >> } >> >> - retval = ext4_insert_delayed_block(inode, map->m_lblk); >> + retval = ext4_insert_delayed_blocks(inode, map->m_lblk, map->m_len); >> up_write(&EXT4_I(inode)->i_data_sem); >> if (retval) >> return retval; >> -- >> 2.39.2 >>