diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-06-25 16:01:30 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:03 -0400 |
commit | 925baeddc5b0764a53f2214a1253251bab0e0324 (patch) | |
tree | 0e069bf9cc1c4ecd17c812fd1fb81bf807909ee6 /fs/btrfs/transaction.c | |
parent | 1cc127b5d1b71453091859301de4a7dd6ee96fa8 (diff) |
Btrfs: Start btree concurrency work.
The allocation trees and the chunk trees are serialized via their own
dedicated mutexes. This means allocation location is still not very
fine grained.
The main FS btree is protected by locks on each block in the btree. Locks
are taken top / down, and as processing finishes on a given level of the
tree, the lock is released after locking the lower level.
The end result of a search is now a path where only the lowest level
is locked. Releasing or freeing the path drops any locks held.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index f04684f7fea3..1ed433a71493 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "ctree.h" | 23 | #include "ctree.h" |
24 | #include "disk-io.h" | 24 | #include "disk-io.h" |
25 | #include "transaction.h" | 25 | #include "transaction.h" |
26 | #include "locking.h" | ||
26 | 27 | ||
27 | static int total_trans = 0; | 28 | static int total_trans = 0; |
28 | extern struct kmem_cache *btrfs_trans_handle_cachep; | 29 | extern struct kmem_cache *btrfs_trans_handle_cachep; |
@@ -96,8 +97,7 @@ static noinline int record_root_in_trans(struct btrfs_root *root) | |||
96 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, | 97 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, |
97 | (unsigned long)root->root_key.objectid, | 98 | (unsigned long)root->root_key.objectid, |
98 | BTRFS_ROOT_DEFRAG_TAG); | 99 | BTRFS_ROOT_DEFRAG_TAG); |
99 | root->commit_root = root->node; | 100 | root->commit_root = btrfs_root_node(root); |
100 | extent_buffer_get(root->node); | ||
101 | } else { | 101 | } else { |
102 | WARN_ON(1); | 102 | WARN_ON(1); |
103 | } | 103 | } |
@@ -559,6 +559,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
559 | struct btrfs_root *tree_root = fs_info->tree_root; | 559 | struct btrfs_root *tree_root = fs_info->tree_root; |
560 | struct btrfs_root *root = pending->root; | 560 | struct btrfs_root *root = pending->root; |
561 | struct extent_buffer *tmp; | 561 | struct extent_buffer *tmp; |
562 | struct extent_buffer *old; | ||
562 | int ret; | 563 | int ret; |
563 | int namelen; | 564 | int namelen; |
564 | u64 objectid; | 565 | u64 objectid; |
@@ -578,16 +579,18 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
578 | key.offset = 1; | 579 | key.offset = 1; |
579 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | 580 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); |
580 | 581 | ||
581 | extent_buffer_get(root->node); | 582 | old = btrfs_lock_root_node(root); |
582 | btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); | 583 | btrfs_cow_block(trans, root, old, NULL, 0, &old); |
583 | free_extent_buffer(tmp); | ||
584 | 584 | ||
585 | btrfs_copy_root(trans, root, root->node, &tmp, objectid); | 585 | btrfs_copy_root(trans, root, old, &tmp, objectid); |
586 | btrfs_tree_unlock(old); | ||
587 | free_extent_buffer(old); | ||
586 | 588 | ||
587 | btrfs_set_root_bytenr(new_root_item, tmp->start); | 589 | btrfs_set_root_bytenr(new_root_item, tmp->start); |
588 | btrfs_set_root_level(new_root_item, btrfs_header_level(tmp)); | 590 | btrfs_set_root_level(new_root_item, btrfs_header_level(tmp)); |
589 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | 591 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, |
590 | new_root_item); | 592 | new_root_item); |
593 | btrfs_tree_unlock(tmp); | ||
591 | free_extent_buffer(tmp); | 594 | free_extent_buffer(tmp); |
592 | if (ret) | 595 | if (ret) |
593 | goto fail; | 596 | goto fail; |