diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
| -rw-r--r-- | fs/btrfs/transaction.c | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 2dbf1c1f56ee..e51d2bc532f8 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 | */ |
| @@ -444,9 +452,6 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
| 444 | 452 | ||
| 445 | btrfs_write_dirty_block_groups(trans, root); | 453 | btrfs_write_dirty_block_groups(trans, root); |
| 446 | 454 | ||
| 447 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | ||
| 448 | BUG_ON(ret); | ||
| 449 | |||
| 450 | while (1) { | 455 | while (1) { |
| 451 | old_root_bytenr = btrfs_root_bytenr(&root->root_item); | 456 | old_root_bytenr = btrfs_root_bytenr(&root->root_item); |
| 452 | if (old_root_bytenr == root->node->start) | 457 | if (old_root_bytenr == root->node->start) |
| @@ -457,13 +462,11 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
| 457 | &root->root_key, | 462 | &root->root_key, |
| 458 | &root->root_item); | 463 | &root->root_item); |
| 459 | BUG_ON(ret); | 464 | BUG_ON(ret); |
| 460 | btrfs_write_dirty_block_groups(trans, root); | ||
| 461 | 465 | ||
| 462 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | 466 | ret = btrfs_write_dirty_block_groups(trans, root); |
| 463 | BUG_ON(ret); | 467 | BUG_ON(ret); |
| 464 | } | 468 | } |
| 465 | free_extent_buffer(root->commit_root); | 469 | switch_commit_root(root); |
| 466 | root->commit_root = btrfs_root_node(root); | ||
| 467 | return 0; | 470 | return 0; |
| 468 | } | 471 | } |
| 469 | 472 | ||
| @@ -495,9 +498,6 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
| 495 | root = list_entry(next, struct btrfs_root, dirty_list); | 498 | root = list_entry(next, struct btrfs_root, dirty_list); |
| 496 | 499 | ||
| 497 | update_cowonly_root(trans, root); | 500 | update_cowonly_root(trans, root); |
| 498 | |||
| 499 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | ||
| 500 | BUG_ON(ret); | ||
| 501 | } | 501 | } |
| 502 | return 0; | 502 | return 0; |
| 503 | } | 503 | } |
| @@ -544,8 +544,7 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans, | |||
| 544 | btrfs_update_reloc_root(trans, root); | 544 | btrfs_update_reloc_root(trans, root); |
| 545 | 545 | ||
| 546 | if (root->commit_root != root->node) { | 546 | if (root->commit_root != root->node) { |
| 547 | free_extent_buffer(root->commit_root); | 547 | switch_commit_root(root); |
| 548 | root->commit_root = btrfs_root_node(root); | ||
| 549 | btrfs_set_root_node(&root->root_item, | 548 | btrfs_set_root_node(&root->root_item, |
| 550 | root->node); | 549 | root->node); |
| 551 | } | 550 | } |
| @@ -943,9 +942,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 943 | 942 | ||
| 944 | mutex_unlock(&root->fs_info->trans_mutex); | 943 | mutex_unlock(&root->fs_info->trans_mutex); |
| 945 | 944 | ||
| 946 | if (flush_on_commit || snap_pending) { | 945 | if (flush_on_commit) { |
| 947 | if (flush_on_commit) | 946 | btrfs_start_delalloc_inodes(root); |
| 948 | btrfs_start_delalloc_inodes(root); | 947 | ret = btrfs_wait_ordered_extents(root, 0); |
| 948 | BUG_ON(ret); | ||
| 949 | } else if (snap_pending) { | ||
| 949 | ret = btrfs_wait_ordered_extents(root, 1); | 950 | ret = btrfs_wait_ordered_extents(root, 1); |
| 950 | BUG_ON(ret); | 951 | BUG_ON(ret); |
| 951 | } | 952 | } |
| @@ -1009,15 +1010,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1009 | 1010 | ||
| 1010 | btrfs_set_root_node(&root->fs_info->tree_root->root_item, | 1011 | btrfs_set_root_node(&root->fs_info->tree_root->root_item, |
| 1011 | root->fs_info->tree_root->node); | 1012 | root->fs_info->tree_root->node); |
| 1012 | free_extent_buffer(root->fs_info->tree_root->commit_root); | 1013 | switch_commit_root(root->fs_info->tree_root); |
| 1013 | root->fs_info->tree_root->commit_root = | ||
| 1014 | btrfs_root_node(root->fs_info->tree_root); | ||
| 1015 | 1014 | ||
| 1016 | btrfs_set_root_node(&root->fs_info->chunk_root->root_item, | 1015 | btrfs_set_root_node(&root->fs_info->chunk_root->root_item, |
| 1017 | root->fs_info->chunk_root->node); | 1016 | root->fs_info->chunk_root->node); |
| 1018 | free_extent_buffer(root->fs_info->chunk_root->commit_root); | 1017 | switch_commit_root(root->fs_info->chunk_root); |
| 1019 | root->fs_info->chunk_root->commit_root = | ||
| 1020 | btrfs_root_node(root->fs_info->chunk_root); | ||
| 1021 | 1018 | ||
| 1022 | update_super_roots(root); | 1019 | update_super_roots(root); |
| 1023 | 1020 | ||
| @@ -1057,6 +1054,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1057 | cur_trans->commit_done = 1; | 1054 | cur_trans->commit_done = 1; |
| 1058 | 1055 | ||
| 1059 | root->fs_info->last_trans_committed = cur_trans->transid; | 1056 | root->fs_info->last_trans_committed = cur_trans->transid; |
| 1057 | |||
| 1060 | wake_up(&cur_trans->commit_wait); | 1058 | wake_up(&cur_trans->commit_wait); |
| 1061 | 1059 | ||
| 1062 | put_transaction(cur_trans); | 1060 | put_transaction(cur_trans); |
