diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-09-11 16:17:57 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:07 -0400 |
commit | d0c803c4049c5ca322d4795d8b74f28768603e0e (patch) | |
tree | b4c4f11b2f5938ad183a1771cd0b9e122709e2ff /fs/btrfs/disk-io.c | |
parent | 31ff1cd25d376e8f499d450de177dffadc9e1c56 (diff) |
Btrfs: Record dirty pages tree-log pages in an extent_io tree
This is the same way the transaction code makes sure that all the
other tree blocks are safely on disk. There's an extent_io tree
for each root, and any blocks allocated to the tree logs are
recorded in that tree.
At tree-log sync, the extent_io tree is walked to flush down the
dirty pages and wait for them.
The main benefit is less time spent walking the tree log and skipping
clean pages, and getting sequential IO down to the drive.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 5edb7f885799..57fbf107e59f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -777,6 +777,8 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
777 | spin_lock_init(&root->list_lock); | 777 | spin_lock_init(&root->list_lock); |
778 | mutex_init(&root->objectid_mutex); | 778 | mutex_init(&root->objectid_mutex); |
779 | mutex_init(&root->log_mutex); | 779 | mutex_init(&root->log_mutex); |
780 | extent_io_tree_init(&root->dirty_log_pages, | ||
781 | fs_info->btree_inode->i_mapping, GFP_NOFS); | ||
780 | 782 | ||
781 | btrfs_leaf_ref_tree_init(&root->ref_tree_struct); | 783 | btrfs_leaf_ref_tree_init(&root->ref_tree_struct); |
782 | root->ref_tree = &root->ref_tree_struct; | 784 | root->ref_tree = &root->ref_tree_struct; |
@@ -819,11 +821,23 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, | |||
819 | struct btrfs_fs_info *fs_info) | 821 | struct btrfs_fs_info *fs_info) |
820 | { | 822 | { |
821 | struct extent_buffer *eb; | 823 | struct extent_buffer *eb; |
824 | struct btrfs_root *log_root_tree = fs_info->log_root_tree; | ||
825 | u64 start = 0; | ||
826 | u64 end = 0; | ||
822 | int ret; | 827 | int ret; |
823 | 828 | ||
824 | if (!fs_info->log_root_tree) | 829 | if (!log_root_tree) |
825 | return 0; | 830 | return 0; |
826 | 831 | ||
832 | while(1) { | ||
833 | ret = find_first_extent_bit(&log_root_tree->dirty_log_pages, | ||
834 | 0, &start, &end, EXTENT_DIRTY); | ||
835 | if (ret) | ||
836 | break; | ||
837 | |||
838 | clear_extent_dirty(&log_root_tree->dirty_log_pages, | ||
839 | start, end, GFP_NOFS); | ||
840 | } | ||
827 | eb = fs_info->log_root_tree->node; | 841 | eb = fs_info->log_root_tree->node; |
828 | 842 | ||
829 | WARN_ON(btrfs_header_level(eb) != 0); | 843 | WARN_ON(btrfs_header_level(eb) != 0); |
@@ -1412,7 +1426,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1412 | memset(&BTRFS_I(fs_info->btree_inode)->location, 0, | 1426 | memset(&BTRFS_I(fs_info->btree_inode)->location, 0, |
1413 | sizeof(struct btrfs_key)); | 1427 | sizeof(struct btrfs_key)); |
1414 | insert_inode_hash(fs_info->btree_inode); | 1428 | insert_inode_hash(fs_info->btree_inode); |
1415 | mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS); | ||
1416 | 1429 | ||
1417 | mutex_init(&fs_info->trans_mutex); | 1430 | mutex_init(&fs_info->trans_mutex); |
1418 | mutex_init(&fs_info->tree_log_mutex); | 1431 | mutex_init(&fs_info->tree_log_mutex); |