diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 4 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 2 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 6 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 12 |
4 files changed, 14 insertions, 10 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 17ad92c29cfd..38eeb6c49c8a 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -827,6 +827,7 @@ struct btrfs_fs_info { | |||
827 | struct mutex drop_mutex; | 827 | struct mutex drop_mutex; |
828 | struct mutex volume_mutex; | 828 | struct mutex volume_mutex; |
829 | struct mutex tree_reloc_mutex; | 829 | struct mutex tree_reloc_mutex; |
830 | struct rw_semaphore extent_commit_sem; | ||
830 | 831 | ||
831 | /* | 832 | /* |
832 | * this protects the ordered operations list only while we are | 833 | * this protects the ordered operations list only while we are |
@@ -961,9 +962,6 @@ struct btrfs_root { | |||
961 | /* the node lock is held while changing the node pointer */ | 962 | /* the node lock is held while changing the node pointer */ |
962 | spinlock_t node_lock; | 963 | spinlock_t node_lock; |
963 | 964 | ||
964 | /* taken when updating the commit root */ | ||
965 | struct rw_semaphore commit_root_sem; | ||
966 | |||
967 | struct extent_buffer *commit_root; | 965 | struct extent_buffer *commit_root; |
968 | struct btrfs_root *log_root; | 966 | struct btrfs_root *log_root; |
969 | struct btrfs_root *reloc_root; | 967 | struct btrfs_root *reloc_root; |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 3a9b88759880..3cf4cfa575c8 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -907,7 +907,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
907 | spin_lock_init(&root->inode_lock); | 907 | spin_lock_init(&root->inode_lock); |
908 | mutex_init(&root->objectid_mutex); | 908 | mutex_init(&root->objectid_mutex); |
909 | mutex_init(&root->log_mutex); | 909 | mutex_init(&root->log_mutex); |
910 | init_rwsem(&root->commit_root_sem); | ||
911 | init_waitqueue_head(&root->log_writer_wait); | 910 | init_waitqueue_head(&root->log_writer_wait); |
912 | init_waitqueue_head(&root->log_commit_wait[0]); | 911 | init_waitqueue_head(&root->log_commit_wait[0]); |
913 | init_waitqueue_head(&root->log_commit_wait[1]); | 912 | init_waitqueue_head(&root->log_commit_wait[1]); |
@@ -1624,6 +1623,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1624 | mutex_init(&fs_info->cleaner_mutex); | 1623 | mutex_init(&fs_info->cleaner_mutex); |
1625 | mutex_init(&fs_info->volume_mutex); | 1624 | mutex_init(&fs_info->volume_mutex); |
1626 | mutex_init(&fs_info->tree_reloc_mutex); | 1625 | mutex_init(&fs_info->tree_reloc_mutex); |
1626 | init_rwsem(&fs_info->extent_commit_sem); | ||
1627 | 1627 | ||
1628 | btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); | 1628 | btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); |
1629 | btrfs_init_free_cluster(&fs_info->data_alloc_cluster); | 1629 | btrfs_init_free_cluster(&fs_info->data_alloc_cluster); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index fadf69a2764b..2fe21fa74913 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -267,7 +267,7 @@ static int caching_kthread(void *data) | |||
267 | last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET); | 267 | last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET); |
268 | again: | 268 | again: |
269 | /* need to make sure the commit_root doesn't disappear */ | 269 | /* need to make sure the commit_root doesn't disappear */ |
270 | down_read(&fs_info->extent_root->commit_root_sem); | 270 | down_read(&fs_info->extent_commit_sem); |
271 | 271 | ||
272 | /* | 272 | /* |
273 | * We don't want to deadlock with somebody trying to allocate a new | 273 | * We don't want to deadlock with somebody trying to allocate a new |
@@ -304,7 +304,7 @@ again: | |||
304 | 304 | ||
305 | if (need_resched()) { | 305 | if (need_resched()) { |
306 | btrfs_release_path(fs_info->extent_root, path); | 306 | btrfs_release_path(fs_info->extent_root, path); |
307 | up_read(&fs_info->extent_root->commit_root_sem); | 307 | up_read(&fs_info->extent_commit_sem); |
308 | cond_resched(); | 308 | cond_resched(); |
309 | goto again; | 309 | goto again; |
310 | } | 310 | } |
@@ -345,7 +345,7 @@ next: | |||
345 | 345 | ||
346 | err: | 346 | err: |
347 | btrfs_free_path(path); | 347 | btrfs_free_path(path); |
348 | up_read(&fs_info->extent_root->commit_root_sem); | 348 | up_read(&fs_info->extent_commit_sem); |
349 | atomic_dec(&block_group->space_info->caching_threads); | 349 | atomic_dec(&block_group->space_info->caching_threads); |
350 | wake_up(&block_group->caching_q); | 350 | wake_up(&block_group->caching_q); |
351 | 351 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index e51d2bc532f8..de48e4ec808c 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -42,10 +42,8 @@ static noinline void put_transaction(struct btrfs_transaction *transaction) | |||
42 | 42 | ||
43 | static noinline void switch_commit_root(struct btrfs_root *root) | 43 | static noinline void switch_commit_root(struct btrfs_root *root) |
44 | { | 44 | { |
45 | down_write(&root->commit_root_sem); | ||
46 | free_extent_buffer(root->commit_root); | 45 | free_extent_buffer(root->commit_root); |
47 | root->commit_root = btrfs_root_node(root); | 46 | root->commit_root = btrfs_root_node(root); |
48 | up_write(&root->commit_root_sem); | ||
49 | } | 47 | } |
50 | 48 | ||
51 | /* | 49 | /* |
@@ -466,7 +464,10 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
466 | ret = btrfs_write_dirty_block_groups(trans, root); | 464 | ret = btrfs_write_dirty_block_groups(trans, root); |
467 | BUG_ON(ret); | 465 | BUG_ON(ret); |
468 | } | 466 | } |
469 | switch_commit_root(root); | 467 | |
468 | if (root != root->fs_info->extent_root) | ||
469 | switch_commit_root(root); | ||
470 | |||
470 | return 0; | 471 | return 0; |
471 | } | 472 | } |
472 | 473 | ||
@@ -499,6 +500,11 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
499 | 500 | ||
500 | update_cowonly_root(trans, root); | 501 | update_cowonly_root(trans, root); |
501 | } | 502 | } |
503 | |||
504 | down_write(&fs_info->extent_commit_sem); | ||
505 | switch_commit_root(fs_info->extent_root); | ||
506 | up_write(&fs_info->extent_commit_sem); | ||
507 | |||
502 | return 0; | 508 | return 0; |
503 | } | 509 | } |
504 | 510 | ||