[RFC][PATCH 04/10 v1][RESEND] ext4: let ext4 maintain extent status tree

Zheng Liu
2012-07-22T07:51:26Z

This patch lets ext4 maintain extent status tree.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: Allison Henderson <achender@linux.vnet.ibm.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
fs/ext4/extents.c | 2 ++
fs/ext4/indirect.c | 3 +++
fs/ext4/inode.c | 30 ++++++++++++++++++++++++++++--
fs/ext4/super.c | 12 +++++++++++-
4 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 91341ec..0747917 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4270,6 +4270,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_space(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
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index 830e1b2..e190427 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -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_space(inode, last_block,
+ EXT_MAX_BLOCKS - last_block);

/*
* The orphan list entry will now protect us from any crash which
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 02bc8cb..2f82630 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -555,7 +555,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;
}
@@ -637,8 +646,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_space(inode, map->m_lblk,
+ map->m_len);
+ if (ret < 0)
+ retval = ret;
+ }
}

up_write((&EXT4_I(inode)->i_data_sem));
@@ -1750,6 +1767,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))
@@ -1796,6 +1814,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_add_space(inode, map->m_lblk, map->m_len);
+ up_write((&EXT4_I(inode)->i_data_sem));
+ if (ret)
+ return ret;
+ }
+
return retval;
}

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 7cd5e4f..6f97c47 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -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>
@@ -1056,6 +1057,7 @@ void ext4_clear_inode(struct inode *inode)
clear_inode(inode);
dquot_drop(inode);
ext4_discard_preallocations(inode);
+ ext4_es_remove_space(inode, 0, EXT_MAX_BLOCKS);
if (EXT4_I(inode)->jinode) {
jbd2_journal_release_jbd_inode(EXT4_JOURNAL(inode),
EXT4_I(inode)->jinode);
@@ -5080,9 +5082,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;
@@ -5130,6 +5137,9 @@ out5:
ext4_exit_system_zone();
out6:
ext4_exit_pageio();
+out7:
+ ext4_exit_es();
+
return err;
}

--
1.7.4.1