aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 087074db0bd5..750f35a37aae 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -19,6 +19,7 @@
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/writeback.h> 21#include <linux/writeback.h>
22#include <linux/pagemap.h>
22#include "ctree.h" 23#include "ctree.h"
23#include "disk-io.h" 24#include "disk-io.h"
24#include "transaction.h" 25#include "transaction.h"
@@ -66,7 +67,9 @@ static int join_transaction(struct btrfs_root *root)
66 cur_trans->commit_done = 0; 67 cur_trans->commit_done = 0;
67 cur_trans->start_time = get_seconds(); 68 cur_trans->start_time = get_seconds();
68 list_add_tail(&cur_trans->list, &root->fs_info->trans_list); 69 list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
69 init_bit_radix(&cur_trans->dirty_pages); 70 extent_map_tree_init(&cur_trans->dirty_pages,
71 root->fs_info->btree_inode->i_mapping,
72 GFP_NOFS);
70 } else { 73 } else {
71 cur_trans->num_writers++; 74 cur_trans->num_writers++;
72 cur_trans->num_joined++; 75 cur_trans->num_joined++;
@@ -88,7 +91,7 @@ static int record_root_in_trans(struct btrfs_root *root)
88 (unsigned long)root->root_key.objectid, 91 (unsigned long)root->root_key.objectid,
89 BTRFS_ROOT_DEFRAG_TAG); 92 BTRFS_ROOT_DEFRAG_TAG);
90 root->commit_root = root->node; 93 root->commit_root = root->node;
91 get_bh(root->node); 94 extent_buffer_get(root->node);
92 } else { 95 } else {
93 WARN_ON(1); 96 WARN_ON(1);
94 } 97 }
@@ -144,29 +147,30 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
144int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, 147int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
145 struct btrfs_root *root) 148 struct btrfs_root *root)
146{ 149{
147 unsigned long gang[16];
148 int ret; 150 int ret;
149 int i;
150 int err; 151 int err;
151 int werr = 0; 152 int werr = 0;
153 struct extent_map_tree *dirty_pages;
152 struct page *page; 154 struct page *page;
153 struct radix_tree_root *dirty_pages;
154 struct inode *btree_inode = root->fs_info->btree_inode; 155 struct inode *btree_inode = root->fs_info->btree_inode;
156 u64 start;
157 u64 end;
158 unsigned long index;
155 159
156 if (!trans || !trans->transaction) { 160 if (!trans || !trans->transaction) {
157 return filemap_write_and_wait(btree_inode->i_mapping); 161 return filemap_write_and_wait(btree_inode->i_mapping);
158 } 162 }
159 dirty_pages = &trans->transaction->dirty_pages; 163 dirty_pages = &trans->transaction->dirty_pages;
160 while(1) { 164 while(1) {
161 ret = find_first_radix_bit(dirty_pages, gang, 165 ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
162 0, ARRAY_SIZE(gang)); 166 EXTENT_DIRTY);
163 if (!ret) 167 if (ret)
164 break; 168 break;
165 for (i = 0; i < ret; i++) { 169 clear_extent_dirty(dirty_pages, start, end, GFP_NOFS);
166 /* FIXME EIO */ 170 while(start <= end) {
167 clear_radix_bit(dirty_pages, gang[i]); 171 index = start >> PAGE_CACHE_SHIFT;
168 page = find_lock_page(btree_inode->i_mapping, 172 start = (index + 1) << PAGE_CACHE_SHIFT;
169 gang[i]); 173 page = find_lock_page(btree_inode->i_mapping, index);
170 if (!page) 174 if (!page)
171 continue; 175 continue;
172 if (PageWriteback(page)) { 176 if (PageWriteback(page)) {
@@ -202,10 +206,11 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
202 btrfs_write_dirty_block_groups(trans, extent_root); 206 btrfs_write_dirty_block_groups(trans, extent_root);
203 while(1) { 207 while(1) {
204 old_extent_block = btrfs_root_blocknr(&extent_root->root_item); 208 old_extent_block = btrfs_root_blocknr(&extent_root->root_item);
205 if (old_extent_block == bh_blocknr(extent_root->node)) 209 if (old_extent_block ==
210 extent_buffer_blocknr(extent_root->node))
206 break; 211 break;
207 btrfs_set_root_blocknr(&extent_root->root_item, 212 btrfs_set_root_blocknr(&extent_root->root_item,
208 bh_blocknr(extent_root->node)); 213 extent_buffer_blocknr(extent_root->node));
209 ret = btrfs_update_root(trans, tree_root, 214 ret = btrfs_update_root(trans, tree_root,
210 &extent_root->root_key, 215 &extent_root->root_key,
211 &extent_root->root_item); 216 &extent_root->root_item);
@@ -279,9 +284,9 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
279 (unsigned long)root->root_key.objectid, 284 (unsigned long)root->root_key.objectid,
280 BTRFS_ROOT_TRANS_TAG); 285 BTRFS_ROOT_TRANS_TAG);
281 if (root->commit_root == root->node) { 286 if (root->commit_root == root->node) {
282 WARN_ON(bh_blocknr(root->node) != 287 WARN_ON(extent_buffer_blocknr(root->node) !=
283 btrfs_root_blocknr(&root->root_item)); 288 btrfs_root_blocknr(&root->root_item));
284 brelse(root->commit_root); 289 free_extent_buffer(root->commit_root);
285 root->commit_root = NULL; 290 root->commit_root = NULL;
286 291
287 /* make sure to update the root on disk 292 /* make sure to update the root on disk
@@ -310,7 +315,7 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
310 315
311 root->root_key.offset = root->fs_info->generation; 316 root->root_key.offset = root->fs_info->generation;
312 btrfs_set_root_blocknr(&root->root_item, 317 btrfs_set_root_blocknr(&root->root_item,
313 bh_blocknr(root->node)); 318 extent_buffer_blocknr(root->node));
314 err = btrfs_insert_root(trans, root->fs_info->tree_root, 319 err = btrfs_insert_root(trans, root->fs_info->tree_root,
315 &root->root_key, 320 &root->root_key,
316 &root->root_item); 321 &root->root_item);
@@ -389,10 +394,10 @@ int btrfs_defrag_dirty_roots(struct btrfs_fs_info *info)
389 for (i = 0; i < ret; i++) { 394 for (i = 0; i < ret; i++) {
390 root = gang[i]; 395 root = gang[i];
391 last = root->root_key.objectid + 1; 396 last = root->root_key.objectid + 1;
392 btrfs_defrag_root(root, 1); 397 // btrfs_defrag_root(root, 1);
393 } 398 }
394 } 399 }
395 btrfs_defrag_root(info->extent_root, 1); 400 // btrfs_defrag_root(info->extent_root, 1);
396 return err; 401 return err;
397} 402}
398 403
@@ -414,7 +419,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
414 dirty = list_entry(list->next, struct dirty_root, list); 419 dirty = list_entry(list->next, struct dirty_root, list);
415 list_del_init(&dirty->list); 420 list_del_init(&dirty->list);
416 421
417 num_blocks = btrfs_root_blocks_used(&dirty->root->root_item); 422 num_blocks = btrfs_root_used(&dirty->root->root_item);
418 root = dirty->latest_root; 423 root = dirty->latest_root;
419 424
420 while(1) { 425 while(1) {
@@ -441,11 +446,11 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
441 } 446 }
442 BUG_ON(ret); 447 BUG_ON(ret);
443 448
444 num_blocks -= btrfs_root_blocks_used(&dirty->root->root_item); 449 num_blocks -= btrfs_root_used(&dirty->root->root_item);
445 blocks_used = btrfs_root_blocks_used(&root->root_item); 450 blocks_used = btrfs_root_used(&root->root_item);
446 if (num_blocks) { 451 if (num_blocks) {
447 record_root_in_trans(root); 452 record_root_in_trans(root);
448 btrfs_set_root_blocks_used(&root->root_item, 453 btrfs_set_root_used(&root->root_item,
449 blocks_used - num_blocks); 454 blocks_used - num_blocks);
450 } 455 }
451 ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key); 456 ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key);
@@ -553,9 +558,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
553 btrfs_set_super_generation(&root->fs_info->super_copy, 558 btrfs_set_super_generation(&root->fs_info->super_copy,
554 cur_trans->transid); 559 cur_trans->transid);
555 btrfs_set_super_root(&root->fs_info->super_copy, 560 btrfs_set_super_root(&root->fs_info->super_copy,
556 bh_blocknr(root->fs_info->tree_root->node)); 561 extent_buffer_blocknr(root->fs_info->tree_root->node));
557 memcpy(root->fs_info->disk_super, &root->fs_info->super_copy, 562
558 sizeof(root->fs_info->super_copy)); 563 write_extent_buffer(root->fs_info->sb_buffer,
564 &root->fs_info->super_copy, 0,
565 sizeof(root->fs_info->super_copy));
559 566
560 btrfs_copy_pinned(root, &pinned_copy); 567 btrfs_copy_pinned(root, &pinned_copy);
561 568