]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ext4: let ext4 maintain extent status tree
authorZheng Liu <wenqing.lz@taobao.com>
Wed, 19 Sep 2012 19:06:50 +0000 (15:06 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 19 Sep 2012 19:06:50 +0000 (15:06 -0400)
This patch lets ext4 maintain extent status tree.

Reviewed-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Reviewed-by: Allison Henderson <achender@linux.vnet.ibm.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
fs/ext4/extents.c
fs/ext4/indirect.c
fs/ext4/inode.c
fs/ext4/super.c

index a510917c175a8581d115a50f9c84e2ce88a32dfc..45453fe77ed1c3cd91c2d571bb081ab1ca253268 100644 (file)
@@ -4330,6 +4330,8 @@ void ext4_ext_truncate(struct inode *inode)
 
        last_block = (inode->i_size + sb->s_blocksize - 1)
                        >> EXT4_BLOCK_SIZE_BITS(sb);
+       err = ext4_es_remove_extent(inode, last_block,
+                                   EXT_MAX_BLOCKS - last_block);
        err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1);
 
        /* In a multi-transaction truncate, we only make the final
@@ -4937,6 +4939,8 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
        ext4_ext_invalidate_cache(inode);
        ext4_discard_preallocations(inode);
 
+       err = ext4_es_remove_extent(inode, first_block,
+                                   stop_block - first_block);
        err = ext4_ext_remove_space(inode, first_block, stop_block - 1);
 
        ext4_ext_invalidate_cache(inode);
index 830e1b2bf145c99f1ebdc2198147295d73eff8ac..9db67b15daad5674c055e09a4996460cc1596012 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include "ext4_jbd2.h"
+#include "ext4_extents.h"
 #include "truncate.h"
 
 #include <trace/events/ext4.h>
@@ -1398,6 +1399,8 @@ void ext4_ind_truncate(struct inode *inode)
        down_write(&ei->i_data_sem);
 
        ext4_discard_preallocations(inode);
+       ext4_es_remove_extent(inode, last_block,
+                             EXT_MAX_BLOCKS - last_block);
 
        /*
         * The orphan list entry will now protect us from any crash which
index ca76b5ed6c9e93d11afbc4d6350089b26943d9bc..4446e4696d0b7dc4b67be1eb8f1aa79fa3b7dffe 100644 (file)
@@ -574,7 +574,16 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
                up_read((&EXT4_I(inode)->i_data_sem));
 
        if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
-               int ret = check_block_validity(inode, map);
+               int ret;
+               if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) {
+                       /* delayed alloc may be allocated by fallocate and
+                        * coverted to initialized by directIO.
+                        * we need to handle delayed extent here.
+                        */
+                       down_write((&EXT4_I(inode)->i_data_sem));
+                       goto delayed_mapped;
+               }
+               ret = check_block_validity(inode, map);
                if (ret != 0)
                        return ret;
        }
@@ -656,8 +665,16 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
                 * set the BH_Da_Mapped bit on them. Its important to do this
                 * under the protection of i_data_sem.
                 */
-               if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED)
+               if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
+                       int ret;
                        set_buffers_da_mapped(inode, map);
+delayed_mapped:
+                       /* delayed allocation blocks has been allocated */
+                       ret = ext4_es_remove_extent(inode, map->m_lblk,
+                                                   map->m_len);
+                       if (ret < 0)
+                               retval = ret;
+               }
        }
 
        up_write((&EXT4_I(inode)->i_data_sem));
@@ -1781,6 +1798,7 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
                              struct buffer_head *bh)
 {
        int retval;
+       int ret;
        sector_t invalid_block = ~((sector_t) 0xffff);
 
        if (invalid_block < ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es))
@@ -1827,6 +1845,14 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
 out_unlock:
        up_read((&EXT4_I(inode)->i_data_sem));
 
+       if (retval == 0) {
+               down_write((&EXT4_I(inode)->i_data_sem));
+               ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len);
+               up_write((&EXT4_I(inode)->i_data_sem));
+               if (ret)
+                       return ret;
+       }
+
        return retval;
 }
 
index 214e528ef0015699ea03074950dab35897ed1741..afeddd710424e9fa67dcbb438c9833f4449a8ee0 100644 (file)
@@ -50,6 +50,7 @@
 #include "xattr.h"
 #include "acl.h"
 #include "mballoc.h"
+#include "ext4_extents.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/ext4.h>
@@ -1038,6 +1039,7 @@ void ext4_clear_inode(struct inode *inode)
        clear_inode(inode);
        dquot_drop(inode);
        ext4_discard_preallocations(inode);
+       ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS);
        if (EXT4_I(inode)->jinode) {
                jbd2_journal_release_jbd_inode(EXT4_JOURNAL(inode),
                                               EXT4_I(inode)->jinode);
@@ -5294,9 +5296,14 @@ static int __init ext4_init_fs(void)
                init_waitqueue_head(&ext4__ioend_wq[i]);
        }
 
-       err = ext4_init_pageio();
+       err = ext4_init_es();
        if (err)
                return err;
+
+       err = ext4_init_pageio();
+       if (err)
+               goto out7;
+
        err = ext4_init_system_zone();
        if (err)
                goto out6;
@@ -5346,6 +5353,9 @@ out5:
        ext4_exit_system_zone();
 out6:
        ext4_exit_pageio();
+out7:
+       ext4_exit_es();
+
        return err;
 }