aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-06-28 15:57:36 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-06-28 15:57:36 -0400
commitccd467d60e81b48cdbecae93532b66bcdedca91d (patch)
tree7c8c74ca8c6c058fc2e3c90c0082e796b7c1e92e /fs/btrfs/extent-tree.c
parentf2654de42a759127cb1f1e8a626ec94178732e20 (diff)
Btrfs: crash recovery fixes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 01dc30579287..14b93268920e 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -523,6 +523,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
523 } 523 }
524 return 0; 524 return 0;
525fail: 525fail:
526 WARN_ON(1);
526 for (i =0; i < faili; i++) { 527 for (i =0; i < faili; i++) {
527 if (leaf) { 528 if (leaf) {
528 u64 disk_blocknr; 529 u64 disk_blocknr;
@@ -572,7 +573,7 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans,
572 bi = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], 573 bi = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
573 struct btrfs_block_group_item); 574 struct btrfs_block_group_item);
574 memcpy(bi, &cache->item, sizeof(*bi)); 575 memcpy(bi, &cache->item, sizeof(*bi));
575 mark_buffer_dirty(path->nodes[0]); 576 btrfs_mark_buffer_dirty(path->nodes[0]);
576 btrfs_release_path(extent_root, path); 577 btrfs_release_path(extent_root, path);
577fail: 578fail:
578 finish_current_insert(trans, extent_root); 579 finish_current_insert(trans, extent_root);
@@ -739,8 +740,30 @@ static int try_remove_page(struct address_space *mapping, unsigned long index)
739 return ret; 740 return ret;
740} 741}
741 742
742int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct 743int btrfs_copy_pinned(struct btrfs_root *root, struct radix_tree_root *copy)
743 btrfs_root *root) 744{
745 unsigned long gang[8];
746 u64 last = 0;
747 struct radix_tree_root *pinned_radix = &root->fs_info->pinned_radix;
748 int ret;
749 int i;
750
751 while(1) {
752 ret = find_first_radix_bit(pinned_radix, gang, last,
753 ARRAY_SIZE(gang));
754 if (!ret)
755 break;
756 for (i = 0 ; i < ret; i++) {
757 set_radix_bit(copy, gang[i]);
758 last = gang[i] + 1;
759 }
760 }
761 return 0;
762}
763
764int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
765 struct btrfs_root *root,
766 struct radix_tree_root *unpin_radix)
744{ 767{
745 unsigned long gang[8]; 768 unsigned long gang[8];
746 struct inode *btree_inode = root->fs_info->btree_inode; 769 struct inode *btree_inode = root->fs_info->btree_inode;
@@ -752,7 +775,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
752 struct radix_tree_root *extent_radix = &root->fs_info->extent_map_radix; 775 struct radix_tree_root *extent_radix = &root->fs_info->extent_map_radix;
753 776
754 while(1) { 777 while(1) {
755 ret = find_first_radix_bit(pinned_radix, gang, 0, 778 ret = find_first_radix_bit(unpin_radix, gang, 0,
756 ARRAY_SIZE(gang)); 779 ARRAY_SIZE(gang));
757 if (!ret) 780 if (!ret)
758 break; 781 break;
@@ -760,6 +783,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
760 first = gang[0]; 783 first = gang[0];
761 for (i = 0; i < ret; i++) { 784 for (i = 0; i < ret; i++) {
762 clear_radix_bit(pinned_radix, gang[i]); 785 clear_radix_bit(pinned_radix, gang[i]);
786 clear_radix_bit(unpin_radix, gang[i]);
763 block_group = btrfs_lookup_block_group(root->fs_info, 787 block_group = btrfs_lookup_block_group(root->fs_info,
764 gang[i]); 788 gang[i]);
765 if (block_group) { 789 if (block_group) {
@@ -1309,6 +1333,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1309 if (data) { 1333 if (data) {
1310 ret = find_free_extent(trans, root, 0, 0, 1334 ret = find_free_extent(trans, root, 0, 0,
1311 search_end, 0, &prealloc_key, 0, 0, 0); 1335 search_end, 0, &prealloc_key, 0, 0, 0);
1336 BUG_ON(ret);
1312 if (ret) 1337 if (ret)
1313 return ret; 1338 return ret;
1314 exclude_nr = info->extent_tree_prealloc_nr; 1339 exclude_nr = info->extent_tree_prealloc_nr;
@@ -1319,6 +1344,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1319 ret = find_free_extent(trans, root, num_blocks, search_start, 1344 ret = find_free_extent(trans, root, num_blocks, search_start,
1320 search_end, hint_block, ins, 1345 search_end, hint_block, ins,
1321 exclude_start, exclude_nr, data); 1346 exclude_start, exclude_nr, data);
1347 BUG_ON(ret);
1322 if (ret) 1348 if (ret)
1323 return ret; 1349 return ret;
1324 1350
@@ -1334,10 +1360,12 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1334 if (!data) { 1360 if (!data) {
1335 exclude_start = ins->objectid; 1361 exclude_start = ins->objectid;
1336 exclude_nr = ins->offset; 1362 exclude_nr = ins->offset;
1363 hint_block = exclude_start + exclude_nr;
1337 ret = find_free_extent(trans, root, 0, search_start, 1364 ret = find_free_extent(trans, root, 0, search_start,
1338 search_end, hint_block, 1365 search_end, hint_block,
1339 &prealloc_key, exclude_start, 1366 &prealloc_key, exclude_start,
1340 exclude_nr, 0); 1367 exclude_nr, 0);
1368 BUG_ON(ret);
1341 if (ret) 1369 if (ret)
1342 return ret; 1370 return ret;
1343 } 1371 }
@@ -1348,6 +1376,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1348 ret = btrfs_insert_item(trans, extent_root, ins, &extent_item, 1376 ret = btrfs_insert_item(trans, extent_root, ins, &extent_item,
1349 sizeof(extent_item)); 1377 sizeof(extent_item));
1350 1378
1379 BUG_ON(ret);
1351 finish_current_insert(trans, extent_root); 1380 finish_current_insert(trans, extent_root);
1352 pending_ret = del_pending_extents(trans, extent_root); 1381 pending_ret = del_pending_extents(trans, extent_root);
1353 if (ret) { 1382 if (ret) {