Skip to content

Commit 1850d76

Browse files
zhangyi089tytso
authored andcommitted
ext4: make ext4_insert_delayed_block() insert multi-blocks
Rename ext4_insert_delayed_block() to ext4_insert_delayed_blocks(), pass length parameter to make it insert multiple delalloc blocks at a time. For non-bigalloc case, just reserve len blocks and insert delalloc extent. For bigalloc case, we can ensure that the clusters in the middle of a extent must be unallocated, we only need to check whether the start and end clusters are delayed/allocated. We should subtract the space for the start and/or end block(s) if they are allocated. Signed-off-by: Zhang Yi <[email protected]> Reviewed-by: Jan Kara <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 49bf6ab commit 1850d76

File tree

1 file changed

+36
-15
lines changed

1 file changed

+36
-15
lines changed

fs/ext4/inode.c

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,24 +1679,29 @@ static int ext4_clu_alloc_state(struct inode *inode, ext4_lblk_t lblk)
16791679
}
16801680

16811681
/*
1682-
* ext4_insert_delayed_block - adds a delayed block to the extents status
1683-
* tree, incrementing the reserved cluster/block
1684-
* count or making a pending reservation
1685-
* where needed
1682+
* ext4_insert_delayed_blocks - adds a multiple delayed blocks to the extents
1683+
* status tree, incrementing the reserved
1684+
* cluster/block count or making pending
1685+
* reservations where needed
16861686
*
16871687
* @inode - file containing the newly added block
1688-
* @lblk - logical block to be added
1688+
* @lblk - start logical block to be added
1689+
* @len - length of blocks to be added
16891690
*
16901691
* Returns 0 on success, negative error code on failure.
16911692
*/
1692-
static int ext4_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk)
1693+
static int ext4_insert_delayed_blocks(struct inode *inode, ext4_lblk_t lblk,
1694+
ext4_lblk_t len)
16931695
{
16941696
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
16951697
int ret;
1696-
bool allocated = false;
1698+
bool lclu_allocated = false;
1699+
bool end_allocated = false;
1700+
ext4_lblk_t resv_clu;
1701+
ext4_lblk_t end = lblk + len - 1;
16971702

16981703
/*
1699-
* If the cluster containing lblk is shared with a delayed,
1704+
* If the cluster containing lblk or end is shared with a delayed,
17001705
* written, or unwritten extent in a bigalloc file system, it's
17011706
* already been accounted for and does not need to be reserved.
17021707
* A pending reservation must be made for the cluster if it's
@@ -1707,23 +1712,39 @@ static int ext4_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk)
17071712
* extents status tree doesn't get a match.
17081713
*/
17091714
if (sbi->s_cluster_ratio == 1) {
1710-
ret = ext4_da_reserve_space(inode, 1);
1715+
ret = ext4_da_reserve_space(inode, len);
17111716
if (ret != 0) /* ENOSPC */
17121717
return ret;
17131718
} else { /* bigalloc */
1719+
resv_clu = EXT4_B2C(sbi, end) - EXT4_B2C(sbi, lblk) + 1;
1720+
17141721
ret = ext4_clu_alloc_state(inode, lblk);
17151722
if (ret < 0)
17161723
return ret;
1717-
if (ret == 2)
1718-
allocated = true;
1719-
if (ret == 0) {
1720-
ret = ext4_da_reserve_space(inode, 1);
1724+
if (ret > 0) {
1725+
resv_clu--;
1726+
lclu_allocated = (ret == 2);
1727+
}
1728+
1729+
if (EXT4_B2C(sbi, lblk) != EXT4_B2C(sbi, end)) {
1730+
ret = ext4_clu_alloc_state(inode, end);
1731+
if (ret < 0)
1732+
return ret;
1733+
if (ret > 0) {
1734+
resv_clu--;
1735+
end_allocated = (ret == 2);
1736+
}
1737+
}
1738+
1739+
if (resv_clu) {
1740+
ret = ext4_da_reserve_space(inode, resv_clu);
17211741
if (ret != 0) /* ENOSPC */
17221742
return ret;
17231743
}
17241744
}
17251745

1726-
ext4_es_insert_delayed_extent(inode, lblk, 1, allocated, false);
1746+
ext4_es_insert_delayed_extent(inode, lblk, len, lclu_allocated,
1747+
end_allocated);
17271748
return 0;
17281749
}
17291750

@@ -1828,7 +1849,7 @@ static int ext4_da_map_blocks(struct inode *inode, struct ext4_map_blocks *map,
18281849
}
18291850
}
18301851

1831-
retval = ext4_insert_delayed_block(inode, map->m_lblk);
1852+
retval = ext4_insert_delayed_blocks(inode, map->m_lblk, map->m_len);
18321853
up_write(&EXT4_I(inode)->i_data_sem);
18331854
if (retval)
18341855
return retval;

0 commit comments

Comments
 (0)