ext4: don't use EXT4_FREE_BLOCKS_FORGET unnecessarily
Commit 18888cf0883c: "ext4: speed up truncate/unlink by not using bforget() unless needed" removed the use of EXT4_FREE_BLOCKS_FORGET in the most important codepath for file systems using extents, but a similar optimization also can be done for file systems using indirect blocks, and for the two special cases in the ext4 extents code. Cc: Andrey Sidorov <qrxd43@motorola.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
parent
2ed5724d5a
commit
981250ca89
|
@ -2355,6 +2355,15 @@ int ext4_ext_index_trans_blocks(struct inode *inode, int extents)
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int get_default_free_blocks_flags(struct inode *inode)
|
||||||
|
{
|
||||||
|
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
|
||||||
|
return EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET;
|
||||||
|
else if (ext4_should_journal_data(inode))
|
||||||
|
return EXT4_FREE_BLOCKS_FORGET;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
|
static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
|
||||||
struct ext4_extent *ex,
|
struct ext4_extent *ex,
|
||||||
long long *partial_cluster,
|
long long *partial_cluster,
|
||||||
|
@ -2363,12 +2372,7 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
|
||||||
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
||||||
unsigned short ee_len = ext4_ext_get_actual_len(ex);
|
unsigned short ee_len = ext4_ext_get_actual_len(ex);
|
||||||
ext4_fsblk_t pblk;
|
ext4_fsblk_t pblk;
|
||||||
int flags = 0;
|
int flags = get_default_free_blocks_flags(inode);
|
||||||
|
|
||||||
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
|
|
||||||
flags |= EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET;
|
|
||||||
else if (ext4_should_journal_data(inode))
|
|
||||||
flags |= EXT4_FREE_BLOCKS_FORGET;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For bigalloc file systems, we never free a partial cluster
|
* For bigalloc file systems, we never free a partial cluster
|
||||||
|
@ -2635,10 +2639,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
|
||||||
if (*partial_cluster > 0 &&
|
if (*partial_cluster > 0 &&
|
||||||
(EXT4_B2C(sbi, ext4_ext_pblock(ex) + ex_ee_len - 1) !=
|
(EXT4_B2C(sbi, ext4_ext_pblock(ex) + ex_ee_len - 1) !=
|
||||||
*partial_cluster)) {
|
*partial_cluster)) {
|
||||||
int flags = EXT4_FREE_BLOCKS_FORGET;
|
int flags = get_default_free_blocks_flags(inode);
|
||||||
|
|
||||||
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
|
|
||||||
flags |= EXT4_FREE_BLOCKS_METADATA;
|
|
||||||
|
|
||||||
ext4_free_blocks(handle, inode, NULL,
|
ext4_free_blocks(handle, inode, NULL,
|
||||||
EXT4_C2B(sbi, *partial_cluster),
|
EXT4_C2B(sbi, *partial_cluster),
|
||||||
|
@ -2869,10 +2870,7 @@ again:
|
||||||
* even the first extent, then we should free the blocks in the partial
|
* even the first extent, then we should free the blocks in the partial
|
||||||
* cluster as well. */
|
* cluster as well. */
|
||||||
if (partial_cluster > 0 && path->p_hdr->eh_entries == 0) {
|
if (partial_cluster > 0 && path->p_hdr->eh_entries == 0) {
|
||||||
int flags = EXT4_FREE_BLOCKS_FORGET;
|
int flags = get_default_free_blocks_flags(inode);
|
||||||
|
|
||||||
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
|
|
||||||
flags |= EXT4_FREE_BLOCKS_METADATA;
|
|
||||||
|
|
||||||
ext4_free_blocks(handle, inode, NULL,
|
ext4_free_blocks(handle, inode, NULL,
|
||||||
EXT4_C2B(EXT4_SB(sb), partial_cluster),
|
EXT4_C2B(EXT4_SB(sb), partial_cluster),
|
||||||
|
|
|
@ -926,11 +926,13 @@ static int ext4_clear_blocks(handle_t *handle, struct inode *inode,
|
||||||
__le32 *last)
|
__le32 *last)
|
||||||
{
|
{
|
||||||
__le32 *p;
|
__le32 *p;
|
||||||
int flags = EXT4_FREE_BLOCKS_FORGET | EXT4_FREE_BLOCKS_VALIDATED;
|
int flags = EXT4_FREE_BLOCKS_VALIDATED;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
|
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
|
||||||
flags |= EXT4_FREE_BLOCKS_METADATA;
|
flags |= EXT4_FREE_BLOCKS_FORGET | EXT4_FREE_BLOCKS_METADATA;
|
||||||
|
else if (ext4_should_journal_data(inode))
|
||||||
|
flags |= EXT4_FREE_BLOCKS_FORGET;
|
||||||
|
|
||||||
if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), block_to_free,
|
if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), block_to_free,
|
||||||
count)) {
|
count)) {
|
||||||
|
|
Loading…
Reference in New Issue