aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-06-25 16:01:30 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:03 -0400
commita213501153fd66e2359e091b1612841305ba6551 (patch)
tree1f4c316c9d3cad0eb6d9be14cb0e67e46e815dce /fs/btrfs/transaction.c
parent925baeddc5b0764a53f2214a1253251bab0e0324 (diff)
Btrfs: Replace the big fs_mutex with a collection of other locks
Extent alloctions are still protected by a large alloc_mutex. Objectid allocations are covered by a objectid mutex Other btree operations are protected by a lock on individual btree nodes Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c42
1 files changed, 16 insertions, 26 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 1ed433a71493..5a1ee0665ae8 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -370,6 +370,7 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
370 struct btrfs_trans_handle *trans; 370 struct btrfs_trans_handle *trans;
371 unsigned long nr; 371 unsigned long nr;
372 372
373 smp_mb();
373 if (root->defrag_running) 374 if (root->defrag_running)
374 return 0; 375 return 0;
375 trans = btrfs_start_transaction(root, 1); 376 trans = btrfs_start_transaction(root, 1);
@@ -378,16 +379,15 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
378 ret = btrfs_defrag_leaves(trans, root, cacheonly); 379 ret = btrfs_defrag_leaves(trans, root, cacheonly);
379 nr = trans->blocks_used; 380 nr = trans->blocks_used;
380 btrfs_end_transaction(trans, root); 381 btrfs_end_transaction(trans, root);
381 mutex_unlock(&info->fs_mutex);
382 btrfs_btree_balance_dirty(info->tree_root, nr); 382 btrfs_btree_balance_dirty(info->tree_root, nr);
383 cond_resched(); 383 cond_resched();
384 384
385 mutex_lock(&info->fs_mutex);
386 trans = btrfs_start_transaction(root, 1); 385 trans = btrfs_start_transaction(root, 1);
387 if (ret != -EAGAIN) 386 if (ret != -EAGAIN)
388 break; 387 break;
389 } 388 }
390 root->defrag_running = 0; 389 root->defrag_running = 0;
390 smp_mb();
391 radix_tree_tag_clear(&info->fs_roots_radix, 391 radix_tree_tag_clear(&info->fs_roots_radix,
392 (unsigned long)root->root_key.objectid, 392 (unsigned long)root->root_key.objectid,
393 BTRFS_ROOT_DEFRAG_TAG); 393 BTRFS_ROOT_DEFRAG_TAG);
@@ -435,14 +435,14 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root,
435 while(!list_empty(list)) { 435 while(!list_empty(list)) {
436 struct btrfs_root *root; 436 struct btrfs_root *root;
437 437
438 mutex_lock(&tree_root->fs_info->fs_mutex);
439 dirty = list_entry(list->next, struct dirty_root, list); 438 dirty = list_entry(list->next, struct dirty_root, list);
440 list_del_init(&dirty->list); 439 list_del_init(&dirty->list);
441 440
442 num_bytes = btrfs_root_used(&dirty->root->root_item); 441 num_bytes = btrfs_root_used(&dirty->root->root_item);
443 root = dirty->latest_root; 442 root = dirty->latest_root;
444 root->fs_info->throttles++; 443 atomic_inc(&root->fs_info->throttles);
445 444
445 mutex_lock(&root->fs_info->drop_mutex);
446 while(1) { 446 while(1) {
447 trans = btrfs_start_transaction(tree_root, 1); 447 trans = btrfs_start_transaction(tree_root, 1);
448 ret = btrfs_drop_snapshot(trans, dirty->root); 448 ret = btrfs_drop_snapshot(trans, dirty->root);
@@ -459,14 +459,16 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root,
459 nr = trans->blocks_used; 459 nr = trans->blocks_used;
460 ret = btrfs_end_transaction(trans, tree_root); 460 ret = btrfs_end_transaction(trans, tree_root);
461 BUG_ON(ret); 461 BUG_ON(ret);
462 mutex_unlock(&tree_root->fs_info->fs_mutex); 462
463 mutex_unlock(&root->fs_info->drop_mutex);
463 btrfs_btree_balance_dirty(tree_root, nr); 464 btrfs_btree_balance_dirty(tree_root, nr);
464 cond_resched(); 465 cond_resched();
465 mutex_lock(&tree_root->fs_info->fs_mutex); 466 mutex_lock(&root->fs_info->drop_mutex);
466 } 467 }
467 BUG_ON(ret); 468 BUG_ON(ret);
468 root->fs_info->throttles--; 469 atomic_dec(&root->fs_info->throttles);
469 470
471 mutex_lock(&root->fs_info->alloc_mutex);
470 num_bytes -= btrfs_root_used(&dirty->root->root_item); 472 num_bytes -= btrfs_root_used(&dirty->root->root_item);
471 bytes_used = btrfs_root_used(&root->root_item); 473 bytes_used = btrfs_root_used(&root->root_item);
472 if (num_bytes) { 474 if (num_bytes) {
@@ -474,11 +476,15 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root,
474 btrfs_set_root_used(&root->root_item, 476 btrfs_set_root_used(&root->root_item,
475 bytes_used - num_bytes); 477 bytes_used - num_bytes);
476 } 478 }
479 mutex_unlock(&root->fs_info->alloc_mutex);
480
477 ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key); 481 ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key);
478 if (ret) { 482 if (ret) {
479 BUG(); 483 BUG();
480 break; 484 break;
481 } 485 }
486 mutex_unlock(&root->fs_info->drop_mutex);
487
482 nr = trans->blocks_used; 488 nr = trans->blocks_used;
483 ret = btrfs_end_transaction(trans, tree_root); 489 ret = btrfs_end_transaction(trans, tree_root);
484 BUG_ON(ret); 490 BUG_ON(ret);
@@ -486,7 +492,6 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root,
486 free_extent_buffer(dirty->root->node); 492 free_extent_buffer(dirty->root->node);
487 kfree(dirty->root); 493 kfree(dirty->root);
488 kfree(dirty); 494 kfree(dirty);
489 mutex_unlock(&tree_root->fs_info->fs_mutex);
490 495
491 btrfs_btree_balance_dirty(tree_root, nr); 496 btrfs_btree_balance_dirty(tree_root, nr);
492 cond_resched(); 497 cond_resched();
@@ -503,7 +508,7 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans,
503 u64 objectid = 0; 508 u64 objectid = 0;
504 int ret; 509 int ret;
505 510
506 root->fs_info->throttles++; 511 atomic_inc(&root->fs_info->throttles);
507 while(1) { 512 while(1) {
508 ret = btrfs_find_first_ordered_inode( 513 ret = btrfs_find_first_ordered_inode(
509 &cur_trans->ordered_inode_tree, 514 &cur_trans->ordered_inode_tree,
@@ -512,7 +517,6 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans,
512 break; 517 break;
513 518
514 mutex_unlock(&root->fs_info->trans_mutex); 519 mutex_unlock(&root->fs_info->trans_mutex);
515 mutex_unlock(&root->fs_info->fs_mutex);
516 520
517 if (S_ISREG(inode->i_mode)) { 521 if (S_ISREG(inode->i_mode)) {
518 atomic_inc(&BTRFS_I(inode)->ordered_writeback); 522 atomic_inc(&BTRFS_I(inode)->ordered_writeback);
@@ -521,7 +525,6 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans,
521 } 525 }
522 iput(inode); 526 iput(inode);
523 527
524 mutex_lock(&root->fs_info->fs_mutex);
525 mutex_lock(&root->fs_info->trans_mutex); 528 mutex_lock(&root->fs_info->trans_mutex);
526 } 529 }
527 while(1) { 530 while(1) {
@@ -533,7 +536,6 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans,
533 if (!ret) 536 if (!ret)
534 break; 537 break;
535 mutex_unlock(&root->fs_info->trans_mutex); 538 mutex_unlock(&root->fs_info->trans_mutex);
536 mutex_unlock(&root->fs_info->fs_mutex);
537 539
538 if (S_ISREG(inode->i_mode)) { 540 if (S_ISREG(inode->i_mode)) {
539 atomic_inc(&BTRFS_I(inode)->ordered_writeback); 541 atomic_inc(&BTRFS_I(inode)->ordered_writeback);
@@ -543,10 +545,9 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans,
543 atomic_dec(&inode->i_count); 545 atomic_dec(&inode->i_count);
544 iput(inode); 546 iput(inode);
545 547
546 mutex_lock(&root->fs_info->fs_mutex);
547 mutex_lock(&root->fs_info->trans_mutex); 548 mutex_lock(&root->fs_info->trans_mutex);
548 } 549 }
549 root->fs_info->throttles--; 550 atomic_dec(&root->fs_info->throttles);
550 return 0; 551 return 0;
551} 552}
552 553
@@ -661,7 +662,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
661 mutex_unlock(&root->fs_info->trans_mutex); 662 mutex_unlock(&root->fs_info->trans_mutex);
662 btrfs_end_transaction(trans, root); 663 btrfs_end_transaction(trans, root);
663 664
664 mutex_unlock(&root->fs_info->fs_mutex);
665 ret = wait_for_commit(root, cur_trans); 665 ret = wait_for_commit(root, cur_trans);
666 BUG_ON(ret); 666 BUG_ON(ret);
667 667
@@ -669,7 +669,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
669 put_transaction(cur_trans); 669 put_transaction(cur_trans);
670 mutex_unlock(&root->fs_info->trans_mutex); 670 mutex_unlock(&root->fs_info->trans_mutex);
671 671
672 mutex_lock(&root->fs_info->fs_mutex);
673 return 0; 672 return 0;
674 } 673 }
675 674
@@ -687,12 +686,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
687 struct btrfs_transaction, list); 686 struct btrfs_transaction, list);
688 if (!prev_trans->commit_done) { 687 if (!prev_trans->commit_done) {
689 prev_trans->use_count++; 688 prev_trans->use_count++;
690 mutex_unlock(&root->fs_info->fs_mutex);
691 mutex_unlock(&root->fs_info->trans_mutex); 689 mutex_unlock(&root->fs_info->trans_mutex);
692 690
693 wait_for_commit(root, prev_trans); 691 wait_for_commit(root, prev_trans);
694 692
695 mutex_lock(&root->fs_info->fs_mutex);
696 mutex_lock(&root->fs_info->trans_mutex); 693 mutex_lock(&root->fs_info->trans_mutex);
697 put_transaction(prev_trans); 694 put_transaction(prev_trans);
698 } 695 }
@@ -709,12 +706,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
709 else 706 else
710 timeout = 1; 707 timeout = 1;
711 708
712 mutex_unlock(&root->fs_info->fs_mutex);
713 mutex_unlock(&root->fs_info->trans_mutex); 709 mutex_unlock(&root->fs_info->trans_mutex);
714 710
715 schedule_timeout(timeout); 711 schedule_timeout(timeout);
716 712
717 mutex_lock(&root->fs_info->fs_mutex);
718 mutex_lock(&root->fs_info->trans_mutex); 713 mutex_lock(&root->fs_info->trans_mutex);
719 finish_wait(&cur_trans->writer_wait, &wait); 714 finish_wait(&cur_trans->writer_wait, &wait);
720 ret = btrfs_write_ordered_inodes(trans, root); 715 ret = btrfs_write_ordered_inodes(trans, root);
@@ -755,12 +750,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
755 btrfs_copy_pinned(root, pinned_copy); 750 btrfs_copy_pinned(root, pinned_copy);
756 751
757 mutex_unlock(&root->fs_info->trans_mutex); 752 mutex_unlock(&root->fs_info->trans_mutex);
758 mutex_unlock(&root->fs_info->fs_mutex);
759 ret = btrfs_write_and_wait_transaction(trans, root); 753 ret = btrfs_write_and_wait_transaction(trans, root);
760 BUG_ON(ret); 754 BUG_ON(ret);
761 write_ctree_super(trans, root); 755 write_ctree_super(trans, root);
762 756
763 mutex_lock(&root->fs_info->fs_mutex);
764 btrfs_finish_extent_commit(trans, root, pinned_copy); 757 btrfs_finish_extent_commit(trans, root, pinned_copy);
765 mutex_lock(&root->fs_info->trans_mutex); 758 mutex_lock(&root->fs_info->trans_mutex);
766 759
@@ -781,9 +774,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
781 kmem_cache_free(btrfs_trans_handle_cachep, trans); 774 kmem_cache_free(btrfs_trans_handle_cachep, trans);
782 775
783 if (root->fs_info->closing) { 776 if (root->fs_info->closing) {
784 mutex_unlock(&root->fs_info->fs_mutex);
785 drop_dirty_roots(root->fs_info->tree_root, &dirty_fs_roots); 777 drop_dirty_roots(root->fs_info->tree_root, &dirty_fs_roots);
786 mutex_lock(&root->fs_info->fs_mutex);
787 } 778 }
788 return ret; 779 return ret;
789} 780}
@@ -823,7 +814,7 @@ void btrfs_transaction_cleaner(struct work_struct *work)
823 unsigned long delay = HZ * 30; 814 unsigned long delay = HZ * 30;
824 int ret; 815 int ret;
825 816
826 mutex_lock(&root->fs_info->fs_mutex); 817 smp_mb();
827 if (root->fs_info->closing) 818 if (root->fs_info->closing)
828 goto out; 819 goto out;
829 820
@@ -844,7 +835,6 @@ void btrfs_transaction_cleaner(struct work_struct *work)
844 trans = btrfs_start_transaction(root, 1); 835 trans = btrfs_start_transaction(root, 1);
845 ret = btrfs_commit_transaction(trans, root); 836 ret = btrfs_commit_transaction(trans, root);
846out: 837out:
847 mutex_unlock(&root->fs_info->fs_mutex);
848 btrfs_clean_old_snapshots(root); 838 btrfs_clean_old_snapshots(root);
849 btrfs_transaction_queue_work(root, delay); 839 btrfs_transaction_queue_work(root, delay);
850} 840}