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.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 81f7124c3051..32454d1c566f 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -40,6 +40,14 @@ static noinline void put_transaction(struct btrfs_transaction *transaction)
40 } 40 }
41} 41}
42 42
43static noinline void switch_commit_root(struct btrfs_root *root)
44{
45 down_write(&root->commit_root_sem);
46 free_extent_buffer(root->commit_root);
47 root->commit_root = btrfs_root_node(root);
48 up_write(&root->commit_root_sem);
49}
50
43/* 51/*
44 * either allocate a new transaction or hop into the existing one 52 * either allocate a new transaction or hop into the existing one
45 */ 53 */
@@ -458,8 +466,7 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
458 ret = btrfs_write_dirty_block_groups(trans, root); 466 ret = btrfs_write_dirty_block_groups(trans, root);
459 BUG_ON(ret); 467 BUG_ON(ret);
460 } 468 }
461 free_extent_buffer(root->commit_root); 469 switch_commit_root(root);
462 root->commit_root = btrfs_root_node(root);
463 return 0; 470 return 0;
464} 471}
465 472
@@ -537,8 +544,7 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans,
537 btrfs_update_reloc_root(trans, root); 544 btrfs_update_reloc_root(trans, root);
538 545
539 if (root->commit_root != root->node) { 546 if (root->commit_root != root->node) {
540 free_extent_buffer(root->commit_root); 547 switch_commit_root(root);
541 root->commit_root = btrfs_root_node(root);
542 btrfs_set_root_node(&root->root_item, 548 btrfs_set_root_node(&root->root_item,
543 root->node); 549 root->node);
544 } 550 }
@@ -1002,15 +1008,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1002 1008
1003 btrfs_set_root_node(&root->fs_info->tree_root->root_item, 1009 btrfs_set_root_node(&root->fs_info->tree_root->root_item,
1004 root->fs_info->tree_root->node); 1010 root->fs_info->tree_root->node);
1005 free_extent_buffer(root->fs_info->tree_root->commit_root); 1011 switch_commit_root(root->fs_info->tree_root);
1006 root->fs_info->tree_root->commit_root =
1007 btrfs_root_node(root->fs_info->tree_root);
1008 1012
1009 btrfs_set_root_node(&root->fs_info->chunk_root->root_item, 1013 btrfs_set_root_node(&root->fs_info->chunk_root->root_item,
1010 root->fs_info->chunk_root->node); 1014 root->fs_info->chunk_root->node);
1011 free_extent_buffer(root->fs_info->chunk_root->commit_root); 1015 switch_commit_root(root->fs_info->chunk_root);
1012 root->fs_info->chunk_root->commit_root =
1013 btrfs_root_node(root->fs_info->chunk_root);
1014 1016
1015 update_super_roots(root); 1017 update_super_roots(root);
1016 1018
@@ -1050,6 +1052,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1050 cur_trans->commit_done = 1; 1052 cur_trans->commit_done = 1;
1051 1053
1052 root->fs_info->last_trans_committed = cur_trans->transid; 1054 root->fs_info->last_trans_committed = cur_trans->transid;
1055
1053 wake_up(&cur_trans->commit_wait); 1056 wake_up(&cur_trans->commit_wait);
1054 1057
1055 put_transaction(cur_trans); 1058 put_transaction(cur_trans);