ext4: don't use EXT4_FREE_BLOCKS_FORGET unnecessarily
authorTheodore Ts'o <tytso@mit.edu>
Wed, 12 Jun 2013 15:48:29 +0000 (11:48 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 12 Jun 2013 15:48:29 +0000 (11:48 -0400)
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>
fs/ext4/extents.c
fs/ext4/indirect.c

index 208f664..d04f409 100644 (file)
@@ -2355,6 +2355,15 @@ int ext4_ext_index_trans_blocks(struct inode *inode, int extents)
        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,
                              struct ext4_extent *ex,
                              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);
        unsigned short ee_len =  ext4_ext_get_actual_len(ex);
        ext4_fsblk_t pblk;
-       int flags = 0;
-
-       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;
+       int flags = get_default_free_blocks_flags(inode);
 
        /*
         * 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 &&
            (EXT4_B2C(sbi, ext4_ext_pblock(ex) + ex_ee_len - 1) !=
             *partial_cluster)) {
-               int flags = EXT4_FREE_BLOCKS_FORGET;
-
-               if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
-                       flags |= EXT4_FREE_BLOCKS_METADATA;
+               int flags = get_default_free_blocks_flags(inode);
 
                ext4_free_blocks(handle, inode, NULL,
                                 EXT4_C2B(sbi, *partial_cluster),
@@ -2869,10 +2870,7 @@ again:
         * even the first extent, then we should free the blocks in the partial
         * cluster as well. */
        if (partial_cluster > 0 && path->p_hdr->eh_entries == 0) {
-               int flags = EXT4_FREE_BLOCKS_FORGET;
-
-               if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
-                       flags |= EXT4_FREE_BLOCKS_METADATA;
+               int flags = get_default_free_blocks_flags(inode);
 
                ext4_free_blocks(handle, inode, NULL,
                                 EXT4_C2B(EXT4_SB(sb), partial_cluster),
index 2a1f8a5..963d23d 100644 (file)
@@ -926,11 +926,13 @@ static int ext4_clear_blocks(handle_t *handle, struct inode *inode,
                             __le32 *last)
 {
        __le32 *p;
-       int     flags = EXT4_FREE_BLOCKS_FORGET | EXT4_FREE_BLOCKS_VALIDATED;
+       int     flags = EXT4_FREE_BLOCKS_VALIDATED;
        int     err;
 
        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,
                                   count)) {