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>
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index dcea9d7..50891b3 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -330,8 +330,13 @@
struct btrfs_path {
struct extent_buffer *nodes[BTRFS_MAX_LEVEL];
int slots[BTRFS_MAX_LEVEL];
+ /* if there is real range locking, this locks field will change */
+ int locks[BTRFS_MAX_LEVEL];
int reada;
+ /* keep some upper locks as we walk down */
+ int keep_locks;
int lowest_level;
+ int skip_locking;
};
/*
@@ -515,6 +520,8 @@
spinlock_t hash_lock;
struct mutex trans_mutex;
struct mutex fs_mutex;
+ struct mutex alloc_mutex;
+ struct mutex chunk_mutex;
struct list_head trans_list;
struct list_head hashers;
struct list_head dead_roots;
@@ -576,6 +583,10 @@
*/
struct btrfs_root {
struct extent_buffer *node;
+
+ /* the node lock is held while changing the node pointer */
+ spinlock_t node_lock;
+
struct extent_buffer *commit_root;
struct btrfs_root_item root_item;
struct btrfs_key root_key;
@@ -1353,13 +1364,7 @@
struct btrfs_block_group_cache
*hint, u64 search_start,
int data, int owner);
-int btrfs_inc_root_ref(struct btrfs_trans_handle *trans,
- struct btrfs_root *root, u64 owner_objectid);
struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
- struct btrfs_root *root, u32 size,
- u64 root_objectid,
- u64 hint, u64 empty_size);
-struct extent_buffer *__btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
u32 blocksize,
u64 root_objectid,
@@ -1368,8 +1373,6 @@
int level,
u64 hint,
u64 empty_size);
-int btrfs_grow_extent_tree(struct btrfs_trans_handle *trans,
- struct btrfs_root *root, u64 new_size);
int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size);
int btrfs_insert_extent_backref(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
@@ -1409,6 +1412,10 @@
int btrfs_previous_item(struct btrfs_root *root,
struct btrfs_path *path, u64 min_objectid,
int type);
+
+struct extent_buffer *btrfs_root_node(struct btrfs_root *root);
+struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root);
+
int btrfs_cow_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct extent_buffer *buf,
struct extent_buffer *parent, int parent_slot,