Add support for full delayed allocation over ext3 format file. This patch added a function to estimate the number of indirect blocks need to reserve for non-extent based (ext3) file, in order to properly reserve the need amount of indirect blocks for delayed allocation. Signed-off-by: Mingming Cao <cmm@xxxxxxxxxx> --- fs/ext4/inode.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) Index: linux-2.6.26-rc6/fs/ext4/inode.c =================================================================== --- linux-2.6.26-rc6.orig/fs/ext4/inode.c 2008-06-20 16:50:09.000000000 -0700 +++ linux-2.6.26-rc6/fs/ext4/inode.c 2008-06-20 17:36:08.000000000 -0700 @@ -1426,6 +1426,36 @@ static int ext4_journalled_write_end(str return ret ? ret : copied; } +/* + * Calculate the number of metadata blocks need to reserve + * to allocate @blocks for non extent file based file + */ +static int ext4_indirect_calc_metadata_amount(struct inode *inode, int blocks) +{ + int icap = EXT4_ADDR_PER_BLOCK(inode->i_sb); + int ind_blks, dind_blks, tind_blks; + + /* number of new indirect blocks needed */ + ind_blks = (blocks + icap - 1) / icap; + + dind_blks = (ind_blks + icap - 1) / icap; + + tind_blks = 1; + + return ind_blks + dind_blks + tind_blks; +} + +/* + * Calculate the number of metadata blocks need to reserve + * to allocate given number of blocks + */ +static int ext4_calc_metadata_amount(struct inode *inode, int blocks) +{ + if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) + return ext4_ext_calc_metadata_amount(inode, blocks); + + return ext4_indirect_calc_metadata_amount(inode, blocks); +} static int ext4_da_reserve_space(struct inode *inode, int nrblocks) { @@ -1439,7 +1469,7 @@ static int ext4_da_reserve_space(struct */ spin_lock(&EXT4_I(inode)->i_block_reservation_lock); total = EXT4_I(inode)->i_reserved_data_blocks + nrblocks; - mdblocks = ext4_ext_calc_metadata_amount(inode, total); + mdblocks = ext4_calc_metadata_amount(inode, total); BUG_ON(mdblocks < EXT4_I(inode)->i_reserved_meta_blocks); md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks; @@ -1468,7 +1498,7 @@ void ext4_da_release_space(struct inode spin_lock(&EXT4_I(inode)->i_block_reservation_lock); /* recalculate the number of metablocks still need to be reserved */ total = EXT4_I(inode)->i_reserved_data_blocks - used - to_free; - mdb = ext4_ext_calc_metadata_amount(inode, total); + mdb = ext4_calc_metadata_amount(inode, total); /* figure out how many metablocks to release */ BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html