diff options
-rw-r--r-- | fs/btrfs/extent-tree.c | 54 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 12 |
2 files changed, 42 insertions, 24 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 155c8dc56a22..fada9c22a021 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -45,9 +45,9 @@ struct pending_extent_op { | |||
45 | }; | 45 | }; |
46 | 46 | ||
47 | static int finish_current_insert(struct btrfs_trans_handle *trans, struct | 47 | static int finish_current_insert(struct btrfs_trans_handle *trans, struct |
48 | btrfs_root *extent_root); | 48 | btrfs_root *extent_root, int all); |
49 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct | 49 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct |
50 | btrfs_root *extent_root); | 50 | btrfs_root *extent_root, int all); |
51 | static struct btrfs_block_group_cache * | 51 | static struct btrfs_block_group_cache * |
52 | __btrfs_find_block_group(struct btrfs_root *root, | 52 | __btrfs_find_block_group(struct btrfs_root *root, |
53 | struct btrfs_block_group_cache *hint, | 53 | struct btrfs_block_group_cache *hint, |
@@ -711,8 +711,8 @@ static int __btrfs_update_extent_ref(struct btrfs_trans_handle *trans, | |||
711 | parent, ref_root, ref_generation, | 711 | parent, ref_root, ref_generation, |
712 | owner_objectid); | 712 | owner_objectid); |
713 | BUG_ON(ret); | 713 | BUG_ON(ret); |
714 | finish_current_insert(trans, extent_root); | 714 | finish_current_insert(trans, extent_root, 0); |
715 | del_pending_extents(trans, extent_root); | 715 | del_pending_extents(trans, extent_root, 0); |
716 | out: | 716 | out: |
717 | btrfs_free_path(path); | 717 | btrfs_free_path(path); |
718 | return ret; | 718 | return ret; |
@@ -784,8 +784,8 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
784 | ref_root, ref_generation, | 784 | ref_root, ref_generation, |
785 | owner_objectid); | 785 | owner_objectid); |
786 | BUG_ON(ret); | 786 | BUG_ON(ret); |
787 | finish_current_insert(trans, root->fs_info->extent_root); | 787 | finish_current_insert(trans, root->fs_info->extent_root, 0); |
788 | del_pending_extents(trans, root->fs_info->extent_root); | 788 | del_pending_extents(trans, root->fs_info->extent_root, 0); |
789 | 789 | ||
790 | btrfs_free_path(path); | 790 | btrfs_free_path(path); |
791 | return 0; | 791 | return 0; |
@@ -810,8 +810,8 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
810 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | 810 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, |
811 | struct btrfs_root *root) | 811 | struct btrfs_root *root) |
812 | { | 812 | { |
813 | finish_current_insert(trans, root->fs_info->extent_root); | 813 | finish_current_insert(trans, root->fs_info->extent_root, 1); |
814 | del_pending_extents(trans, root->fs_info->extent_root); | 814 | del_pending_extents(trans, root->fs_info->extent_root, 1); |
815 | return 0; | 815 | return 0; |
816 | } | 816 | } |
817 | 817 | ||
@@ -1292,8 +1292,8 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, | |||
1292 | btrfs_mark_buffer_dirty(leaf); | 1292 | btrfs_mark_buffer_dirty(leaf); |
1293 | btrfs_release_path(extent_root, path); | 1293 | btrfs_release_path(extent_root, path); |
1294 | fail: | 1294 | fail: |
1295 | finish_current_insert(trans, extent_root); | 1295 | finish_current_insert(trans, extent_root, 0); |
1296 | pending_ret = del_pending_extents(trans, extent_root); | 1296 | pending_ret = del_pending_extents(trans, extent_root, 0); |
1297 | if (ret) | 1297 | if (ret) |
1298 | return ret; | 1298 | return ret; |
1299 | if (pending_ret) | 1299 | if (pending_ret) |
@@ -1690,7 +1690,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, | |||
1690 | } | 1690 | } |
1691 | 1691 | ||
1692 | static int finish_current_insert(struct btrfs_trans_handle *trans, | 1692 | static int finish_current_insert(struct btrfs_trans_handle *trans, |
1693 | struct btrfs_root *extent_root) | 1693 | struct btrfs_root *extent_root, int all) |
1694 | { | 1694 | { |
1695 | u64 start; | 1695 | u64 start; |
1696 | u64 end; | 1696 | u64 end; |
@@ -1714,7 +1714,7 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
1714 | &end, EXTENT_WRITEBACK); | 1714 | &end, EXTENT_WRITEBACK); |
1715 | if (ret) { | 1715 | if (ret) { |
1716 | mutex_unlock(&info->extent_ins_mutex); | 1716 | mutex_unlock(&info->extent_ins_mutex); |
1717 | if (search) { | 1717 | if (search && all) { |
1718 | search = 0; | 1718 | search = 0; |
1719 | continue; | 1719 | continue; |
1720 | } | 1720 | } |
@@ -1723,7 +1723,7 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
1723 | 1723 | ||
1724 | ret = try_lock_extent(&info->extent_ins, start, end, GFP_NOFS); | 1724 | ret = try_lock_extent(&info->extent_ins, start, end, GFP_NOFS); |
1725 | if (!ret) { | 1725 | if (!ret) { |
1726 | search = end+1; | 1726 | search = end + 1; |
1727 | mutex_unlock(&info->extent_ins_mutex); | 1727 | mutex_unlock(&info->extent_ins_mutex); |
1728 | cond_resched(); | 1728 | cond_resched(); |
1729 | continue; | 1729 | continue; |
@@ -1785,7 +1785,10 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
1785 | } | 1785 | } |
1786 | kfree(extent_op); | 1786 | kfree(extent_op); |
1787 | unlock_extent(&info->extent_ins, start, end, GFP_NOFS); | 1787 | unlock_extent(&info->extent_ins, start, end, GFP_NOFS); |
1788 | search = 0; | 1788 | if (all) |
1789 | search = 0; | ||
1790 | else | ||
1791 | search = end + 1; | ||
1789 | 1792 | ||
1790 | cond_resched(); | 1793 | cond_resched(); |
1791 | } | 1794 | } |
@@ -1992,7 +1995,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, | |||
1992 | #endif | 1995 | #endif |
1993 | } | 1996 | } |
1994 | btrfs_free_path(path); | 1997 | btrfs_free_path(path); |
1995 | finish_current_insert(trans, extent_root); | 1998 | finish_current_insert(trans, extent_root, 0); |
1996 | return ret; | 1999 | return ret; |
1997 | } | 2000 | } |
1998 | 2001 | ||
@@ -2001,7 +2004,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, | |||
2001 | * them from the extent map | 2004 | * them from the extent map |
2002 | */ | 2005 | */ |
2003 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct | 2006 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct |
2004 | btrfs_root *extent_root) | 2007 | btrfs_root *extent_root, int all) |
2005 | { | 2008 | { |
2006 | int ret; | 2009 | int ret; |
2007 | int err = 0; | 2010 | int err = 0; |
@@ -2023,7 +2026,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct | |||
2023 | EXTENT_WRITEBACK); | 2026 | EXTENT_WRITEBACK); |
2024 | if (ret) { | 2027 | if (ret) { |
2025 | mutex_unlock(&info->extent_ins_mutex); | 2028 | mutex_unlock(&info->extent_ins_mutex); |
2026 | if (search) { | 2029 | if (all && search) { |
2027 | search = 0; | 2030 | search = 0; |
2028 | continue; | 2031 | continue; |
2029 | } | 2032 | } |
@@ -2088,7 +2091,10 @@ free_extent: | |||
2088 | err = ret; | 2091 | err = ret; |
2089 | unlock_extent(extent_ins, start, end, GFP_NOFS); | 2092 | unlock_extent(extent_ins, start, end, GFP_NOFS); |
2090 | 2093 | ||
2091 | search = 0; | 2094 | if (all) |
2095 | search = 0; | ||
2096 | else | ||
2097 | search = end + 1; | ||
2092 | cond_resched(); | 2098 | cond_resched(); |
2093 | } | 2099 | } |
2094 | return err; | 2100 | return err; |
@@ -2155,8 +2161,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
2155 | root_objectid, ref_generation, | 2161 | root_objectid, ref_generation, |
2156 | owner_objectid, pin, pin == 0); | 2162 | owner_objectid, pin, pin == 0); |
2157 | 2163 | ||
2158 | finish_current_insert(trans, root->fs_info->extent_root); | 2164 | finish_current_insert(trans, root->fs_info->extent_root, 0); |
2159 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root); | 2165 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root, 0); |
2160 | return ret ? ret : pending_ret; | 2166 | return ret ? ret : pending_ret; |
2161 | } | 2167 | } |
2162 | 2168 | ||
@@ -2580,8 +2586,8 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2580 | trans->alloc_exclude_start = 0; | 2586 | trans->alloc_exclude_start = 0; |
2581 | trans->alloc_exclude_nr = 0; | 2587 | trans->alloc_exclude_nr = 0; |
2582 | btrfs_free_path(path); | 2588 | btrfs_free_path(path); |
2583 | finish_current_insert(trans, extent_root); | 2589 | finish_current_insert(trans, extent_root, 0); |
2584 | pending_ret = del_pending_extents(trans, extent_root); | 2590 | pending_ret = del_pending_extents(trans, extent_root, 0); |
2585 | 2591 | ||
2586 | if (ret) | 2592 | if (ret) |
2587 | goto out; | 2593 | goto out; |
@@ -5229,8 +5235,8 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
5229 | sizeof(cache->item)); | 5235 | sizeof(cache->item)); |
5230 | BUG_ON(ret); | 5236 | BUG_ON(ret); |
5231 | 5237 | ||
5232 | finish_current_insert(trans, extent_root); | 5238 | finish_current_insert(trans, extent_root, 0); |
5233 | ret = del_pending_extents(trans, extent_root); | 5239 | ret = del_pending_extents(trans, extent_root, 0); |
5234 | BUG_ON(ret); | 5240 | BUG_ON(ret); |
5235 | set_avail_alloc_bits(extent_root->fs_info, type); | 5241 | set_avail_alloc_bits(extent_root->fs_info, type); |
5236 | 5242 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 924af6f2aeac..968b84f17a19 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -430,7 +430,10 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
430 | u64 old_root_bytenr; | 430 | u64 old_root_bytenr; |
431 | struct btrfs_root *tree_root = root->fs_info->tree_root; | 431 | struct btrfs_root *tree_root = root->fs_info->tree_root; |
432 | 432 | ||
433 | btrfs_extent_post_op(trans, root); | ||
433 | btrfs_write_dirty_block_groups(trans, root); | 434 | btrfs_write_dirty_block_groups(trans, root); |
435 | btrfs_extent_post_op(trans, root); | ||
436 | |||
434 | while(1) { | 437 | while(1) { |
435 | old_root_bytenr = btrfs_root_bytenr(&root->root_item); | 438 | old_root_bytenr = btrfs_root_bytenr(&root->root_item); |
436 | if (old_root_bytenr == root->node->start) | 439 | if (old_root_bytenr == root->node->start) |
@@ -440,11 +443,15 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
440 | btrfs_set_root_level(&root->root_item, | 443 | btrfs_set_root_level(&root->root_item, |
441 | btrfs_header_level(root->node)); | 444 | btrfs_header_level(root->node)); |
442 | btrfs_set_root_generation(&root->root_item, trans->transid); | 445 | btrfs_set_root_generation(&root->root_item, trans->transid); |
446 | |||
447 | btrfs_extent_post_op(trans, root); | ||
448 | |||
443 | ret = btrfs_update_root(trans, tree_root, | 449 | ret = btrfs_update_root(trans, tree_root, |
444 | &root->root_key, | 450 | &root->root_key, |
445 | &root->root_item); | 451 | &root->root_item); |
446 | BUG_ON(ret); | 452 | BUG_ON(ret); |
447 | btrfs_write_dirty_block_groups(trans, root); | 453 | btrfs_write_dirty_block_groups(trans, root); |
454 | btrfs_extent_post_op(trans, root); | ||
448 | } | 455 | } |
449 | return 0; | 456 | return 0; |
450 | } | 457 | } |
@@ -459,15 +466,20 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, | |||
459 | struct list_head *next; | 466 | struct list_head *next; |
460 | struct extent_buffer *eb; | 467 | struct extent_buffer *eb; |
461 | 468 | ||
469 | btrfs_extent_post_op(trans, fs_info->tree_root); | ||
470 | |||
462 | eb = btrfs_lock_root_node(fs_info->tree_root); | 471 | eb = btrfs_lock_root_node(fs_info->tree_root); |
463 | btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb, 0); | 472 | btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb, 0); |
464 | btrfs_tree_unlock(eb); | 473 | btrfs_tree_unlock(eb); |
465 | free_extent_buffer(eb); | 474 | free_extent_buffer(eb); |
466 | 475 | ||
476 | btrfs_extent_post_op(trans, fs_info->tree_root); | ||
477 | |||
467 | while(!list_empty(&fs_info->dirty_cowonly_roots)) { | 478 | while(!list_empty(&fs_info->dirty_cowonly_roots)) { |
468 | next = fs_info->dirty_cowonly_roots.next; | 479 | next = fs_info->dirty_cowonly_roots.next; |
469 | list_del_init(next); | 480 | list_del_init(next); |
470 | root = list_entry(next, struct btrfs_root, dirty_list); | 481 | root = list_entry(next, struct btrfs_root, dirty_list); |
482 | |||
471 | update_cowonly_root(trans, root); | 483 | update_cowonly_root(trans, root); |
472 | } | 484 | } |
473 | return 0; | 485 | return 0; |