aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-09-11 16:17:57 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:07 -0400
commitd0c803c4049c5ca322d4795d8b74f28768603e0e (patch)
treeb4c4f11b2f5938ad183a1771cd0b9e122709e2ff /fs/btrfs/tree-log.c
parent31ff1cd25d376e8f499d450de177dffadc9e1c56 (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/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index ae96451bc223..bfa710800963 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1954,10 +1954,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
1954 int ret; 1954 int ret;
1955 unsigned long batch; 1955 unsigned long batch;
1956 struct btrfs_root *log = root->log_root; 1956 struct btrfs_root *log = root->log_root;
1957 struct walk_control wc = {
1958 .write = 1,
1959 .process_func = process_one_buffer
1960 };
1961 1957
1962 mutex_lock(&log->fs_info->tree_log_mutex); 1958 mutex_lock(&log->fs_info->tree_log_mutex);
1963 if (atomic_read(&log->fs_info->tree_log_commit)) { 1959 if (atomic_read(&log->fs_info->tree_log_commit)) {
@@ -1985,18 +1981,11 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
1985 if (batch == log->fs_info->tree_log_batch) 1981 if (batch == log->fs_info->tree_log_batch)
1986 break; 1982 break;
1987 } 1983 }
1988 ret = walk_log_tree(trans, log, &wc);
1989 BUG_ON(ret);
1990
1991 ret = walk_log_tree(trans, log->fs_info->log_root_tree, &wc);
1992 BUG_ON(ret);
1993
1994 wc.wait = 1;
1995 1984
1996 ret = walk_log_tree(trans, log, &wc); 1985 ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages);
1997 BUG_ON(ret); 1986 BUG_ON(ret);
1998 1987 ret = btrfs_write_and_wait_marked_extents(root->fs_info->log_root_tree,
1999 ret = walk_log_tree(trans, log->fs_info->log_root_tree, &wc); 1988 &root->fs_info->log_root_tree->dirty_log_pages);
2000 BUG_ON(ret); 1989 BUG_ON(ret);
2001 1990
2002 btrfs_set_super_log_root(&root->fs_info->super_for_commit, 1991 btrfs_set_super_log_root(&root->fs_info->super_for_commit,
@@ -2025,6 +2014,8 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root)
2025 int ret; 2014 int ret;
2026 struct btrfs_root *log; 2015 struct btrfs_root *log;
2027 struct key; 2016 struct key;
2017 u64 start;
2018 u64 end;
2028 struct walk_control wc = { 2019 struct walk_control wc = {
2029 .free = 1, 2020 .free = 1,
2030 .process_func = process_one_buffer 2021 .process_func = process_one_buffer
@@ -2037,6 +2028,16 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root)
2037 ret = walk_log_tree(trans, log, &wc); 2028 ret = walk_log_tree(trans, log, &wc);
2038 BUG_ON(ret); 2029 BUG_ON(ret);
2039 2030
2031 while(1) {
2032 ret = find_first_extent_bit(&log->dirty_log_pages,
2033 0, &start, &end, EXTENT_DIRTY);
2034 if (ret)
2035 break;
2036
2037 clear_extent_dirty(&log->dirty_log_pages,
2038 start, end, GFP_NOFS);
2039 }
2040
2040 log = root->log_root; 2041 log = root->log_root;
2041 ret = btrfs_del_root(trans, root->fs_info->log_root_tree, 2042 ret = btrfs_del_root(trans, root->fs_info->log_root_tree,
2042 &log->root_key); 2043 &log->root_key);