aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.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/disk-io.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/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index e5c758e306d5..fe40bdd984ff 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -32,6 +32,7 @@
32#include "volumes.h" 32#include "volumes.h"
33#include "print-tree.h" 33#include "print-tree.h"
34#include "async-thread.h" 34#include "async-thread.h"
35#include "locking.h"
35 36
36#if 0 37#if 0
37static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf) 38static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf)
@@ -681,9 +682,11 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
681{ 682{
682 struct inode *btree_inode = root->fs_info->btree_inode; 683 struct inode *btree_inode = root->fs_info->btree_inode;
683 if (btrfs_header_generation(buf) == 684 if (btrfs_header_generation(buf) ==
684 root->fs_info->running_transaction->transid) 685 root->fs_info->running_transaction->transid) {
686 WARN_ON(!btrfs_tree_locked(buf));
685 clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, 687 clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree,
686 buf); 688 buf);
689 }
687 return 0; 690 return 0;
688} 691}
689 692
@@ -720,6 +723,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
720 root->in_sysfs = 0; 723 root->in_sysfs = 0;
721 724
722 INIT_LIST_HEAD(&root->dirty_list); 725 INIT_LIST_HEAD(&root->dirty_list);
726 spin_lock_init(&root->node_lock);
723 memset(&root->root_key, 0, sizeof(root->root_key)); 727 memset(&root->root_key, 0, sizeof(root->root_key));
724 memset(&root->root_item, 0, sizeof(root->root_item)); 728 memset(&root->root_item, 0, sizeof(root->root_item));
725 memset(&root->defrag_progress, 0, sizeof(root->defrag_progress)); 729 memset(&root->defrag_progress, 0, sizeof(root->defrag_progress));
@@ -1196,6 +1200,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1196 1200
1197 mutex_init(&fs_info->trans_mutex); 1201 mutex_init(&fs_info->trans_mutex);
1198 mutex_init(&fs_info->fs_mutex); 1202 mutex_init(&fs_info->fs_mutex);
1203 mutex_init(&fs_info->alloc_mutex);
1204 mutex_init(&fs_info->chunk_mutex);
1199 1205
1200#if 0 1206#if 0
1201 ret = add_hasher(fs_info, "crc32c"); 1207 ret = add_hasher(fs_info, "crc32c");
@@ -1274,7 +1280,9 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1274 1280
1275 mutex_lock(&fs_info->fs_mutex); 1281 mutex_lock(&fs_info->fs_mutex);
1276 1282
1283 mutex_lock(&fs_info->chunk_mutex);
1277 ret = btrfs_read_sys_array(tree_root); 1284 ret = btrfs_read_sys_array(tree_root);
1285 mutex_unlock(&fs_info->chunk_mutex);
1278 if (ret) { 1286 if (ret) {
1279 printk("btrfs: failed to read the system array on %s\n", 1287 printk("btrfs: failed to read the system array on %s\n",
1280 sb->s_id); 1288 sb->s_id);
@@ -1296,7 +1304,9 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1296 (unsigned long)btrfs_header_chunk_tree_uuid(chunk_root->node), 1304 (unsigned long)btrfs_header_chunk_tree_uuid(chunk_root->node),
1297 BTRFS_UUID_SIZE); 1305 BTRFS_UUID_SIZE);
1298 1306
1307 mutex_lock(&fs_info->chunk_mutex);
1299 ret = btrfs_read_chunk_tree(chunk_root); 1308 ret = btrfs_read_chunk_tree(chunk_root);
1309 mutex_unlock(&fs_info->chunk_mutex);
1300 BUG_ON(ret); 1310 BUG_ON(ret);
1301 1311
1302 btrfs_close_extra_devices(fs_devices); 1312 btrfs_close_extra_devices(fs_devices);
@@ -1654,6 +1664,7 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
1654 u64 transid = btrfs_header_generation(buf); 1664 u64 transid = btrfs_header_generation(buf);
1655 struct inode *btree_inode = root->fs_info->btree_inode; 1665 struct inode *btree_inode = root->fs_info->btree_inode;
1656 1666
1667 WARN_ON(!btrfs_tree_locked(buf));
1657 if (transid != root->fs_info->generation) { 1668 if (transid != root->fs_info->generation) {
1658 printk(KERN_CRIT "transid mismatch buffer %llu, found %Lu running %Lu\n", 1669 printk(KERN_CRIT "transid mismatch buffer %llu, found %Lu running %Lu\n",
1659 (unsigned long long)buf->start, 1670 (unsigned long long)buf->start,