diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 34 |
1 files changed, 12 insertions, 22 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 543e5ee4033a..fcef3cae0c92 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -36,7 +36,6 @@ struct dirty_root { | |||
36 | struct list_head list; | 36 | struct list_head list; |
37 | struct btrfs_root *root; | 37 | struct btrfs_root *root; |
38 | struct btrfs_root *latest_root; | 38 | struct btrfs_root *latest_root; |
39 | struct btrfs_leaf_ref_tree ref_tree; | ||
40 | }; | 39 | }; |
41 | 40 | ||
42 | static noinline void put_transaction(struct btrfs_transaction *transaction) | 41 | static noinline void put_transaction(struct btrfs_transaction *transaction) |
@@ -108,13 +107,13 @@ static noinline int record_root_in_trans(struct btrfs_root *root) | |||
108 | 107 | ||
109 | dirty->latest_root = root; | 108 | dirty->latest_root = root; |
110 | INIT_LIST_HEAD(&dirty->list); | 109 | INIT_LIST_HEAD(&dirty->list); |
111 | btrfs_leaf_ref_tree_init(&dirty->ref_tree); | ||
112 | dirty->ref_tree.generation = running_trans_id; | ||
113 | 110 | ||
114 | root->commit_root = btrfs_root_node(root); | 111 | root->commit_root = btrfs_root_node(root); |
115 | root->ref_tree = &dirty->ref_tree; | 112 | root->dirty_root = dirty; |
116 | 113 | ||
117 | memcpy(dirty->root, root, sizeof(*root)); | 114 | memcpy(dirty->root, root, sizeof(*root)); |
115 | dirty->root->ref_tree = &root->ref_tree_struct; | ||
116 | |||
118 | spin_lock_init(&dirty->root->node_lock); | 117 | spin_lock_init(&dirty->root->node_lock); |
119 | mutex_init(&dirty->root->objectid_mutex); | 118 | mutex_init(&dirty->root->objectid_mutex); |
120 | dirty->root->node = root->commit_root; | 119 | dirty->root->node = root->commit_root; |
@@ -217,12 +216,13 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
217 | if (waitqueue_active(&cur_trans->writer_wait)) | 216 | if (waitqueue_active(&cur_trans->writer_wait)) |
218 | wake_up(&cur_trans->writer_wait); | 217 | wake_up(&cur_trans->writer_wait); |
219 | 218 | ||
220 | if (0 && cur_trans->in_commit && throttle) { | 219 | if (throttle && atomic_read(&root->fs_info->throttles)) { |
221 | DEFINE_WAIT(wait); | 220 | DEFINE_WAIT(wait); |
222 | mutex_unlock(&root->fs_info->trans_mutex); | 221 | mutex_unlock(&root->fs_info->trans_mutex); |
223 | prepare_to_wait(&root->fs_info->transaction_throttle, &wait, | 222 | prepare_to_wait(&root->fs_info->transaction_throttle, &wait, |
224 | TASK_UNINTERRUPTIBLE); | 223 | TASK_UNINTERRUPTIBLE); |
225 | schedule(); | 224 | if (atomic_read(&root->fs_info->throttles)) |
225 | schedule(); | ||
226 | finish_wait(&root->fs_info->transaction_throttle, &wait); | 226 | finish_wait(&root->fs_info->transaction_throttle, &wait); |
227 | mutex_lock(&root->fs_info->trans_mutex); | 227 | mutex_lock(&root->fs_info->trans_mutex); |
228 | } | 228 | } |
@@ -333,6 +333,8 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, | |||
333 | list_del_init(next); | 333 | list_del_init(next); |
334 | root = list_entry(next, struct btrfs_root, dirty_list); | 334 | root = list_entry(next, struct btrfs_root, dirty_list); |
335 | update_cowonly_root(trans, root); | 335 | update_cowonly_root(trans, root); |
336 | if (root->fs_info->closing) | ||
337 | btrfs_remove_leaf_refs(root); | ||
336 | } | 338 | } |
337 | return 0; | 339 | return 0; |
338 | } | 340 | } |
@@ -346,10 +348,8 @@ int btrfs_add_dead_root(struct btrfs_root *root, | |||
346 | dirty = kmalloc(sizeof(*dirty), GFP_NOFS); | 348 | dirty = kmalloc(sizeof(*dirty), GFP_NOFS); |
347 | if (!dirty) | 349 | if (!dirty) |
348 | return -ENOMEM; | 350 | return -ENOMEM; |
349 | btrfs_leaf_ref_tree_init(&dirty->ref_tree); | ||
350 | dirty->root = root; | 351 | dirty->root = root; |
351 | dirty->latest_root = latest; | 352 | dirty->latest_root = latest; |
352 | root->ref_tree = NULL; | ||
353 | list_add(&dirty->list, dead_list); | 353 | list_add(&dirty->list, dead_list); |
354 | return 0; | 354 | return 0; |
355 | } | 355 | } |
@@ -379,18 +379,14 @@ static noinline int add_dirty_roots(struct btrfs_trans_handle *trans, | |||
379 | BTRFS_ROOT_TRANS_TAG); | 379 | BTRFS_ROOT_TRANS_TAG); |
380 | 380 | ||
381 | BUG_ON(!root->ref_tree); | 381 | BUG_ON(!root->ref_tree); |
382 | dirty = container_of(root->ref_tree, struct dirty_root, | 382 | dirty = root->dirty_root; |
383 | ref_tree); | ||
384 | 383 | ||
385 | if (root->commit_root == root->node) { | 384 | if (root->commit_root == root->node) { |
386 | WARN_ON(root->node->start != | 385 | WARN_ON(root->node->start != |
387 | btrfs_root_bytenr(&root->root_item)); | 386 | btrfs_root_bytenr(&root->root_item)); |
388 | 387 | ||
389 | BUG_ON(!btrfs_leaf_ref_tree_empty( | ||
390 | root->ref_tree)); | ||
391 | free_extent_buffer(root->commit_root); | 388 | free_extent_buffer(root->commit_root); |
392 | root->commit_root = NULL; | 389 | root->commit_root = NULL; |
393 | root->ref_tree = NULL; | ||
394 | 390 | ||
395 | kfree(dirty->root); | 391 | kfree(dirty->root); |
396 | kfree(dirty); | 392 | kfree(dirty); |
@@ -410,7 +406,6 @@ static noinline int add_dirty_roots(struct btrfs_trans_handle *trans, | |||
410 | sizeof(struct btrfs_disk_key)); | 406 | sizeof(struct btrfs_disk_key)); |
411 | root->root_item.drop_level = 0; | 407 | root->root_item.drop_level = 0; |
412 | root->commit_root = NULL; | 408 | root->commit_root = NULL; |
413 | root->ref_tree = NULL; | ||
414 | root->root_key.offset = root->fs_info->generation; | 409 | root->root_key.offset = root->fs_info->generation; |
415 | btrfs_set_root_bytenr(&root->root_item, | 410 | btrfs_set_root_bytenr(&root->root_item, |
416 | root->node->start); | 411 | root->node->start); |
@@ -485,7 +480,7 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root, | |||
485 | while(!list_empty(list)) { | 480 | while(!list_empty(list)) { |
486 | struct btrfs_root *root; | 481 | struct btrfs_root *root; |
487 | 482 | ||
488 | dirty = list_entry(list->next, struct dirty_root, list); | 483 | dirty = list_entry(list->prev, struct dirty_root, list); |
489 | list_del_init(&dirty->list); | 484 | list_del_init(&dirty->list); |
490 | 485 | ||
491 | num_bytes = btrfs_root_used(&dirty->root->root_item); | 486 | num_bytes = btrfs_root_used(&dirty->root->root_item); |
@@ -507,7 +502,7 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root, | |||
507 | if (err) | 502 | if (err) |
508 | ret = err; | 503 | ret = err; |
509 | nr = trans->blocks_used; | 504 | nr = trans->blocks_used; |
510 | ret = btrfs_end_transaction_throttle(trans, tree_root); | 505 | ret = btrfs_end_transaction(trans, tree_root); |
511 | BUG_ON(ret); | 506 | BUG_ON(ret); |
512 | 507 | ||
513 | mutex_unlock(&root->fs_info->drop_mutex); | 508 | mutex_unlock(&root->fs_info->drop_mutex); |
@@ -517,6 +512,7 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root, | |||
517 | } | 512 | } |
518 | BUG_ON(ret); | 513 | BUG_ON(ret); |
519 | atomic_dec(&root->fs_info->throttles); | 514 | atomic_dec(&root->fs_info->throttles); |
515 | wake_up(&root->fs_info->transaction_throttle); | ||
520 | 516 | ||
521 | mutex_lock(&root->fs_info->alloc_mutex); | 517 | mutex_lock(&root->fs_info->alloc_mutex); |
522 | num_bytes -= btrfs_root_used(&dirty->root->root_item); | 518 | num_bytes -= btrfs_root_used(&dirty->root->root_item); |
@@ -539,8 +535,6 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root, | |||
539 | ret = btrfs_end_transaction(trans, tree_root); | 535 | ret = btrfs_end_transaction(trans, tree_root); |
540 | BUG_ON(ret); | 536 | BUG_ON(ret); |
541 | 537 | ||
542 | btrfs_remove_leaf_refs(dirty->root); | ||
543 | |||
544 | free_extent_buffer(dirty->root->node); | 538 | free_extent_buffer(dirty->root->node); |
545 | kfree(dirty->root); | 539 | kfree(dirty->root); |
546 | kfree(dirty); | 540 | kfree(dirty); |
@@ -725,10 +719,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
725 | &dirty_fs_roots); | 719 | &dirty_fs_roots); |
726 | BUG_ON(ret); | 720 | BUG_ON(ret); |
727 | 721 | ||
728 | spin_lock(&root->fs_info->ref_cache_lock); | ||
729 | root->fs_info->running_ref_cache_size = 0; | ||
730 | spin_unlock(&root->fs_info->ref_cache_lock); | ||
731 | |||
732 | ret = btrfs_commit_tree_roots(trans, root); | 722 | ret = btrfs_commit_tree_roots(trans, root); |
733 | BUG_ON(ret); | 723 | BUG_ON(ret); |
734 | 724 | ||