summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason2008-06-25 22:01:30 +0200
committerChris Mason2008-09-25 17:04:03 +0200
commit925baeddc5b0764a53f2214a1253251bab0e0324 (patch)
tree0e069bf9cc1c4ecd17c812fd1fb81bf807909ee6 /fs/btrfs/inode.c
parentBtrfs: Add a thread pool just for submit_bio (diff)
downloadkernel-qcow2-linux-925baeddc5b0764a53f2214a1253251bab0e0324.tar.gz
kernel-qcow2-linux-925baeddc5b0764a53f2214a1253251bab0e0324.tar.xz
kernel-qcow2-linux-925baeddc5b0764a53f2214a1253251bab0e0324.zip
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/inode.c')
-rw-r--r--fs/btrfs/inode.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 0c79346fd2c9..61bd8953a683 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -115,6 +115,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
trans = btrfs_start_transaction(root, 1);
BUG_ON(!trans);
btrfs_set_trans_block_group(trans, inode);
+ mutex_unlock(&root->fs_info->fs_mutex);
num_bytes = (end - start + blocksize) & ~(blocksize - 1);
num_bytes = max(blocksize, num_bytes);
@@ -159,6 +160,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
btrfs_add_ordered_inode(inode);
btrfs_update_inode(trans, root, inode);
out:
+ mutex_lock(&root->fs_info->fs_mutex);
btrfs_end_transaction(trans, root);
return ret;
}
@@ -349,10 +351,12 @@ int __btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
mutex_lock(&root->fs_info->fs_mutex);
trans = btrfs_start_transaction(root, 1);
+ mutex_unlock(&root->fs_info->fs_mutex);
btrfs_set_trans_block_group(trans, inode);
btrfs_csum_file_blocks(trans, root, inode, bio, sums);
+ mutex_lock(&root->fs_info->fs_mutex);
ret = btrfs_end_transaction(trans, root);
BUG_ON(ret);
mutex_unlock(&root->fs_info->fs_mutex);
@@ -807,6 +811,7 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans,
goto err;
}
ret = btrfs_delete_one_dir_name(trans, root, path, di);
+ btrfs_release_path(root, path);
dentry->d_inode->i_ctime = dir->i_ctime;
ret = btrfs_del_inode_ref(trans, root, name, name_len,
@@ -881,8 +886,9 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
struct btrfs_trans_handle *trans;
unsigned long nr = 0;
- if (inode->i_size > BTRFS_EMPTY_DIR_SIZE)
+ if (inode->i_size > BTRFS_EMPTY_DIR_SIZE) {
return -ENOTEMPTY;
+ }
mutex_lock(&root->fs_info->fs_mutex);
ret = btrfs_check_free_space(root, 1, 1);