Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable

* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable:
Btrfs: be more polite in the async caching threads
Btrfs: preserve commit_root for async caching

+28 -12
+1 -3
fs/btrfs/ctree.h
··· 825 825 struct mutex drop_mutex; 826 826 struct mutex volume_mutex; 827 827 struct mutex tree_reloc_mutex; 828 + struct rw_semaphore extent_commit_sem; 828 829 829 830 /* 830 831 * this protects the ordered operations list only while we are ··· 959 958 960 959 /* the node lock is held while changing the node pointer */ 961 960 spinlock_t node_lock; 962 - 963 - /* taken when updating the commit root */ 964 - struct rw_semaphore commit_root_sem; 965 961 966 962 struct extent_buffer *commit_root; 967 963 struct btrfs_root *log_root;
+1 -1
fs/btrfs/disk-io.c
··· 909 909 spin_lock_init(&root->inode_lock); 910 910 mutex_init(&root->objectid_mutex); 911 911 mutex_init(&root->log_mutex); 912 - init_rwsem(&root->commit_root_sem); 913 912 init_waitqueue_head(&root->log_writer_wait); 914 913 init_waitqueue_head(&root->log_commit_wait[0]); 915 914 init_waitqueue_head(&root->log_commit_wait[1]); ··· 1639 1640 mutex_init(&fs_info->cleaner_mutex); 1640 1641 mutex_init(&fs_info->volume_mutex); 1641 1642 mutex_init(&fs_info->tree_reloc_mutex); 1643 + init_rwsem(&fs_info->extent_commit_sem); 1642 1644 1643 1645 btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); 1644 1646 btrfs_init_free_cluster(&fs_info->data_alloc_cluster);
+6 -5
fs/btrfs/extent-tree.c
··· 267 267 last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET); 268 268 again: 269 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 273 * We don't want to deadlock with somebody trying to allocate a new ··· 302 302 else if (ret) 303 303 break; 304 304 305 - if (need_resched()) { 305 + if (need_resched() || 306 + btrfs_transaction_in_commit(fs_info)) { 306 307 btrfs_release_path(fs_info->extent_root, path); 307 - up_read(&fs_info->extent_root->commit_root_sem); 308 - cond_resched(); 308 + up_read(&fs_info->extent_commit_sem); 309 + schedule_timeout(1); 309 310 goto again; 310 311 } 311 312 ··· 346 345 347 346 err: 348 347 btrfs_free_path(path); 349 - up_read(&fs_info->extent_root->commit_root_sem); 348 + up_read(&fs_info->extent_commit_sem); 350 349 atomic_dec(&block_group->space_info->caching_threads); 351 350 wake_up(&block_group->caching_q); 352 351
+19 -3
fs/btrfs/transaction.c
··· 42 42 43 43 static noinline void switch_commit_root(struct btrfs_root *root) 44 44 { 45 - down_write(&root->commit_root_sem); 46 45 free_extent_buffer(root->commit_root); 47 46 root->commit_root = btrfs_root_node(root); 48 - up_write(&root->commit_root_sem); 49 47 } 50 48 51 49 /* ··· 464 466 ret = btrfs_write_dirty_block_groups(trans, root); 465 467 BUG_ON(ret); 466 468 } 467 - switch_commit_root(root); 469 + 470 + if (root != root->fs_info->extent_root) 471 + switch_commit_root(root); 472 + 468 473 return 0; 469 474 } 470 475 ··· 500 499 501 500 update_cowonly_root(trans, root); 502 501 } 502 + 503 + down_write(&fs_info->extent_commit_sem); 504 + switch_commit_root(fs_info->extent_root); 505 + up_write(&fs_info->extent_commit_sem); 506 + 503 507 return 0; 504 508 } 505 509 ··· 855 849 super->root = root_item->bytenr; 856 850 super->generation = root_item->generation; 857 851 super->root_level = root_item->level; 852 + } 853 + 854 + int btrfs_transaction_in_commit(struct btrfs_fs_info *info) 855 + { 856 + int ret = 0; 857 + spin_lock(&info->new_trans_lock); 858 + if (info->running_transaction) 859 + ret = info->running_transaction->in_commit; 860 + spin_unlock(&info->new_trans_lock); 861 + return ret; 858 862 } 859 863 860 864 int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
+1
fs/btrfs/transaction.h
··· 107 107 struct btrfs_root *root); 108 108 int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, 109 109 struct extent_io_tree *dirty_pages); 110 + int btrfs_transaction_in_commit(struct btrfs_fs_info *info); 110 111 #endif