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/disk-io.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/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 13 |
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 |
37 | static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf) | 38 | static 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, |