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.c27
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