diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-04-28 09:29:35 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-04-28 09:29:35 -0400 |
commit | 7c4452b9a6ca7aabe37ea2e43d443110bdc08cd8 (patch) | |
tree | 6d3db5ec3a394dfcf143869796f1c59c4e86278f /fs/btrfs | |
parent | 06a2f9fa4c12a055cc396936408a78ae0acfb6b4 (diff) |
Btrfs: smarter transaction writeback
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 1 | ||||
-rw-r--r-- | fs/btrfs/super.c | 1 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 37 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 1 |
4 files changed, 37 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index afc5267515e2..652cf305a967 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -762,6 +762,7 @@ struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
762 | BUG_ON(ret); | 762 | BUG_ON(ret); |
763 | buf = btrfs_find_create_tree_block(root, ins.objectid); | 763 | buf = btrfs_find_create_tree_block(root, ins.objectid); |
764 | set_buffer_uptodate(buf); | 764 | set_buffer_uptodate(buf); |
765 | set_radix_bit(&trans->transaction->dirty_pages, buf->b_page->index); | ||
765 | return buf; | 766 | return buf; |
766 | } | 767 | } |
767 | 768 | ||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index a10e902d3102..1890e8648dbd 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -980,7 +980,6 @@ static int btrfs_sync_fs(struct super_block *sb, int wait) | |||
980 | filemap_flush(root->fs_info->btree_inode->i_mapping); | 980 | filemap_flush(root->fs_info->btree_inode->i_mapping); |
981 | return 0; | 981 | return 0; |
982 | } | 982 | } |
983 | filemap_write_and_wait(root->fs_info->btree_inode->i_mapping); | ||
984 | mutex_lock(&root->fs_info->fs_mutex); | 983 | mutex_lock(&root->fs_info->fs_mutex); |
985 | trans = btrfs_start_transaction(root, 1); | 984 | trans = btrfs_start_transaction(root, 1); |
986 | ret = btrfs_commit_transaction(trans, root); | 985 | ret = btrfs_commit_transaction(trans, root); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 8a2545f6a5b6..f9b8864dcc40 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -45,6 +45,7 @@ static int join_transaction(struct btrfs_root *root) | |||
45 | cur_trans->use_count = 1; | 45 | cur_trans->use_count = 1; |
46 | cur_trans->commit_done = 0; | 46 | cur_trans->commit_done = 0; |
47 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); | 47 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); |
48 | init_bit_radix(&cur_trans->dirty_pages); | ||
48 | } | 49 | } |
49 | cur_trans->num_writers++; | 50 | cur_trans->num_writers++; |
50 | return 0; | 51 | return 0; |
@@ -106,8 +107,40 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
106 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | 107 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, |
107 | struct btrfs_root *root) | 108 | struct btrfs_root *root) |
108 | { | 109 | { |
109 | filemap_write_and_wait(root->fs_info->btree_inode->i_mapping); | 110 | unsigned long gang[16]; |
110 | return 0; | 111 | int ret; |
112 | int i; | ||
113 | int err; | ||
114 | int werr = 0; | ||
115 | struct page *page; | ||
116 | struct radix_tree_root *dirty_pages; | ||
117 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
118 | |||
119 | if (!trans || !trans->transaction) { | ||
120 | return filemap_write_and_wait(btree_inode->i_mapping); | ||
121 | } | ||
122 | dirty_pages = &trans->transaction->dirty_pages; | ||
123 | while(1) { | ||
124 | ret = find_first_radix_bit(dirty_pages, gang, ARRAY_SIZE(gang)); | ||
125 | if (!ret) | ||
126 | break; | ||
127 | for (i = 0; i < ret; i++) { | ||
128 | /* FIXME EIO */ | ||
129 | clear_radix_bit(dirty_pages, gang[i]); | ||
130 | page = find_lock_page(btree_inode->i_mapping, | ||
131 | gang[i]); | ||
132 | if (!page) | ||
133 | continue; | ||
134 | err = write_one_page(page, 0); | ||
135 | if (err) | ||
136 | werr = err; | ||
137 | page_cache_release(page); | ||
138 | } | ||
139 | } | ||
140 | err = filemap_fdatawait(btree_inode->i_mapping); | ||
141 | if (err) | ||
142 | werr = err; | ||
143 | return werr; | ||
111 | } | 144 | } |
112 | 145 | ||
113 | int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, | 146 | int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 3cc29900a074..afe42d167cee 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -9,6 +9,7 @@ struct btrfs_transaction { | |||
9 | int commit_done; | 9 | int commit_done; |
10 | int magic; | 10 | int magic; |
11 | struct list_head list; | 11 | struct list_head list; |
12 | struct radix_tree_root dirty_pages; | ||
12 | wait_queue_head_t writer_wait; | 13 | wait_queue_head_t writer_wait; |
13 | wait_queue_head_t commit_wait; | 14 | wait_queue_head_t commit_wait; |
14 | }; | 15 | }; |