diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 23 |
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 | ||
43 | static 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); |