From: Chris Mason Date: Fri, 18 Dec 2015 19:11:10 +0000 (-0800) Subject: Merge branch 'freespace-tree' into for-linus-4.5 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=f7d3d2f99eeaa9f5c111965b1516972f4fc5e449;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git Merge branch 'freespace-tree' into for-linus-4.5 Signed-off-by: Chris Mason --- f7d3d2f99eeaa9f5c111965b1516972f4fc5e449 diff --cc fs/btrfs/ctree.h index 35489e7129a7,ed610f9c04b2..cf87979a153e --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@@ -2182,8 -2206,7 +2243,9 @@@ struct btrfs_ioctl_defrag_range_args #define BTRFS_MOUNT_CHECK_INTEGRITY_INCLUDING_EXTENT_DATA (1 << 21) #define BTRFS_MOUNT_PANIC_ON_FATAL_ERROR (1 << 22) #define BTRFS_MOUNT_RESCAN_UUID_TREE (1 << 23) -#define BTRFS_MOUNT_FREE_SPACE_TREE (1 << 24) +#define BTRFS_MOUNT_FRAGMENT_DATA (1 << 24) +#define BTRFS_MOUNT_FRAGMENT_METADATA (1 << 25) ++#define BTRFS_MOUNT_FREE_SPACE_TREE (1 << 26) #define BTRFS_DEFAULT_COMMIT_INTERVAL (30) #define BTRFS_DEFAULT_MAX_INLINE (8192) diff --cc fs/btrfs/extent-tree.c index 4b89680a1923,a4a4f593ec71..8abb344e3dcb --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@@ -407,10 -387,8 +407,9 @@@ static int load_extent_tree_free(struc u64 total_found = 0; u64 last = 0; u32 nritems; - int ret = -ENOMEM; + int ret; + bool wakeup = true; - caching_ctl = container_of(work, struct btrfs_caching_control, work); block_group = caching_ctl->block_group; fs_info = block_group->fs_info; extent_root = fs_info->extent_root; @@@ -521,10 -486,9 +518,10 @@@ next else last = key.objectid + key.offset; - if (total_found > (1024 * 1024 * 2)) { + if (total_found > CACHING_CTL_WAKE_UP) { total_found = 0; - wake_up(&caching_ctl->wait); + if (wakeup) + wake_up(&caching_ctl->wait); } } path->slots[0]++; @@@ -534,41 -498,41 +531,58 @@@ total_found += add_new_free_space(block_group, fs_info, last, block_group->key.objectid + block_group->key.offset); + caching_ctl->progress = (u64)-1; + + out: + btrfs_free_path(path); + return ret; + } + + static noinline void caching_thread(struct btrfs_work *work) + { + struct btrfs_block_group_cache *block_group; + struct btrfs_fs_info *fs_info; + struct btrfs_caching_control *caching_ctl; + int ret; + + caching_ctl = container_of(work, struct btrfs_caching_control, work); + block_group = caching_ctl->block_group; + fs_info = block_group->fs_info; + + mutex_lock(&caching_ctl->mutex); + down_read(&fs_info->commit_root_sem); + + if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) + ret = load_free_space_tree(caching_ctl); + else + ret = load_extent_tree_free(caching_ctl); + spin_lock(&block_group->lock); block_group->caching_ctl = NULL; - block_group->cached = BTRFS_CACHE_FINISHED; + block_group->cached = ret ? BTRFS_CACHE_ERROR : BTRFS_CACHE_FINISHED; spin_unlock(&block_group->lock); +#ifdef CONFIG_BTRFS_DEBUG + if (btrfs_should_fragment_free_space(extent_root, block_group)) { + u64 bytes_used; + + spin_lock(&block_group->space_info->lock); + spin_lock(&block_group->lock); + bytes_used = block_group->key.offset - + btrfs_block_group_used(&block_group->item); + block_group->space_info->bytes_used += bytes_used >> 1; + spin_unlock(&block_group->lock); + spin_unlock(&block_group->space_info->lock); + fragment_free_space(extent_root, block_group); + } +#endif + + caching_ctl->progress = (u64)-1; - err: - btrfs_free_path(path); - up_read(&fs_info->commit_root_sem); - - free_excluded_extents(extent_root, block_group); + + up_read(&fs_info->commit_root_sem); + free_excluded_extents(fs_info->extent_root, block_group); mutex_unlock(&caching_ctl->mutex); - out: - if (ret) { - spin_lock(&block_group->lock); - block_group->caching_ctl = NULL; - block_group->cached = BTRFS_CACHE_ERROR; - spin_unlock(&block_group->lock); - } + wake_up(&caching_ctl->wait); put_caching_control(caching_ctl); diff --cc fs/btrfs/tests/btrfs-tests.c index 9626252ee6b4,ba28cefdf9e7..b1d920b30070 --- a/fs/btrfs/tests/btrfs-tests.c +++ b/fs/btrfs/tests/btrfs-tests.c @@@ -169,3 -175,49 +175,55 @@@ void btrfs_free_dummy_root(struct btrfs kfree(root); } + struct btrfs_block_group_cache * + btrfs_alloc_dummy_block_group(unsigned long length) + { + struct btrfs_block_group_cache *cache; + + cache = kzalloc(sizeof(*cache), GFP_NOFS); + if (!cache) + return NULL; + cache->free_space_ctl = kzalloc(sizeof(*cache->free_space_ctl), + GFP_NOFS); + if (!cache->free_space_ctl) { + kfree(cache); + return NULL; + } ++ cache->fs_info = btrfs_alloc_dummy_fs_info(); ++ if (!cache->fs_info) { ++ kfree(cache->free_space_ctl); ++ kfree(cache); ++ return NULL; ++ } + + cache->key.objectid = 0; + cache->key.offset = length; + cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; + cache->sectorsize = 4096; + cache->full_stripe_len = 4096; + + INIT_LIST_HEAD(&cache->list); + INIT_LIST_HEAD(&cache->cluster_list); + INIT_LIST_HEAD(&cache->bg_list); + btrfs_init_free_space_ctl(cache); + mutex_init(&cache->free_space_lock); + + return cache; + } + + void btrfs_free_dummy_block_group(struct btrfs_block_group_cache *cache) + { + if (!cache) + return; + __btrfs_remove_free_space_cache(cache->free_space_ctl); + kfree(cache->free_space_ctl); + kfree(cache); + } + + void btrfs_init_dummy_trans(struct btrfs_trans_handle *trans) + { + memset(trans, 0, sizeof(*trans)); + trans->transid = 1; + INIT_LIST_HEAD(&trans->qgroup_ref_list); + trans->type = __TRANS_DUMMY; + } diff --cc fs/btrfs/tests/free-space-tests.c index 8b72b005bfb9,bae6c599f604..cd3e300b9ba5 --- a/fs/btrfs/tests/free-space-tests.c +++ b/fs/btrfs/tests/free-space-tests.c @@@ -922,10 -872,7 +887,8 @@@ int btrfs_test_free_space_cache(void ret = test_steal_space_from_bitmap_to_extent(cache); out: - __btrfs_remove_free_space_cache(cache->free_space_ctl); - kfree(cache->free_space_ctl); - kfree(cache); + btrfs_free_dummy_block_group(cache); + btrfs_free_dummy_root(root); test_msg("Free space cache tests finished\n"); return ret; }