diff options
Diffstat (limited to 'fs/btrfs/free-space-cache.c')
-rw-r--r-- | fs/btrfs/free-space-cache.c | 231 |
1 files changed, 121 insertions, 110 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index e4b48f377d3a..da6841efac26 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -18,6 +18,7 @@ #include <linux/pagemap.h> #include <linux/sched.h> +#include <linux/sched/signal.h> #include <linux/slab.h> #include <linux/math64.h> #include <linux/ratelimit.h> @@ -42,11 +43,16 @@ static int link_free_space(struct btrfs_free_space_ctl *ctl, struct btrfs_free_space *info); static void unlink_free_space(struct btrfs_free_space_ctl *ctl, struct btrfs_free_space *info); +static int btrfs_wait_cache_io_root(struct btrfs_root *root, + struct btrfs_trans_handle *trans, + struct btrfs_io_ctl *io_ctl, + struct btrfs_path *path); static struct inode *__lookup_free_space_inode(struct btrfs_root *root, struct btrfs_path *path, u64 offset) { + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_key key; struct btrfs_key location; struct btrfs_disk_key disk_key; @@ -74,9 +80,7 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root, btrfs_disk_key_to_cpu(&location, &disk_key); btrfs_release_path(path); - inode = btrfs_iget(root->fs_info->sb, &location, root, NULL); - if (!inode) - return ERR_PTR(-ENOENT); + inode = btrfs_iget(fs_info->sb, &location, root, NULL); if (IS_ERR(inode)) return inode; if (is_bad_inode(inode)) { @@ -91,7 +95,7 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root, return inode; } -struct inode *lookup_free_space_inode(struct btrfs_root *root, +struct inode *lookup_free_space_inode(struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *block_group, struct btrfs_path *path) { @@ -105,15 +109,14 @@ struct inode *lookup_free_space_inode(struct btrfs_root *root, if (inode) return inode; - inode = __lookup_free_space_inode(root, path, + inode = __lookup_free_space_inode(fs_info->tree_root, path, block_group->key.objectid); if (IS_ERR(inode)) return inode; spin_lock(&block_group->lock); if (!((BTRFS_I(inode)->flags & flags) == flags)) { - btrfs_info(root->fs_info, - "Old style space inode found, converting."); + btrfs_info(fs_info, "Old style space inode found, converting."); BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM | BTRFS_INODE_NODATACOW; block_group->disk_cache_state = BTRFS_DC_CLEAR; @@ -153,7 +156,7 @@ static int __create_free_space_inode(struct btrfs_root *root, inode_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_inode_item); btrfs_item_key(leaf, &disk_key, path->slots[0]); - memset_extent_buffer(leaf, 0, (unsigned long)inode_item, + memzero_extent_buffer(leaf, (unsigned long)inode_item, sizeof(*inode_item)); btrfs_set_inode_generation(leaf, inode_item, trans->transid); btrfs_set_inode_size(leaf, inode_item, 0); @@ -181,7 +184,7 @@ static int __create_free_space_inode(struct btrfs_root *root, leaf = path->nodes[0]; header = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_free_space_header); - memset_extent_buffer(leaf, 0, (unsigned long)header, sizeof(*header)); + memzero_extent_buffer(leaf, (unsigned long)header, sizeof(*header)); btrfs_set_free_space_key(leaf, header, &disk_key); btrfs_mark_buffer_dirty(leaf); btrfs_release_path(path); @@ -189,7 +192,7 @@ static int __create_free_space_inode(struct btrfs_root *root, return 0; } -int create_free_space_inode(struct btrfs_root *root, +int create_free_space_inode(struct btrfs_fs_info *fs_info, struct btrfs_trans_handle *trans, struct btrfs_block_group_cache *block_group, struct btrfs_path *path) @@ -197,23 +200,23 @@ int create_free_space_inode(struct btrfs_root *root, int ret; u64 ino; - ret = btrfs_find_free_objectid(root, &ino); + ret = btrfs_find_free_objectid(fs_info->tree_root, &ino); if (ret < 0) return ret; - return __create_free_space_inode(root, trans, path, ino, + return __create_free_space_inode(fs_info->tree_root, trans, path, ino, block_group->key.objectid); } -int btrfs_check_trunc_cache_free_space(struct btrfs_root *root, +int btrfs_check_trunc_cache_free_space(struct btrfs_fs_info *fs_info, struct btrfs_block_rsv *rsv) { u64 needed_bytes; int ret; /* 1 for slack space, 1 for updating the inode */ - needed_bytes = btrfs_calc_trunc_metadata_size(root, 1) + - btrfs_calc_trans_metadata_size(root, 1); + needed_bytes = btrfs_calc_trunc_metadata_size(fs_info, 1) + + btrfs_calc_trans_metadata_size(fs_info, 1); spin_lock(&rsv->lock); if (rsv->reserved < needed_bytes) @@ -224,29 +227,27 @@ int btrfs_check_trunc_cache_free_space(struct btrfs_root *root, return ret; } -int btrfs_truncate_free_space_cache(struct btrfs_root *root, - struct btrfs_trans_handle *trans, +int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans, struct btrfs_block_group_cache *block_group, struct inode *inode) { + struct btrfs_root *root = BTRFS_I(inode)->root; int ret = 0; - struct btrfs_path *path = btrfs_alloc_path(); bool locked = false; - if (!path) { - ret = -ENOMEM; - goto fail; - } - if (block_group) { + struct btrfs_path *path = btrfs_alloc_path(); + + if (!path) { + ret = -ENOMEM; + goto fail; + } locked = true; mutex_lock(&trans->transaction->cache_write_mutex); if (!list_empty(&block_group->io_list)) { list_del_init(&block_group->io_list); - btrfs_wait_cache_io(root, trans, block_group, - &block_group->io_ctl, path, - block_group->key.objectid); + btrfs_wait_cache_io(trans, block_group, path); btrfs_put_block_group(block_group); } @@ -257,10 +258,10 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, spin_lock(&block_group->lock); block_group->disk_cache_state = BTRFS_DC_CLEAR; spin_unlock(&block_group->lock); + btrfs_free_path(path); } - btrfs_free_path(path); - btrfs_i_size_write(inode, 0); + btrfs_i_size_write(BTRFS_I(inode), 0); truncate_pagecache(inode, 0); /* @@ -285,14 +286,14 @@ fail: return ret; } -static int readahead_cache(struct inode *inode) +static void readahead_cache(struct inode *inode) { struct file_ra_state *ra; unsigned long last_index; ra = kzalloc(sizeof(*ra), GFP_NOFS); if (!ra) - return -ENOMEM; + return; file_ra_state_init(ra, inode->i_mapping); last_index = (i_size_read(inode) - 1) >> PAGE_SHIFT; @@ -300,19 +301,17 @@ static int readahead_cache(struct inode *inode) page_cache_sync_readahead(inode->i_mapping, ra, NULL, 0, last_index); kfree(ra); - - return 0; } static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode, - struct btrfs_root *root, int write) + int write) { int num_pages; int check_crcs = 0; num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); - if (btrfs_ino(inode) != BTRFS_FREE_INO_OBJECTID) + if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FREE_INO_OBJECTID) check_crcs = 1; /* Make sure we can fit our crcs into the first page */ @@ -327,7 +326,7 @@ static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode, return -ENOMEM; io_ctl->num_pages = num_pages; - io_ctl->root = root; + io_ctl->fs_info = btrfs_sb(inode->i_sb); io_ctl->check_crcs = check_crcs; io_ctl->inode = inode; @@ -450,7 +449,7 @@ static int io_ctl_check_generation(struct btrfs_io_ctl *io_ctl, u64 generation) gen = io_ctl->cur; if (le64_to_cpu(*gen) != generation) { - btrfs_err_rl(io_ctl->root->fs_info, + btrfs_err_rl(io_ctl->fs_info, "space cache generation (%llu) does not match inode (%llu)", *gen, generation); io_ctl_unmap_page(io_ctl); @@ -476,7 +475,7 @@ static void io_ctl_set_crc(struct btrfs_io_ctl *io_ctl, int index) crc = btrfs_csum_data(io_ctl->orig + offset, crc, PAGE_SIZE - offset); - btrfs_csum_final(crc, (char *)&crc); + btrfs_csum_final(crc, (u8 *)&crc); io_ctl_unmap_page(io_ctl); tmp = page_address(io_ctl->pages[0]); tmp += index; @@ -504,9 +503,9 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index) io_ctl_map_page(io_ctl, 0); crc = btrfs_csum_data(io_ctl->orig + offset, crc, PAGE_SIZE - offset); - btrfs_csum_final(crc, (char *)&crc); + btrfs_csum_final(crc, (u8 *)&crc); if (val != crc) { - btrfs_err_rl(io_ctl->root->fs_info, + btrfs_err_rl(io_ctl->fs_info, "csum mismatch on free space cache"); io_ctl_unmap_page(io_ctl); return -EIO; @@ -669,6 +668,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, struct btrfs_free_space_ctl *ctl, struct btrfs_path *path, u64 offset) { + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_free_space_header *header; struct extent_buffer *leaf; struct btrfs_io_ctl io_ctl; @@ -708,29 +708,27 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, btrfs_release_path(path); if (!BTRFS_I(inode)->generation) { - btrfs_info(root->fs_info, + btrfs_info(fs_info, "The free space cache file (%llu) is invalid. skip it\n", offset); return 0; } if (BTRFS_I(inode)->generation != generation) { - btrfs_err(root->fs_info, - "free space inode generation (%llu) did not match free space cache generation (%llu)", - BTRFS_I(inode)->generation, generation); + btrfs_err(fs_info, + "free space inode generation (%llu) did not match free space cache generation (%llu)", + BTRFS_I(inode)->generation, generation); return 0; } if (!num_entries) return 0; - ret = io_ctl_init(&io_ctl, inode, root, 0); + ret = io_ctl_init(&io_ctl, inode, 0); if (ret) return ret; - ret = readahead_cache(inode); - if (ret) - goto out; + readahead_cache(inode); ret = io_ctl_prepare_pages(&io_ctl, inode, 1); if (ret) @@ -766,7 +764,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, ret = link_free_space(ctl, e); spin_unlock(&ctl->tree_lock); if (ret) { - btrfs_err(root->fs_info, + btrfs_err(fs_info, "Duplicate entries in free space cache, dumping"); kmem_cache_free(btrfs_free_space_cachep, e); goto free_cache; @@ -786,7 +784,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, ctl->op->recalc_thresholds(ctl); spin_unlock(&ctl->tree_lock); if (ret) { - btrfs_err(root->fs_info, + btrfs_err(fs_info, "Duplicate entries in free space cache, dumping"); kmem_cache_free(btrfs_free_space_cachep, e); goto free_cache; @@ -826,7 +824,6 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *block_group) { struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; - struct btrfs_root *root = fs_info->tree_root; struct inode *inode; struct btrfs_path *path; int ret = 0; @@ -850,7 +847,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, path->search_commit_root = 1; path->skip_locking = 1; - inode = lookup_free_space_inode(root, block_group, path); + inode = lookup_free_space_inode(fs_info, block_group, path); if (IS_ERR(inode)) { btrfs_free_path(path); return 0; @@ -1033,7 +1030,7 @@ fail: } static noinline_for_stack int -write_pinned_extent_entries(struct btrfs_root *root, +write_pinned_extent_entries(struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *block_group, struct btrfs_io_ctl *io_ctl, int *entries) @@ -1052,7 +1049,7 @@ write_pinned_extent_entries(struct btrfs_root *root, * We shouldn't have switched the pinned extents yet so this is the * right one */ - unpin = root->fs_info->pinned_extents; + unpin = fs_info->pinned_extents; start = block_group->key.objectid; @@ -1126,8 +1123,7 @@ cleanup_bitmap_list(struct list_head *bitmap_list) static void noinline_for_stack cleanup_write_cache_enospc(struct inode *inode, struct btrfs_io_ctl *io_ctl, - struct extent_state **cached_state, - struct list_head *bitmap_list) + struct extent_state **cached_state) { io_ctl_drop_pages(io_ctl); unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, @@ -1135,20 +1131,20 @@ cleanup_write_cache_enospc(struct inode *inode, GFP_NOFS); } -int btrfs_wait_cache_io(struct btrfs_root *root, - struct btrfs_trans_handle *trans, - struct btrfs_block_group_cache *block_group, - struct btrfs_io_ctl *io_ctl, - struct btrfs_path *path, u64 offset) +static int __btrfs_wait_cache_io(struct btrfs_root *root, + struct btrfs_trans_handle *trans, + struct btrfs_block_group_cache *block_group, + struct btrfs_io_ctl *io_ctl, + struct btrfs_path *path, u64 offset) { int ret; struct inode *inode = io_ctl->inode; + struct btrfs_fs_info *fs_info; if (!inode) return 0; - if (block_group) - root = root->fs_info->tree_root; + fs_info = btrfs_sb(inode->i_sb); /* Flush the dirty pages in the cache file. */ ret = flush_dirty_cache(inode); @@ -1165,9 +1161,9 @@ out: BTRFS_I(inode)->generation = 0; if (block_group) { #ifdef DEBUG - btrfs_err(root->fs_info, - "failed to write free space cache for block group %llu", - block_group->key.objectid); + btrfs_err(fs_info, + "failed to write free space cache for block group %llu", + block_group->key.objectid); #endif } } @@ -1200,14 +1196,29 @@ out: } +static int btrfs_wait_cache_io_root(struct btrfs_root *root, + struct btrfs_trans_handle *trans, + struct btrfs_io_ctl *io_ctl, + struct btrfs_path *path) +{ + return __btrfs_wait_cache_io(root, trans, NULL, io_ctl, path, 0); +} + +int btrfs_wait_cache_io(struct btrfs_trans_handle *trans, + struct btrfs_block_group_cache *block_group, + struct btrfs_path *path) +{ + return __btrfs_wait_cache_io(block_group->fs_info->tree_root, trans, + block_group, &block_group->io_ctl, + path, block_group->key.objectid); +} + /** * __btrfs_write_out_cache - write out cached info to an inode * @root - the root the inode belongs to * @ctl - the free space cache we are going to write out * @block_group - the block_group for this cache if it belongs to a block_group * @trans - the trans handle - * @path - the path to use - * @offset - the offset for the key we'll insert * * This function writes out a free space cache struct to disk for quick recovery * on mount. This will return 0 if it was successful in writing the cache out, @@ -1217,9 +1228,9 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, struct btrfs_free_space_ctl *ctl, struct btrfs_block_group_cache *block_group, struct btrfs_io_ctl *io_ctl, - struct btrfs_trans_handle *trans, - struct btrfs_path *path, u64 offset) + struct btrfs_trans_handle *trans) { + struct btrfs_fs_info *fs_info = root->fs_info; struct extent_state *cached_state = NULL; LIST_HEAD(bitmap_list); int entries = 0; @@ -1231,7 +1242,7 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, return -EIO; WARN_ON(io_ctl->pages); - ret = io_ctl_init(io_ctl, inode, root, 1); + ret = io_ctl_init(io_ctl, inode, 1); if (ret) return ret; @@ -1277,7 +1288,8 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, * If this changes while we are working we'll get added back to * the dirty list and redo it. No locking needed */ - ret = write_pinned_extent_entries(root, block_group, io_ctl, &entries); + ret = write_pinned_extent_entries(fs_info, block_group, + io_ctl, &entries); if (ret) goto out_nospc_locked; @@ -1296,8 +1308,8 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, io_ctl_zero_remaining_pages(io_ctl); /* Everything is written out, now we dirty the pages in the file. */ - ret = btrfs_dirty_pages(root, inode, io_ctl->pages, io_ctl->num_pages, - 0, i_size_read(inode), &cached_state); + ret = btrfs_dirty_pages(inode, io_ctl->pages, io_ctl->num_pages, 0, + i_size_read(inode), &cached_state); if (ret) goto out_nospc; @@ -1344,7 +1356,7 @@ out_nospc_locked: mutex_unlock(&ctl->cache_writeout_mutex); out_nospc: - cleanup_write_cache_enospc(inode, io_ctl, &cached_state, &bitmap_list); + cleanup_write_cache_enospc(inode, io_ctl, &cached_state); if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) up_write(&block_group->data_rwsem); @@ -1352,7 +1364,7 @@ out_nospc: goto out; } -int btrfs_write_out_cache(struct btrfs_root *root, +int btrfs_write_out_cache(struct btrfs_fs_info *fs_info, struct btrfs_trans_handle *trans, struct btrfs_block_group_cache *block_group, struct btrfs_path *path) @@ -1361,8 +1373,6 @@ int btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode; int ret = 0; - root = root->fs_info->tree_root; - spin_lock(&block_group->lock); if (block_group->disk_cache_state < BTRFS_DC_SETUP) { spin_unlock(&block_group->lock); @@ -1370,18 +1380,17 @@ int btrfs_write_out_cache(struct btrfs_root *root, } spin_unlock(&block_group->lock); - inode = lookup_free_space_inode(root, block_group, path); + inode = lookup_free_space_inode(fs_info, block_group, path); if (IS_ERR(inode)) return 0; - ret = __btrfs_write_out_cache(root, inode, ctl, block_group, - &block_group->io_ctl, trans, - path, block_group->key.objectid); + ret = __btrfs_write_out_cache(fs_info->tree_root, inode, ctl, + block_group, &block_group->io_ctl, trans); if (ret) { #ifdef DEBUG - btrfs_err(root->fs_info, - "failed to write free space cache for block group %llu", - block_group->key.objectid); + btrfs_err(fs_info, + "failed to write free space cache for block group %llu", + block_group->key.objectid); #endif spin_lock(&block_group->lock); block_group->disk_cache_state = BTRFS_DC_ERROR; @@ -1968,11 +1977,11 @@ static bool use_bitmap(struct btrfs_free_space_ctl *ctl, struct btrfs_free_space *info) { struct btrfs_block_group_cache *block_group = ctl->private; + struct btrfs_fs_info *fs_info = block_group->fs_info; bool forced = false; #ifdef CONFIG_BTRFS_DEBUG - if (btrfs_should_fragment_free_space(block_group->fs_info->extent_root, - block_group)) + if (btrfs_should_fragment_free_space(block_group)) forced = true; #endif @@ -1988,7 +1997,7 @@ static bool use_bitmap(struct btrfs_free_space_ctl *ctl, * of cache left then go ahead an dadd them, no sense in adding * the overhead of a bitmap if we don't have to. */ - if (info->bytes <= block_group->sectorsize * 4) { + if (info->bytes <= fs_info->sectorsize * 4) { if (ctl->free_extents * 2 <= ctl->extents_thresh) return false; } else { @@ -2447,6 +2456,7 @@ out: void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group, u64 bytes) { + struct btrfs_fs_info *fs_info = block_group->fs_info; struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; struct btrfs_free_space *info; struct rb_node *n; @@ -2456,23 +2466,23 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group, info = rb_entry(n, struct btrfs_free_space, offset_index); if (info->bytes >= bytes && !block_group->ro) count++; - btrfs_crit(block_group->fs_info, - "entry offset %llu, bytes %llu, bitmap %s", + btrfs_crit(fs_info, "entry offset %llu, bytes %llu, bitmap %s", info->offset, info->bytes, (info->bitmap) ? "yes" : "no"); } - btrfs_info(block_group->fs_info, "block group has cluster?: %s", + btrfs_info(fs_info, "block group has cluster?: %s", list_empty(&block_group->cluster_list) ? "no" : "yes"); - btrfs_info(block_group->fs_info, + btrfs_info(fs_info, "%d blocks of free space at or bigger than bytes is", count); } void btrfs_init_free_space_ctl(struct btrfs_block_group_cache *block_group) { + struct btrfs_fs_info *fs_info = block_group->fs_info; struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; spin_lock_init(&ctl->tree_lock); - ctl->unit = block_group->sectorsize; + ctl->unit = fs_info->sectorsize; ctl->start = block_group->key.objectid; ctl->private = block_group; ctl->op = &free_space_op; @@ -3011,7 +3021,7 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, * returns zero and sets up cluster if things worked out, otherwise * it returns -enospc */ -int btrfs_find_space_cluster(struct btrfs_root *root, +int btrfs_find_space_cluster(struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *block_group, struct btrfs_free_cluster *cluster, u64 offset, u64 bytes, u64 empty_size) @@ -3029,14 +3039,14 @@ int btrfs_find_space_cluster(struct btrfs_root *root, * For metadata, allow allocates with smaller extents. For * data, keep it dense. */ - if (btrfs_test_opt(root->fs_info, SSD_SPREAD)) { + if (btrfs_test_opt(fs_info, SSD_SPREAD)) { cont1_bytes = min_bytes = bytes + empty_size; } else if (block_group->flags & BTRFS_BLOCK_GROUP_METADATA) { cont1_bytes = bytes; - min_bytes = block_group->sectorsize; + min_bytes = fs_info->sectorsize; } else { cont1_bytes = max(bytes, (bytes + empty_size) >> 2); - min_bytes = block_group->sectorsize; + min_bytes = fs_info->sectorsize; } spin_lock(&ctl->tree_lock); @@ -3124,8 +3134,7 @@ static int do_trimming(struct btrfs_block_group_cache *block_group, spin_unlock(&block_group->lock); spin_unlock(&space_info->lock); - ret = btrfs_discard_extent(fs_info->extent_root, - start, bytes, &trimmed); + ret = btrfs_discard_extent(fs_info, start, bytes, &trimmed); if (!ret) *total_trimmed += trimmed; @@ -3321,6 +3330,7 @@ void btrfs_get_block_group_trimming(struct btrfs_block_group_cache *cache) void btrfs_put_block_group_trimming(struct btrfs_block_group_cache *block_group) { + struct btrfs_fs_info *fs_info = block_group->fs_info; struct extent_map_tree *em_tree; struct extent_map *em; bool cleanup; @@ -3331,8 +3341,8 @@ void btrfs_put_block_group_trimming(struct btrfs_block_group_cache *block_group) spin_unlock(&block_group->lock); if (cleanup) { - lock_chunks(block_group->fs_info->chunk_root); - em_tree = &block_group->fs_info->mapping_tree.map_tree; + mutex_lock(&fs_info->chunk_mutex); + em_tree = &fs_info->mapping_tree.map_tree; write_lock(&em_tree->lock); em = lookup_extent_mapping(em_tree, block_group->key.objectid, 1); @@ -3343,7 +3353,7 @@ void btrfs_put_block_group_trimming(struct btrfs_block_group_cache *block_group) */ remove_extent_mapping(em_tree, em); write_unlock(&em_tree->lock); - unlock_chunks(block_group->fs_info->chunk_root); + mutex_unlock(&fs_info->chunk_mutex); /* once for us and once for the tree */ free_extent_map(em); @@ -3473,7 +3483,7 @@ int load_free_ino_cache(struct btrfs_fs_info *fs_info, struct btrfs_root *root) int ret = 0; u64 root_gen = btrfs_root_generation(&root->root_item); - if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE)) + if (!btrfs_test_opt(fs_info, INODE_MAP_CACHE)) return 0; /* @@ -3512,17 +3522,17 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root, struct btrfs_path *path, struct inode *inode) { + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; int ret; struct btrfs_io_ctl io_ctl; bool release_metadata = true; - if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE)) + if (!btrfs_test_opt(fs_info, INODE_MAP_CACHE)) return 0; memset(&io_ctl, 0, sizeof(io_ctl)); - ret = __btrfs_write_out_cache(root, inode, ctl, NULL, &io_ctl, - trans, path, 0); + ret = __btrfs_write_out_cache(root, inode, ctl, NULL, &io_ctl, trans); if (!ret) { /* * At this point writepages() didn't error out, so our metadata @@ -3531,16 +3541,17 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root, * with or without an error. */ release_metadata = false; - ret = btrfs_wait_cache_io(root, trans, NULL, &io_ctl, path, 0); + ret = btrfs_wait_cache_io_root(root, trans, &io_ctl, path); } if (ret) { if (release_metadata) - btrfs_delalloc_release_metadata(inode, inode->i_size); + btrfs_delalloc_release_metadata(BTRFS_I(inode), + inode->i_size); #ifdef DEBUG - btrfs_err(root->fs_info, - "failed to write free ino cache for root %llu", - root->root_key.objectid); + btrfs_err(fs_info, + "failed to write free ino cache for root %llu", + root->root_key.objectid); #endif } |