nuke fs wide allocation mutex
PATCH 1/1 nuke fs wide allocation mutex
Hello,
This patch removes the giant fs_info->alloc_mutex and replaces it with a bunch of little locks. There is now a pinned_mutex, which is used when messing with the pinned_extents extent io tree, and the extent_ins_mutex which is used with the pending_del and extent_ins extent io trees. The locking for the extent tree stuff was inspired by a patch that Yan Zheng wrote to fix a race condition, I cleaned it up some and changed the locking around a little bit, but the idea remains the same. Basically instead of holding the extent_ins_mutex throughout the processing of an extent on the extent_ins or pending_del trees, we just hold it while we're searching and when we clear the bits on those trees, and lock the extent for the duration of the operations on the extent. Also to keep from getting hung up waiting to lock an extent, I've added a try_lock_extent so if we cannot lock the extent, move on to the next one in the tree and we'll come back to that one. I have tested this heavily and it does not appear to break anything. This has to be applied on top of my find_free_extent redo patch. Thank you,
fs/btrfs/ctree.c +2 -2
@@ -1390,8 +1390,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root lowest_level = p->lowest_level;WARN_ON (lowest_level && ins_len >0 );WARN_ON (p->nodes[0 ] !=NULL ); -WARN_ON (cow && root == root->fs_info->extent_root && - !mutex_is_locked (&root->fs_info->alloc_mutex)); +if (ins_len <0 ) lowest_unlock =2 ;
@@ -2051,6 +2050,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans,if (c == root->node) {/* trying to split the root, lets make a new one */ ret =insert_new_root (trans, root, path, level +1 ); +printk (KERN_ERR "splitting the root, %llu\n" , c->start);if (ret)return ret; }else {
fs/btrfs/ctree.h +7 -0
@@ -516,12 +516,14 @@ struct btrfs_free_space {struct rb_node offset_index;u64 offset;u64 bytes; +unsigned long ip; };struct btrfs_block_group_cache {struct btrfs_key key;struct btrfs_block_group_item item;spinlock_t lock; +struct mutex alloc_mutex;u64 pinned;u64 reserved;u64 flags;
@@ -600,6 +602,7 @@ struct btrfs_fs_info {struct mutex transaction_kthread_mutex;struct mutex cleaner_mutex;struct mutex alloc_mutex; +struct mutex extent_io_mutex;struct mutex chunk_mutex;struct mutex drop_mutex;struct mutex volume_mutex;
@@ -1879,8 +1882,12 @@ int btrfs_acl_chmod(struct inode *inode);/* free-space-cache.c */ int btrfs_add_free_space (struct btrfs_block_group_cache *block_group,u64 bytenr,u64 size); +int btrfs_add_free_space_lock (struct btrfs_block_group_cache *block_group, +u64 offset,u64 bytes);int btrfs_remove_free_space (struct btrfs_block_group_cache *block_group,u64 bytenr,u64 size); +int btrfs_remove_free_space_lock (struct btrfs_block_group_cache *block_group, +u64 offset,u64 bytes);void btrfs_remove_free_space_cache (struct btrfs_block_group_cache *block_group); struct btrfs_free_space *btrfs_find_free_space(struct btrfs_block_group_cache
fs/btrfs/disk-io.c +1 -0
@@ -1458,6 +1458,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,mutex_init (&fs_info->tree_log_mutex);mutex_init (&fs_info->drop_mutex);mutex_init (&fs_info->alloc_mutex); +mutex_init (&fs_info->extent_io_mutex);mutex_init (&fs_info->chunk_mutex);mutex_init (&fs_info->transaction_kthread_mutex);mutex_init (&fs_info->cleaner_mutex);
fs/btrfs/extent-tree.c +178 -74
714 lines not on this page · raw message
fs/btrfs/free-space-cache.c +68 -26
175 lines not on this page · raw message
fs/btrfs/tree-log.c +2 -0
@@ -272,8 +272,10 @@ static int process_one_buffer(struct btrfs_root *log, {if (wc->pin) {mutex_lock (&log->fs_info->alloc_mutex); +mutex_lock (&log->fs_info->extent_io_mutex);btrfs_update_pinned_extents (log->fs_info->extent_root, eb->start, eb->len,1 ); +mutex_unlock (&log->fs_info->extent_io_mutex);mutex_unlock (&log->fs_info->alloc_mutex); }