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/transaction.c | |
parent | 06a2f9fa4c12a055cc396936408a78ae0acfb6b4 (diff) |
Btrfs: smarter transaction writeback
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 37 |
1 files changed, 35 insertions, 2 deletions
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, |