Skip to content

Commit

Permalink
ext4: let ext4 maintain extent status tree
Browse files Browse the repository at this point in the history
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: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-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>
  • Loading branch information
Zheng Liu authored and Theodore Ts'o committed Nov 9, 2012
1 parent 9a26b66 commit 51865fd
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 4 deletions.
4 changes: 4 additions & 0 deletions fs/ext4/extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -4344,6 +4344,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
Expand Down Expand Up @@ -4971,6 +4973,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);
Expand Down
1 change: 1 addition & 0 deletions fs/ext4/indirect.c
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,7 @@ 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
Expand Down
38 changes: 35 additions & 3 deletions fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -1303,6 +1320,7 @@ static void ext4_da_page_release_reservation(struct page *page,
struct inode *inode = page->mapping->host;
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
int num_clusters;
ext4_fsblk_t lblk;

head = page_buffers(page);
bh = head;
Expand All @@ -1317,11 +1335,15 @@ static void ext4_da_page_release_reservation(struct page *page,
curr_off = next_off;
} 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
* need to release the reserved space for that cluster. */
num_clusters = EXT4_NUM_B2C(sbi, to_release);
while (num_clusters > 0) {
ext4_fsblk_t lblk;
lblk = (page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits)) +
((num_clusters - 1) << sbi->s_cluster_bits);
if (sbi->s_cluster_ratio == 1 ||
Expand Down Expand Up @@ -1502,9 +1524,15 @@ static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd)
struct pagevec pvec;
struct inode *inode = mpd->inode;
struct address_space *mapping = inode->i_mapping;
ext4_lblk_t start, last;

index = mpd->first_page;
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) {
nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE);
if (nr_pages == 0)
Expand Down Expand Up @@ -1816,6 +1844,10 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
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
* and it should not appear on the bh->b_state.
*/
Expand Down
12 changes: 11 additions & 1 deletion fs/ext4/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -1033,6 +1034,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);
Expand Down Expand Up @@ -5296,9 +5298,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;
Expand Down Expand Up @@ -5348,6 +5355,9 @@ static int __init ext4_init_fs(void)
ext4_exit_system_zone();
out6:
ext4_exit_pageio();
out7:
ext4_exit_es();

return err;
}

Expand Down

0 comments on commit 51865fd

Please sign in to comment.