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.c54
1 files changed, 47 insertions, 7 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index d638c54d39e9..f94c2ad8996c 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -65,6 +65,12 @@ static noinline int join_transaction(struct btrfs_root *root)
65 cur_trans->use_count = 1; 65 cur_trans->use_count = 1;
66 cur_trans->commit_done = 0; 66 cur_trans->commit_done = 0;
67 cur_trans->start_time = get_seconds(); 67 cur_trans->start_time = get_seconds();
68
69 cur_trans->delayed_refs.root.rb_node = NULL;
70 cur_trans->delayed_refs.num_entries = 0;
71 cur_trans->delayed_refs.flushing = 0;
72 spin_lock_init(&cur_trans->delayed_refs.lock);
73
68 INIT_LIST_HEAD(&cur_trans->pending_snapshots); 74 INIT_LIST_HEAD(&cur_trans->pending_snapshots);
69 list_add_tail(&cur_trans->list, &root->fs_info->trans_list); 75 list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
70 extent_io_tree_init(&cur_trans->dirty_pages, 76 extent_io_tree_init(&cur_trans->dirty_pages,
@@ -182,6 +188,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
182 h->block_group = 0; 188 h->block_group = 0;
183 h->alloc_exclude_nr = 0; 189 h->alloc_exclude_nr = 0;
184 h->alloc_exclude_start = 0; 190 h->alloc_exclude_start = 0;
191 h->delayed_ref_updates = 0;
185 root->fs_info->running_transaction->use_count++; 192 root->fs_info->running_transaction->use_count++;
186 mutex_unlock(&root->fs_info->trans_mutex); 193 mutex_unlock(&root->fs_info->trans_mutex);
187 return h; 194 return h;
@@ -281,6 +288,14 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
281 struct btrfs_transaction *cur_trans; 288 struct btrfs_transaction *cur_trans;
282 struct btrfs_fs_info *info = root->fs_info; 289 struct btrfs_fs_info *info = root->fs_info;
283 290
291 if (trans->delayed_ref_updates &&
292 (trans->transaction->delayed_refs.flushing ||
293 trans->transaction->delayed_refs.num_entries > 16384)) {
294 btrfs_run_delayed_refs(trans, root, trans->delayed_ref_updates);
295 } else if (trans->transaction->delayed_refs.num_entries > 64) {
296 wake_up_process(root->fs_info->transaction_kthread);
297 }
298
284 mutex_lock(&info->trans_mutex); 299 mutex_lock(&info->trans_mutex);
285 cur_trans = info->running_transaction; 300 cur_trans = info->running_transaction;
286 WARN_ON(cur_trans != trans->transaction); 301 WARN_ON(cur_trans != trans->transaction);
@@ -424,9 +439,10 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
424 u64 old_root_bytenr; 439 u64 old_root_bytenr;
425 struct btrfs_root *tree_root = root->fs_info->tree_root; 440 struct btrfs_root *tree_root = root->fs_info->tree_root;
426 441
427 btrfs_extent_post_op(trans, root);
428 btrfs_write_dirty_block_groups(trans, root); 442 btrfs_write_dirty_block_groups(trans, root);
429 btrfs_extent_post_op(trans, root); 443
444 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
445 BUG_ON(ret);
430 446
431 while (1) { 447 while (1) {
432 old_root_bytenr = btrfs_root_bytenr(&root->root_item); 448 old_root_bytenr = btrfs_root_bytenr(&root->root_item);
@@ -438,14 +454,14 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
438 btrfs_header_level(root->node)); 454 btrfs_header_level(root->node));
439 btrfs_set_root_generation(&root->root_item, trans->transid); 455 btrfs_set_root_generation(&root->root_item, trans->transid);
440 456
441 btrfs_extent_post_op(trans, root);
442
443 ret = btrfs_update_root(trans, tree_root, 457 ret = btrfs_update_root(trans, tree_root,
444 &root->root_key, 458 &root->root_key,
445 &root->root_item); 459 &root->root_item);
446 BUG_ON(ret); 460 BUG_ON(ret);
447 btrfs_write_dirty_block_groups(trans, root); 461 btrfs_write_dirty_block_groups(trans, root);
448 btrfs_extent_post_op(trans, root); 462
463 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
464 BUG_ON(ret);
449 } 465 }
450 return 0; 466 return 0;
451} 467}
@@ -459,15 +475,18 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
459 struct btrfs_fs_info *fs_info = root->fs_info; 475 struct btrfs_fs_info *fs_info = root->fs_info;
460 struct list_head *next; 476 struct list_head *next;
461 struct extent_buffer *eb; 477 struct extent_buffer *eb;
478 int ret;
462 479
463 btrfs_extent_post_op(trans, fs_info->tree_root); 480 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
481 BUG_ON(ret);
464 482
465 eb = btrfs_lock_root_node(fs_info->tree_root); 483 eb = btrfs_lock_root_node(fs_info->tree_root);
466 btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb); 484 btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb);
467 btrfs_tree_unlock(eb); 485 btrfs_tree_unlock(eb);
468 free_extent_buffer(eb); 486 free_extent_buffer(eb);
469 487
470 btrfs_extent_post_op(trans, fs_info->tree_root); 488 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
489 BUG_ON(ret);
471 490
472 while (!list_empty(&fs_info->dirty_cowonly_roots)) { 491 while (!list_empty(&fs_info->dirty_cowonly_roots)) {
473 next = fs_info->dirty_cowonly_roots.next; 492 next = fs_info->dirty_cowonly_roots.next;
@@ -475,6 +494,9 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
475 root = list_entry(next, struct btrfs_root, dirty_list); 494 root = list_entry(next, struct btrfs_root, dirty_list);
476 495
477 update_cowonly_root(trans, root); 496 update_cowonly_root(trans, root);
497
498 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
499 BUG_ON(ret);
478 } 500 }
479 return 0; 501 return 0;
480} 502}
@@ -895,6 +917,21 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
895 DEFINE_WAIT(wait); 917 DEFINE_WAIT(wait);
896 int ret; 918 int ret;
897 919
920 /* make a pass through all the delayed refs we have so far
921 * any runnings procs may add more while we are here
922 */
923 ret = btrfs_run_delayed_refs(trans, root, 0);
924 BUG_ON(ret);
925
926 /*
927 * set the flushing flag so procs in this transaction have to
928 * start sending their work down.
929 */
930 trans->transaction->delayed_refs.flushing = 1;
931
932 ret = btrfs_run_delayed_refs(trans, root, (u64)-1);
933 BUG_ON(ret);
934
898 INIT_LIST_HEAD(&dirty_fs_roots); 935 INIT_LIST_HEAD(&dirty_fs_roots);
899 mutex_lock(&root->fs_info->trans_mutex); 936 mutex_lock(&root->fs_info->trans_mutex);
900 if (trans->transaction->in_commit) { 937 if (trans->transaction->in_commit) {
@@ -969,6 +1006,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
969 ret = create_pending_snapshots(trans, root->fs_info); 1006 ret = create_pending_snapshots(trans, root->fs_info);
970 BUG_ON(ret); 1007 BUG_ON(ret);
971 1008
1009 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
1010 BUG_ON(ret);
1011
972 WARN_ON(cur_trans != trans->transaction); 1012 WARN_ON(cur_trans != trans->transaction);
973 1013
974 /* btrfs_commit_tree_roots is responsible for getting the 1014 /* btrfs_commit_tree_roots is responsible for getting the