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.c40
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
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 */
@@ -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);