diff options
author | Theodore Ts'o <tytso@mit.edu> | 2013-06-12 11:48:29 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-06-12 11:48:29 -0400 |
commit | 981250ca89261f98bdfd2d6be1fcccb96cbbc00d (patch) | |
tree | dc60f0b2df0b1544fe551ed415e7cefe1c3d3907 /fs/ext4 | |
parent | 2ed5724d5a78a22864ef0bd6af4fcb8a15379f00 (diff) |
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>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/extents.c | 26 | ||||
-rw-r--r-- | fs/ext4/indirect.c | 6 |
2 files changed, 16 insertions, 16 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 208f664f9ee0..d04f40936397 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -2355,6 +2355,15 @@ int ext4_ext_index_trans_blocks(struct inode *inode, int extents) | |||
2355 | return index; | 2355 | return index; |
2356 | } | 2356 | } |
2357 | 2357 | ||
2358 | static inline int get_default_free_blocks_flags(struct inode *inode) | ||
2359 | { | ||
2360 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) | ||
2361 | return EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET; | ||
2362 | else if (ext4_should_journal_data(inode)) | ||
2363 | return EXT4_FREE_BLOCKS_FORGET; | ||
2364 | return 0; | ||
2365 | } | ||
2366 | |||
2358 | static int ext4_remove_blocks(handle_t *handle, struct inode *inode, | 2367 | static int ext4_remove_blocks(handle_t *handle, struct inode *inode, |
2359 | struct ext4_extent *ex, | 2368 | struct ext4_extent *ex, |
2360 | long long *partial_cluster, | 2369 | long long *partial_cluster, |
@@ -2363,12 +2372,7 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, | |||
2363 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 2372 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
2364 | unsigned short ee_len = ext4_ext_get_actual_len(ex); | 2373 | unsigned short ee_len = ext4_ext_get_actual_len(ex); |
2365 | ext4_fsblk_t pblk; | 2374 | ext4_fsblk_t pblk; |
2366 | int flags = 0; | 2375 | int flags = get_default_free_blocks_flags(inode); |
2367 | |||
2368 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) | ||
2369 | flags |= EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET; | ||
2370 | else if (ext4_should_journal_data(inode)) | ||
2371 | flags |= EXT4_FREE_BLOCKS_FORGET; | ||
2372 | 2376 | ||
2373 | /* | 2377 | /* |
2374 | * For bigalloc file systems, we never free a partial cluster | 2378 | * 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 | if (*partial_cluster > 0 && | 2639 | if (*partial_cluster > 0 && |
2636 | (EXT4_B2C(sbi, ext4_ext_pblock(ex) + ex_ee_len - 1) != | 2640 | (EXT4_B2C(sbi, ext4_ext_pblock(ex) + ex_ee_len - 1) != |
2637 | *partial_cluster)) { | 2641 | *partial_cluster)) { |
2638 | int flags = EXT4_FREE_BLOCKS_FORGET; | 2642 | int flags = get_default_free_blocks_flags(inode); |
2639 | |||
2640 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) | ||
2641 | flags |= EXT4_FREE_BLOCKS_METADATA; | ||
2642 | 2643 | ||
2643 | ext4_free_blocks(handle, inode, NULL, | 2644 | ext4_free_blocks(handle, inode, NULL, |
2644 | EXT4_C2B(sbi, *partial_cluster), | 2645 | EXT4_C2B(sbi, *partial_cluster), |
@@ -2869,10 +2870,7 @@ again: | |||
2869 | * even the first extent, then we should free the blocks in the partial | 2870 | * even the first extent, then we should free the blocks in the partial |
2870 | * cluster as well. */ | 2871 | * cluster as well. */ |
2871 | if (partial_cluster > 0 && path->p_hdr->eh_entries == 0) { | 2872 | if (partial_cluster > 0 && path->p_hdr->eh_entries == 0) { |
2872 | int flags = EXT4_FREE_BLOCKS_FORGET; | 2873 | int flags = get_default_free_blocks_flags(inode); |
2873 | |||
2874 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) | ||
2875 | flags |= EXT4_FREE_BLOCKS_METADATA; | ||
2876 | 2874 | ||
2877 | ext4_free_blocks(handle, inode, NULL, | 2875 | ext4_free_blocks(handle, inode, NULL, |
2878 | EXT4_C2B(EXT4_SB(sb), partial_cluster), | 2876 | EXT4_C2B(EXT4_SB(sb), partial_cluster), |
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index 2a1f8a577e08..963d23dc1028 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c | |||
@@ -926,11 +926,13 @@ static int ext4_clear_blocks(handle_t *handle, struct inode *inode, | |||
926 | __le32 *last) | 926 | __le32 *last) |
927 | { | 927 | { |
928 | __le32 *p; | 928 | __le32 *p; |
929 | int flags = EXT4_FREE_BLOCKS_FORGET | EXT4_FREE_BLOCKS_VALIDATED; | 929 | int flags = EXT4_FREE_BLOCKS_VALIDATED; |
930 | int err; | 930 | int err; |
931 | 931 | ||
932 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) | 932 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) |
933 | flags |= EXT4_FREE_BLOCKS_METADATA; | 933 | flags |= EXT4_FREE_BLOCKS_FORGET | EXT4_FREE_BLOCKS_METADATA; |
934 | else if (ext4_should_journal_data(inode)) | ||
935 | flags |= EXT4_FREE_BLOCKS_FORGET; | ||
934 | 936 | ||
935 | if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), block_to_free, | 937 | if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), block_to_free, |
936 | count)) { | 938 | count)) { |