Commit 51865fda authored by Zheng Liu's avatar Zheng Liu Committed by Theodore Ts'o

ext4: let ext4 maintain extent status tree

This patch lets ext4 maintain extent status tree.

Currently it only tracks delay extent status in extent status tree.  When a
delay allocation is issued, the related delay extent will be inserted into
extent status tree.  When a delay extent is written out or invalidated, it will
be removed from this tree.
Signed-off-by: default avatarYongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: default avatarAllison Henderson <achender@linux.vnet.ibm.com>
Signed-off-by: default avatarZheng Liu <wenqing.lz@taobao.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 9a26b661
...@@ -4344,6 +4344,8 @@ void ext4_ext_truncate(struct inode *inode) ...@@ -4344,6 +4344,8 @@ void ext4_ext_truncate(struct inode *inode)
last_block = (inode->i_size + sb->s_blocksize - 1) last_block = (inode->i_size + sb->s_blocksize - 1)
>> EXT4_BLOCK_SIZE_BITS(sb); >> 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); err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1);
/* In a multi-transaction truncate, we only make the final /* In a multi-transaction truncate, we only make the final
...@@ -4971,6 +4973,8 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length) ...@@ -4971,6 +4973,8 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
ext4_ext_invalidate_cache(inode); ext4_ext_invalidate_cache(inode);
ext4_discard_preallocations(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); err = ext4_ext_remove_space(inode, first_block, stop_block - 1);
ext4_ext_invalidate_cache(inode); ext4_ext_invalidate_cache(inode);
......
...@@ -1411,6 +1411,7 @@ void ext4_ind_truncate(struct inode *inode) ...@@ -1411,6 +1411,7 @@ void ext4_ind_truncate(struct inode *inode)
down_write(&ei->i_data_sem); down_write(&ei->i_data_sem);
ext4_discard_preallocations(inode); 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 * The orphan list entry will now protect us from any crash which
......
...@@ -574,7 +574,16 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, ...@@ -574,7 +574,16 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
up_read((&EXT4_I(inode)->i_data_sem)); up_read((&EXT4_I(inode)->i_data_sem));
if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { 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) if (ret != 0)
return ret; return ret;
} }
...@@ -656,8 +665,16 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, ...@@ -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 * set the BH_Da_Mapped bit on them. Its important to do this
* under the protection of i_data_sem. * 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); 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)); up_write((&EXT4_I(inode)->i_data_sem));
...@@ -1303,6 +1320,7 @@ static void ext4_da_page_release_reservation(struct page *page, ...@@ -1303,6 +1320,7 @@ static void ext4_da_page_release_reservation(struct page *page,
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
int num_clusters; int num_clusters;
ext4_fsblk_t lblk;
head = page_buffers(page); head = page_buffers(page);
bh = head; bh = head;
...@@ -1317,11 +1335,15 @@ static void ext4_da_page_release_reservation(struct page *page, ...@@ -1317,11 +1335,15 @@ static void ext4_da_page_release_reservation(struct page *page,
curr_off = next_off; curr_off = next_off;
} while ((bh = bh->b_this_page) != head); } while ((bh = bh->b_this_page) != head);
if (to_release) {
lblk = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
ext4_es_remove_extent(inode, lblk, to_release);
}
/* If we have released all the blocks belonging to a cluster, then we /* If we have released all the blocks belonging to a cluster, then we
* need to release the reserved space for that cluster. */ * need to release the reserved space for that cluster. */
num_clusters = EXT4_NUM_B2C(sbi, to_release); num_clusters = EXT4_NUM_B2C(sbi, to_release);
while (num_clusters > 0) { while (num_clusters > 0) {
ext4_fsblk_t lblk;
lblk = (page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits)) + lblk = (page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits)) +
((num_clusters - 1) << sbi->s_cluster_bits); ((num_clusters - 1) << sbi->s_cluster_bits);
if (sbi->s_cluster_ratio == 1 || if (sbi->s_cluster_ratio == 1 ||
...@@ -1502,9 +1524,15 @@ static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd) ...@@ -1502,9 +1524,15 @@ static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd)
struct pagevec pvec; struct pagevec pvec;
struct inode *inode = mpd->inode; struct inode *inode = mpd->inode;
struct address_space *mapping = inode->i_mapping; struct address_space *mapping = inode->i_mapping;
ext4_lblk_t start, last;
index = mpd->first_page; index = mpd->first_page;
end = mpd->next_page - 1; end = mpd->next_page - 1;
start = index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
last = end << (PAGE_CACHE_SHIFT - inode->i_blkbits);
ext4_es_remove_extent(inode, start, last - start + 1);
while (index <= end) { while (index <= end) {
nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE); nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE);
if (nr_pages == 0) if (nr_pages == 0)
...@@ -1816,6 +1844,10 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, ...@@ -1816,6 +1844,10 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
goto out_unlock; goto out_unlock;
} }
retval = ext4_es_insert_extent(inode, map->m_lblk, map->m_len);
if (retval)
goto out_unlock;
/* Clear EXT4_MAP_FROM_CLUSTER flag since its purpose is served /* Clear EXT4_MAP_FROM_CLUSTER flag since its purpose is served
* and it should not appear on the bh->b_state. * and it should not appear on the bh->b_state.
*/ */
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "xattr.h" #include "xattr.h"
#include "acl.h" #include "acl.h"
#include "mballoc.h" #include "mballoc.h"
#include "ext4_extents.h"
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/ext4.h> #include <trace/events/ext4.h>
...@@ -1033,6 +1034,7 @@ void ext4_clear_inode(struct inode *inode) ...@@ -1033,6 +1034,7 @@ void ext4_clear_inode(struct inode *inode)
clear_inode(inode); clear_inode(inode);
dquot_drop(inode); dquot_drop(inode);
ext4_discard_preallocations(inode); ext4_discard_preallocations(inode);
ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS);
if (EXT4_I(inode)->jinode) { if (EXT4_I(inode)->jinode) {
jbd2_journal_release_jbd_inode(EXT4_JOURNAL(inode), jbd2_journal_release_jbd_inode(EXT4_JOURNAL(inode),
EXT4_I(inode)->jinode); EXT4_I(inode)->jinode);
...@@ -5296,9 +5298,14 @@ static int __init ext4_init_fs(void) ...@@ -5296,9 +5298,14 @@ static int __init ext4_init_fs(void)
init_waitqueue_head(&ext4__ioend_wq[i]); init_waitqueue_head(&ext4__ioend_wq[i]);
} }
err = ext4_init_pageio(); err = ext4_init_es();
if (err) if (err)
return err; return err;
err = ext4_init_pageio();
if (err)
goto out7;
err = ext4_init_system_zone(); err = ext4_init_system_zone();
if (err) if (err)
goto out6; goto out6;
...@@ -5348,6 +5355,9 @@ static int __init ext4_init_fs(void) ...@@ -5348,6 +5355,9 @@ static int __init ext4_init_fs(void)
ext4_exit_system_zone(); ext4_exit_system_zone();
out6: out6:
ext4_exit_pageio(); ext4_exit_pageio();
out7:
ext4_exit_es();
return err; return err;
} }
......
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