Commit 981250ca authored by Theodore Ts'o's avatar Theodore Ts'o

ext4: don't use EXT4_FREE_BLOCKS_FORGET unnecessarily

Commit 18888cf0: "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: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 2ed5724d
...@@ -2355,6 +2355,15 @@ int ext4_ext_index_trans_blocks(struct inode *inode, int extents) ...@@ -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, ...@@ -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, ...@@ -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 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start, ...@@ -2869,10 +2870,7 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
* 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, ...@@ -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)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment