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
commit925baeddc5b0764a53f2214a1253251bab0e0324 (patch)
tree0e069bf9cc1c4ecd17c812fd1fb81bf807909ee6 /fs/btrfs/transaction.c
parent1cc127b5d1b71453091859301de4a7dd6ee96fa8 (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.c15
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
27static int total_trans = 0; 28static int total_trans = 0;
28extern struct kmem_cache *btrfs_trans_handle_cachep; 29extern 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;