diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index e88b59d13439..7e80f32550a6 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -220,6 +220,7 @@ loop: | |||
220 | * commit the transaction. | 220 | * commit the transaction. |
221 | */ | 221 | */ |
222 | atomic_set(&cur_trans->use_count, 2); | 222 | atomic_set(&cur_trans->use_count, 2); |
223 | cur_trans->have_free_bgs = 0; | ||
223 | cur_trans->start_time = get_seconds(); | 224 | cur_trans->start_time = get_seconds(); |
224 | 225 | ||
225 | cur_trans->delayed_refs.href_root = RB_ROOT; | 226 | cur_trans->delayed_refs.href_root = RB_ROOT; |
@@ -248,6 +249,8 @@ loop: | |||
248 | INIT_LIST_HEAD(&cur_trans->pending_chunks); | 249 | INIT_LIST_HEAD(&cur_trans->pending_chunks); |
249 | INIT_LIST_HEAD(&cur_trans->switch_commits); | 250 | INIT_LIST_HEAD(&cur_trans->switch_commits); |
250 | INIT_LIST_HEAD(&cur_trans->pending_ordered); | 251 | INIT_LIST_HEAD(&cur_trans->pending_ordered); |
252 | INIT_LIST_HEAD(&cur_trans->dirty_bgs); | ||
253 | spin_lock_init(&cur_trans->dirty_bgs_lock); | ||
251 | list_add_tail(&cur_trans->list, &fs_info->trans_list); | 254 | list_add_tail(&cur_trans->list, &fs_info->trans_list); |
252 | extent_io_tree_init(&cur_trans->dirty_pages, | 255 | extent_io_tree_init(&cur_trans->dirty_pages, |
253 | fs_info->btree_inode->i_mapping); | 256 | fs_info->btree_inode->i_mapping); |
@@ -1020,6 +1023,7 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
1020 | u64 old_root_bytenr; | 1023 | u64 old_root_bytenr; |
1021 | u64 old_root_used; | 1024 | u64 old_root_used; |
1022 | struct btrfs_root *tree_root = root->fs_info->tree_root; | 1025 | struct btrfs_root *tree_root = root->fs_info->tree_root; |
1026 | bool extent_root = (root->objectid == BTRFS_EXTENT_TREE_OBJECTID); | ||
1023 | 1027 | ||
1024 | old_root_used = btrfs_root_used(&root->root_item); | 1028 | old_root_used = btrfs_root_used(&root->root_item); |
1025 | btrfs_write_dirty_block_groups(trans, root); | 1029 | btrfs_write_dirty_block_groups(trans, root); |
@@ -1027,7 +1031,9 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
1027 | while (1) { | 1031 | while (1) { |
1028 | old_root_bytenr = btrfs_root_bytenr(&root->root_item); | 1032 | old_root_bytenr = btrfs_root_bytenr(&root->root_item); |
1029 | if (old_root_bytenr == root->node->start && | 1033 | if (old_root_bytenr == root->node->start && |
1030 | old_root_used == btrfs_root_used(&root->root_item)) | 1034 | old_root_used == btrfs_root_used(&root->root_item) && |
1035 | (!extent_root || | ||
1036 | list_empty(&trans->transaction->dirty_bgs))) | ||
1031 | break; | 1037 | break; |
1032 | 1038 | ||
1033 | btrfs_set_root_node(&root->root_item, root->node); | 1039 | btrfs_set_root_node(&root->root_item, root->node); |
@@ -1038,7 +1044,15 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
1038 | return ret; | 1044 | return ret; |
1039 | 1045 | ||
1040 | old_root_used = btrfs_root_used(&root->root_item); | 1046 | old_root_used = btrfs_root_used(&root->root_item); |
1041 | ret = btrfs_write_dirty_block_groups(trans, root); | 1047 | if (extent_root) { |
1048 | ret = btrfs_write_dirty_block_groups(trans, root); | ||
1049 | if (ret) | ||
1050 | return ret; | ||
1051 | } | ||
1052 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | ||
1053 | if (ret) | ||
1054 | return ret; | ||
1055 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | ||
1042 | if (ret) | 1056 | if (ret) |
1043 | return ret; | 1057 | return ret; |
1044 | } | 1058 | } |
@@ -1061,10 +1075,6 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
1061 | struct extent_buffer *eb; | 1075 | struct extent_buffer *eb; |
1062 | int ret; | 1076 | int ret; |
1063 | 1077 | ||
1064 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | ||
1065 | if (ret) | ||
1066 | return ret; | ||
1067 | |||
1068 | eb = btrfs_lock_root_node(fs_info->tree_root); | 1078 | eb = btrfs_lock_root_node(fs_info->tree_root); |
1069 | ret = btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, | 1079 | ret = btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, |
1070 | 0, &eb); | 1080 | 0, &eb); |
@@ -1097,6 +1107,7 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
1097 | next = fs_info->dirty_cowonly_roots.next; | 1107 | next = fs_info->dirty_cowonly_roots.next; |
1098 | list_del_init(next); | 1108 | list_del_init(next); |
1099 | root = list_entry(next, struct btrfs_root, dirty_list); | 1109 | root = list_entry(next, struct btrfs_root, dirty_list); |
1110 | clear_bit(BTRFS_ROOT_DIRTY, &root->state); | ||
1100 | 1111 | ||
1101 | if (root != fs_info->extent_root) | 1112 | if (root != fs_info->extent_root) |
1102 | list_add_tail(&root->dirty_list, | 1113 | list_add_tail(&root->dirty_list, |
@@ -1983,6 +1994,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1983 | switch_commit_roots(cur_trans, root->fs_info); | 1994 | switch_commit_roots(cur_trans, root->fs_info); |
1984 | 1995 | ||
1985 | assert_qgroups_uptodate(trans); | 1996 | assert_qgroups_uptodate(trans); |
1997 | ASSERT(list_empty(&cur_trans->dirty_bgs)); | ||
1986 | update_super_roots(root); | 1998 | update_super_roots(root); |
1987 | 1999 | ||
1988 | btrfs_set_super_log_root(root->fs_info->super_copy, 0); | 2000 | btrfs_set_super_log_root(root->fs_info->super_copy, 0); |
@@ -2026,6 +2038,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
2026 | 2038 | ||
2027 | btrfs_finish_extent_commit(trans, root); | 2039 | btrfs_finish_extent_commit(trans, root); |
2028 | 2040 | ||
2041 | if (cur_trans->have_free_bgs) | ||
2042 | btrfs_clear_space_info_full(root->fs_info); | ||
2043 | |||
2029 | root->fs_info->last_trans_committed = cur_trans->transid; | 2044 | root->fs_info->last_trans_committed = cur_trans->transid; |
2030 | /* | 2045 | /* |
2031 | * We needn't acquire the lock here because there is no other task | 2046 | * We needn't acquire the lock here because there is no other task |