diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 1551 |
1 files changed, 663 insertions, 888 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4607af38c72e..e97302f437a1 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -61,10 +61,10 @@ enum { }; static int update_block_group(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 bytenr, + struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, int alloc); static int __btrfs_free_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, struct btrfs_delayed_ref_node *node, u64 parent, u64 root_objectid, u64 owner_objectid, u64 owner_offset, int refs_to_drop, @@ -73,17 +73,17 @@ static void __run_delayed_extent_op(struct btrfs_delayed_extent_op *extent_op, struct extent_buffer *leaf, struct btrfs_extent_item *ei); static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, u64 parent, u64 root_objectid, u64 flags, u64 owner, u64 offset, struct btrfs_key *ins, int ref_mod); static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, u64 parent, u64 root_objectid, u64 flags, struct btrfs_disk_key *key, int level, struct btrfs_key *ins); static int do_chunk_alloc(struct btrfs_trans_handle *trans, - struct btrfs_root *extent_root, u64 flags, + struct btrfs_fs_info *fs_info, u64 flags, int force); static int find_next_key(struct btrfs_path *path, int level, struct btrfs_key *key); @@ -96,8 +96,6 @@ static int btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache, u64 num_bytes, int delalloc); static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, u64 num_bytes); -int btrfs_pin_extent(struct btrfs_root *root, - u64 bytenr, u64 num_bytes, int reserved); static int __reserve_metadata_bytes(struct btrfs_root *root, struct btrfs_space_info *space_info, u64 orig_bytes, @@ -223,18 +221,18 @@ block_group_cache_tree_search(struct btrfs_fs_info *info, u64 bytenr, return ret; } -static int add_excluded_extent(struct btrfs_root *root, +static int add_excluded_extent(struct btrfs_fs_info *fs_info, u64 start, u64 num_bytes) { u64 end = start + num_bytes - 1; - set_extent_bits(&root->fs_info->freed_extents[0], + set_extent_bits(&fs_info->freed_extents[0], start, end, EXTENT_UPTODATE); - set_extent_bits(&root->fs_info->freed_extents[1], + set_extent_bits(&fs_info->freed_extents[1], start, end, EXTENT_UPTODATE); return 0; } -static void free_excluded_extents(struct btrfs_root *root, +static void free_excluded_extents(struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *cache) { u64 start, end; @@ -242,13 +240,13 @@ static void free_excluded_extents(struct btrfs_root *root, start = cache->key.objectid; end = start + cache->key.offset - 1; - clear_extent_bits(&root->fs_info->freed_extents[0], + clear_extent_bits(&fs_info->freed_extents[0], start, end, EXTENT_UPTODATE); - clear_extent_bits(&root->fs_info->freed_extents[1], + clear_extent_bits(&fs_info->freed_extents[1], start, end, EXTENT_UPTODATE); } -static int exclude_super_stripes(struct btrfs_root *root, +static int exclude_super_stripes(struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *cache) { u64 bytenr; @@ -259,7 +257,7 @@ static int exclude_super_stripes(struct btrfs_root *root, if (cache->key.objectid < BTRFS_SUPER_INFO_OFFSET) { stripe_len = BTRFS_SUPER_INFO_OFFSET - cache->key.objectid; cache->bytes_super += stripe_len; - ret = add_excluded_extent(root, cache->key.objectid, + ret = add_excluded_extent(fs_info, cache->key.objectid, stripe_len); if (ret) return ret; @@ -267,7 +265,7 @@ static int exclude_super_stripes(struct btrfs_root *root, for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { bytenr = btrfs_sb_offset(i); - ret = btrfs_rmap_block(root->fs_info, cache->key.objectid, + ret = btrfs_rmap_block(fs_info, cache->key.objectid, bytenr, 0, &logical, &nr, &stripe_len); if (ret) return ret; @@ -293,7 +291,7 @@ static int exclude_super_stripes(struct btrfs_root *root, } cache->bytes_super += len; - ret = add_excluded_extent(root, start, len); + ret = add_excluded_extent(fs_info, start, len); if (ret) { kfree(logical); return ret; @@ -329,13 +327,13 @@ static void put_caching_control(struct btrfs_caching_control *ctl) } #ifdef CONFIG_BTRFS_DEBUG -static void fragment_free_space(struct btrfs_root *root, - struct btrfs_block_group_cache *block_group) +static void fragment_free_space(struct btrfs_block_group_cache *block_group) { + struct btrfs_fs_info *fs_info = block_group->fs_info; u64 start = block_group->key.objectid; u64 len = block_group->key.offset; u64 chunk = block_group->flags & BTRFS_BLOCK_GROUP_METADATA ? - root->nodesize : root->sectorsize; + fs_info->nodesize : fs_info->sectorsize; u64 step = chunk << 1; while (len > chunk) { @@ -394,9 +392,9 @@ u64 add_new_free_space(struct btrfs_block_group_cache *block_group, static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl) { - struct btrfs_block_group_cache *block_group; - struct btrfs_fs_info *fs_info; - struct btrfs_root *extent_root; + struct btrfs_block_group_cache *block_group = caching_ctl->block_group; + struct btrfs_fs_info *fs_info = block_group->fs_info; + struct btrfs_root *extent_root = fs_info->extent_root; struct btrfs_path *path; struct extent_buffer *leaf; struct btrfs_key key; @@ -406,10 +404,6 @@ static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl) int ret; bool wakeup = true; - block_group = caching_ctl->block_group; - fs_info = block_group->fs_info; - extent_root = fs_info->extent_root; - path = btrfs_alloc_path(); if (!path) return -ENOMEM; @@ -422,7 +416,7 @@ static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl) * allocate from this block group until we've had a chance to fragment * the free space. */ - if (btrfs_should_fragment_free_space(extent_root, block_group)) + if (btrfs_should_fragment_free_space(block_group)) wakeup = false; #endif /* @@ -510,7 +504,7 @@ next: key.objectid); if (key.type == BTRFS_METADATA_ITEM_KEY) last = key.objectid + - fs_info->tree_root->nodesize; + fs_info->nodesize; else last = key.objectid + key.offset; @@ -561,7 +555,7 @@ static noinline void caching_thread(struct btrfs_work *work) spin_unlock(&block_group->lock); #ifdef CONFIG_BTRFS_DEBUG - if (btrfs_should_fragment_free_space(extent_root, block_group)) { + if (btrfs_should_fragment_free_space(block_group)) { u64 bytes_used; spin_lock(&block_group->space_info->lock); @@ -571,14 +565,14 @@ static noinline void caching_thread(struct btrfs_work *work) 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); + fragment_free_space(block_group); } #endif caching_ctl->progress = (u64)-1; up_read(&fs_info->commit_root_sem); - free_excluded_extents(fs_info->extent_root, block_group); + free_excluded_extents(fs_info, block_group); mutex_unlock(&caching_ctl->mutex); wake_up(&caching_ctl->wait); @@ -668,8 +662,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, spin_unlock(&cache->lock); #ifdef CONFIG_BTRFS_DEBUG if (ret == 1 && - btrfs_should_fragment_free_space(fs_info->extent_root, - cache)) { + btrfs_should_fragment_free_space(cache)) { u64 bytes_used; spin_lock(&cache->space_info->lock); @@ -679,7 +672,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, cache->space_info->bytes_used += bytes_used >> 1; spin_unlock(&cache->lock); spin_unlock(&cache->space_info->lock); - fragment_free_space(fs_info->extent_root, cache); + fragment_free_space(cache); } #endif mutex_unlock(&caching_ctl->mutex); @@ -687,7 +680,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, wake_up(&caching_ctl->wait); if (ret == 1) { put_caching_control(caching_ctl); - free_excluded_extents(fs_info->extent_root, cache); + free_excluded_extents(fs_info, cache); return 0; } } else { @@ -778,7 +771,7 @@ void btrfs_clear_space_info_full(struct btrfs_fs_info *info) } /* simple helper to search for an existing data extent at a given offset */ -int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len) +int btrfs_lookup_data_extent(struct btrfs_fs_info *fs_info, u64 start, u64 len) { int ret; struct btrfs_key key; @@ -791,8 +784,7 @@ int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len) key.objectid = start; key.offset = len; key.type = BTRFS_EXTENT_ITEM_KEY; - ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path, - 0, 0); + ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0); btrfs_free_path(path); return ret; } @@ -807,7 +799,7 @@ int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len) * the delayed refs are not processed. */ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 bytenr, + struct btrfs_fs_info *fs_info, u64 bytenr, u64 offset, int metadata, u64 *refs, u64 *flags) { struct btrfs_delayed_ref_head *head; @@ -825,8 +817,8 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, * If we don't have skinny metadata, don't bother doing anything * different */ - if (metadata && !btrfs_fs_incompat(root->fs_info, SKINNY_METADATA)) { - offset = root->nodesize; + if (metadata && !btrfs_fs_incompat(fs_info, SKINNY_METADATA)) { + offset = fs_info->nodesize; metadata = 0; } @@ -847,8 +839,7 @@ search_again: else key.type = BTRFS_EXTENT_ITEM_KEY; - ret = btrfs_search_slot(trans, root->fs_info->extent_root, - &key, path, 0, 0); + ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); if (ret < 0) goto out_free; @@ -859,7 +850,7 @@ search_again: path->slots[0]); if (key.objectid == bytenr && key.type == BTRFS_EXTENT_ITEM_KEY && - key.offset == root->nodesize) + key.offset == fs_info->nodesize) ret = 0; } } @@ -1101,7 +1092,7 @@ static int convert_extent_item_v0(struct btrfs_trans_handle *trans, return ret; BUG_ON(ret); /* Corruption */ - btrfs_extend_item(root, path, new_size); + btrfs_extend_item(root->fs_info, path, new_size); leaf = path->nodes[0]; item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); @@ -1114,7 +1105,7 @@ static int convert_extent_item_v0(struct btrfs_trans_handle *trans, BTRFS_BLOCK_FLAG_FULL_BACKREF); bi = (struct btrfs_tree_block_info *)(item + 1); /* FIXME: get first key of the block */ - memset_extent_buffer(leaf, 0, (unsigned long)bi, sizeof(*bi)); + memzero_extent_buffer(leaf, (unsigned long)bi, sizeof(*bi)); btrfs_set_tree_block_level(leaf, bi, (int)owner); } else { btrfs_set_extent_flags(leaf, item, BTRFS_EXTENT_FLAG_DATA); @@ -1540,6 +1531,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, u64 parent, u64 root_objectid, u64 owner, u64 offset, int insert) { + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_key key; struct extent_buffer *leaf; struct btrfs_extent_item *ei; @@ -1553,8 +1545,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, int want; int ret; int err = 0; - bool skinny_metadata = btrfs_fs_incompat(root->fs_info, - SKINNY_METADATA); + bool skinny_metadata = btrfs_fs_incompat(fs_info, SKINNY_METADATA); key.objectid = bytenr; key.type = BTRFS_EXTENT_ITEM_KEY; @@ -1748,7 +1739,7 @@ void setup_inline_extent_backref(struct btrfs_root *root, type = extent_ref_type(parent, owner); size = btrfs_extent_inline_ref_size(type); - btrfs_extend_item(root, path, size); + btrfs_extend_item(root->fs_info, path, size); ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); refs = btrfs_extent_refs(leaf, ei); @@ -1875,7 +1866,7 @@ void update_inline_extent_backref(struct btrfs_root *root, memmove_extent_buffer(leaf, ptr, ptr + size, end - ptr - size); item_size -= size; - btrfs_truncate_item(root, path, item_size, 1); + btrfs_truncate_item(root->fs_info, path, item_size, 1); } btrfs_mark_buffer_dirty(leaf); } @@ -2022,7 +2013,7 @@ static int btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len, return ret; } -int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, +int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, u64 *actual_bytes) { int ret; @@ -2034,10 +2025,10 @@ int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, * Avoid races with device replace and make sure our bbio has devices * associated to its stripes that don't go away while we are discarding. */ - btrfs_bio_counter_inc_blocked(root->fs_info); + btrfs_bio_counter_inc_blocked(fs_info); /* Tell the block device(s) that the sectors can be discarded */ - ret = btrfs_map_block(root->fs_info, REQ_OP_DISCARD, - bytenr, &num_bytes, &bbio, 0); + ret = btrfs_map_block(fs_info, BTRFS_MAP_DISCARD, bytenr, &num_bytes, + &bbio, 0); /* Error condition is -ENOMEM */ if (!ret) { struct btrfs_bio_stripe *stripe = bbio->stripes; @@ -2067,7 +2058,7 @@ int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, } btrfs_put_bbio(bbio); } - btrfs_bio_counter_dec(root->fs_info); + btrfs_bio_counter_dec(fs_info); if (actual_bytes) *actual_bytes = discarded_bytes; @@ -2080,12 +2071,11 @@ int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, /* Can return -ENOMEM */ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, u64 owner, u64 offset) { int ret; - struct btrfs_fs_info *fs_info = root->fs_info; BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID && root_objectid == BTRFS_TREE_LOG_OBJECTID); @@ -2105,13 +2095,12 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, } static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, struct btrfs_delayed_ref_node *node, u64 parent, u64 root_objectid, u64 owner, u64 offset, int refs_to_add, struct btrfs_delayed_extent_op *extent_op) { - struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_path *path; struct extent_buffer *leaf; struct btrfs_extent_item *item; @@ -2154,7 +2143,7 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, path->reada = READA_FORWARD; path->leave_spinning = 1; /* now insert the actual backref */ - ret = insert_extent_backref(trans, root->fs_info->extent_root, + ret = insert_extent_backref(trans, fs_info->extent_root, path, bytenr, parent, root_objectid, owner, offset, refs_to_add); if (ret) @@ -2165,7 +2154,7 @@ out: } static int run_delayed_data_ref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, struct btrfs_delayed_ref_node *node, struct btrfs_delayed_extent_op *extent_op, int insert_reserved) @@ -2182,7 +2171,7 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans, ins.type = BTRFS_EXTENT_ITEM_KEY; ref = btrfs_delayed_node_to_data_ref(node); - trace_run_delayed_data_ref(root->fs_info, node, ref, node->action); + trace_run_delayed_data_ref(fs_info, node, ref, node->action); if (node->type == BTRFS_SHARED_DATA_REF_KEY) parent = ref->parent; @@ -2191,17 +2180,17 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans, if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { if (extent_op) flags |= extent_op->flags_to_set; - ret = alloc_reserved_file_extent(trans, root, + ret = alloc_reserved_file_extent(trans, fs_info, parent, ref_root, flags, ref->objectid, ref->offset, &ins, node->ref_mod); } else if (node->action == BTRFS_ADD_DELAYED_REF) { - ret = __btrfs_inc_extent_ref(trans, root, node, parent, + ret = __btrfs_inc_extent_ref(trans, fs_info, node, parent, ref_root, ref->objectid, ref->offset, node->ref_mod, extent_op); } else if (node->action == BTRFS_DROP_DELAYED_REF) { - ret = __btrfs_free_extent(trans, root, node, parent, + ret = __btrfs_free_extent(trans, fs_info, node, parent, ref_root, ref->objectid, ref->offset, node->ref_mod, extent_op); @@ -2230,7 +2219,7 @@ static void __run_delayed_extent_op(struct btrfs_delayed_extent_op *extent_op, } static int run_delayed_extent_op(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, struct btrfs_delayed_ref_node *node, struct btrfs_delayed_extent_op *extent_op) { @@ -2246,7 +2235,7 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans, if (trans->aborted) return 0; - if (metadata && !btrfs_fs_incompat(root->fs_info, SKINNY_METADATA)) + if (metadata && !btrfs_fs_incompat(fs_info, SKINNY_METADATA)) metadata = 0; path = btrfs_alloc_path(); @@ -2266,8 +2255,7 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans, again: path->reada = READA_FORWARD; path->leave_spinning = 1; - ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, - path, 0, 1); + ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 1); if (ret < 0) { err = ret; goto out; @@ -2302,7 +2290,7 @@ again: item_size = btrfs_item_size_nr(leaf, path->slots[0]); #ifdef BTRFS_COMPAT_EXTENT_TREE_V0 if (item_size < sizeof(*ei)) { - ret = convert_extent_item_v0(trans, root->fs_info->extent_root, + ret = convert_extent_item_v0(trans, fs_info->extent_root, path, (u64)-1, 0); if (ret < 0) { err = ret; @@ -2323,7 +2311,7 @@ out: } static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, struct btrfs_delayed_ref_node *node, struct btrfs_delayed_extent_op *extent_op, int insert_reserved) @@ -2333,11 +2321,10 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, struct btrfs_key ins; u64 parent = 0; u64 ref_root = 0; - bool skinny_metadata = btrfs_fs_incompat(root->fs_info, - SKINNY_METADATA); + bool skinny_metadata = btrfs_fs_incompat(fs_info, SKINNY_METADATA); ref = btrfs_delayed_node_to_tree_ref(node); - trace_run_delayed_tree_ref(root->fs_info, node, ref, node->action); + trace_run_delayed_tree_ref(fs_info, node, ref, node->action); if (node->type == BTRFS_SHARED_BLOCK_REF_KEY) parent = ref->parent; @@ -2353,7 +2340,7 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, } if (node->ref_mod != 1) { - btrfs_err(root->fs_info, + btrfs_err(fs_info, "btree block(%llu) has %d references rather than 1: action %d ref_root %llu parent %llu", node->bytenr, node->ref_mod, node->action, ref_root, parent); @@ -2361,18 +2348,18 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, } if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { BUG_ON(!extent_op || !extent_op->update_flags); - ret = alloc_reserved_tree_block(trans, root, + ret = alloc_reserved_tree_block(trans, fs_info, parent, ref_root, extent_op->flags_to_set, &extent_op->key, ref->level, &ins); } else if (node->action == BTRFS_ADD_DELAYED_REF) { - ret = __btrfs_inc_extent_ref(trans, root, node, + ret = __btrfs_inc_extent_ref(trans, fs_info, node, parent, ref_root, ref->level, 0, 1, extent_op); } else if (node->action == BTRFS_DROP_DELAYED_REF) { - ret = __btrfs_free_extent(trans, root, node, + ret = __btrfs_free_extent(trans, fs_info, node, parent, ref_root, ref->level, 0, 1, extent_op); } else { @@ -2383,7 +2370,7 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, /* helper function to actually process a single delayed ref entry */ static int run_one_delayed_ref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, struct btrfs_delayed_ref_node *node, struct btrfs_delayed_extent_op *extent_op, int insert_reserved) @@ -2392,7 +2379,7 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans, if (trans->aborted) { if (insert_reserved) - btrfs_pin_extent(root, node->bytenr, + btrfs_pin_extent(fs_info, node->bytenr, node->num_bytes, 1); return 0; } @@ -2407,33 +2394,31 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans, */ BUG_ON(extent_op); head = btrfs_delayed_node_to_head(node); - trace_run_delayed_ref_head(root->fs_info, node, head, - node->action); + trace_run_delayed_ref_head(fs_info, node, head, node->action); if (insert_reserved) { - btrfs_pin_extent(root, node->bytenr, + btrfs_pin_extent(fs_info, node->bytenr, node->num_bytes, 1); if (head->is_data) { - ret = btrfs_del_csums(trans, root, + ret = btrfs_del_csums(trans, fs_info, node->bytenr, node->num_bytes); } } /* Also free its reserved qgroup space */ - btrfs_qgroup_free_delayed_ref(root->fs_info, - head->qgroup_ref_root, + btrfs_qgroup_free_delayed_ref(fs_info, head->qgroup_ref_root, head->qgroup_reserved); return ret; } if (node->type == BTRFS_TREE_BLOCK_REF_KEY || node->type == BTRFS_SHARED_BLOCK_REF_KEY) - ret = run_delayed_tree_ref(trans, root, node, extent_op, + ret = run_delayed_tree_ref(trans, fs_info, node, extent_op, insert_reserved); else if (node->type == BTRFS_EXTENT_DATA_REF_KEY || node->type == BTRFS_SHARED_DATA_REF_KEY) - ret = run_delayed_data_ref(trans, root, node, extent_op, + ret = run_delayed_data_ref(trans, fs_info, node, extent_op, insert_reserved); else BUG(); @@ -2454,13 +2439,14 @@ select_delayed_ref(struct btrfs_delayed_ref_head *head) * the extent item from the extent tree, when there still are references * to add, which would fail because they would not find the extent item. */ - list_for_each_entry(ref, &head->ref_list, list) { - if (ref->action == BTRFS_ADD_DELAYED_REF) - return ref; - } + if (!list_empty(&head->ref_add_list)) + return list_first_entry(&head->ref_add_list, + struct btrfs_delayed_ref_node, add_list); - return list_entry(head->ref_list.next, struct btrfs_delayed_ref_node, - list); + ref = list_first_entry(&head->ref_list, struct btrfs_delayed_ref_node, + list); + ASSERT(list_empty(&ref->add_list)); + return ref; } /* @@ -2468,14 +2454,13 @@ select_delayed_ref(struct btrfs_delayed_ref_head *head) * Returns -ENOMEM or -EIO on failure and will abort the transaction. */ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, unsigned long nr) { struct btrfs_delayed_ref_root *delayed_refs; struct btrfs_delayed_ref_node *ref; struct btrfs_delayed_ref_head *locked_ref = NULL; struct btrfs_delayed_extent_op *extent_op; - struct btrfs_fs_info *fs_info = root->fs_info; ktime_t start = ktime_get(); int ret; unsigned long count = 0; @@ -2574,7 +2559,7 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, if (extent_op) { spin_unlock(&locked_ref->lock); - ret = run_delayed_extent_op(trans, root, + ret = run_delayed_extent_op(trans, fs_info, ref, extent_op); btrfs_free_delayed_extent_op(extent_op); @@ -2620,6 +2605,8 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, actual_count++; ref->in_tree = 0; list_del(&ref->list); + if (!list_empty(&ref->add_list)) + list_del(&ref->add_list); } atomic_dec(&delayed_refs->num_entries); @@ -2642,7 +2629,7 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, } spin_unlock(&locked_ref->lock); - ret = run_one_delayed_ref(trans, root, ref, extent_op, + ret = run_one_delayed_ref(trans, fs_info, ref, extent_op, must_insert_reserved); btrfs_free_delayed_extent_op(extent_op); @@ -2743,43 +2730,43 @@ static u64 find_middle(struct rb_root *root) } #endif -static inline u64 heads_to_leaves(struct btrfs_root *root, u64 heads) +static inline u64 heads_to_leaves(struct btrfs_fs_info *fs_info, u64 heads) { u64 num_bytes; num_bytes = heads * (sizeof(struct btrfs_extent_item) + sizeof(struct btrfs_extent_inline_ref)); - if (!btrfs_fs_incompat(root->fs_info, SKINNY_METADATA)) + if (!btrfs_fs_incompat(fs_info, SKINNY_METADATA)) num_bytes += heads * sizeof(struct btrfs_tree_block_info); /* * We don't ever fill up leaves all the way so multiply by 2 just to be * closer to what we're really going to want to use. */ - return div_u64(num_bytes, BTRFS_LEAF_DATA_SIZE(root)); + return div_u64(num_bytes, BTRFS_LEAF_DATA_SIZE(fs_info)); } /* * Takes the number of bytes to be csumm'ed and figures out how many leaves it * would require to store the csums for that many bytes. */ -u64 btrfs_csum_bytes_to_leaves(struct btrfs_root *root, u64 csum_bytes) +u64 btrfs_csum_bytes_to_leaves(struct btrfs_fs_info *fs_info, u64 csum_bytes) { u64 csum_size; u64 num_csums_per_leaf; u64 num_csums; - csum_size = BTRFS_MAX_ITEM_SIZE(root); + csum_size = BTRFS_MAX_ITEM_SIZE(fs_info); num_csums_per_leaf = div64_u64(csum_size, - (u64)btrfs_super_csum_size(root->fs_info->super_copy)); - num_csums = div64_u64(csum_bytes, root->sectorsize); + (u64)btrfs_super_csum_size(fs_info->super_copy)); + num_csums = div64_u64(csum_bytes, fs_info->sectorsize); num_csums += num_csums_per_leaf - 1; num_csums = div64_u64(num_csums, num_csums_per_leaf); return num_csums; } int btrfs_check_space_for_delayed_refs(struct btrfs_trans_handle *trans, - struct btrfs_root *root) + struct btrfs_fs_info *fs_info) { struct btrfs_block_rsv *global_rsv; u64 num_heads = trans->transaction->delayed_refs.num_heads_ready; @@ -2788,15 +2775,16 @@ int btrfs_check_space_for_delayed_refs(struct btrfs_trans_handle *trans, u64 num_bytes, num_dirty_bgs_bytes; int ret = 0; - num_bytes = btrfs_calc_trans_metadata_size(root, 1); - num_heads = heads_to_leaves(root, num_heads); + num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1); + num_heads = heads_to_leaves(fs_info, num_heads); if (num_heads > 1) - num_bytes += (num_heads - 1) * root->nodesize; + num_bytes += (num_heads - 1) * fs_info->nodesize; num_bytes <<= 1; - num_bytes += btrfs_csum_bytes_to_leaves(root, csum_bytes) * root->nodesize; - num_dirty_bgs_bytes = btrfs_calc_trans_metadata_size(root, + num_bytes += btrfs_csum_bytes_to_leaves(fs_info, csum_bytes) * + fs_info->nodesize; + num_dirty_bgs_bytes = btrfs_calc_trans_metadata_size(fs_info, num_dirty_bgs); - global_rsv = &root->fs_info->global_block_rsv; + global_rsv = &fs_info->global_block_rsv; /* * If we can't allocate any more chunks lets make sure we have _lots_ of @@ -2815,9 +2803,8 @@ int btrfs_check_space_for_delayed_refs(struct btrfs_trans_handle *trans, } int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans, - struct btrfs_root *root) + struct btrfs_fs_info *fs_info) { - struct btrfs_fs_info *fs_info = root->fs_info; u64 num_entries = atomic_read(&trans->transaction->delayed_refs.num_entries); u64 avg_runtime; @@ -2826,12 +2813,12 @@ int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans, smp_mb(); avg_runtime = fs_info->avg_delayed_ref_runtime; val = num_entries * avg_runtime; - if (num_entries * avg_runtime >= NSEC_PER_SEC) + if (val >= NSEC_PER_SEC) return 1; if (val >= NSEC_PER_SEC / 2) return 2; - return btrfs_check_space_for_delayed_refs(trans, root); + return btrfs_check_space_for_delayed_refs(trans, fs_info); } struct async_delayed_refs { @@ -2844,16 +2831,21 @@ struct async_delayed_refs { struct btrfs_work work; }; +static inline struct async_delayed_refs * +to_async_delayed_refs(struct btrfs_work *work) +{ + return container_of(work, struct async_delayed_refs, work); +} + static void delayed_ref_async_start(struct btrfs_work *work) { - struct async_delayed_refs *async; + struct async_delayed_refs *async = to_async_delayed_refs(work); struct btrfs_trans_handle *trans; + struct btrfs_fs_info *fs_info = async->root->fs_info; int ret; - async = container_of(work, struct async_delayed_refs, work); - /* if the commit is already started, we don't need to wait here */ - if (btrfs_transaction_blocked(async->root->fs_info)) + if (btrfs_transaction_blocked(fs_info)) goto done; trans = btrfs_join_transaction(async->root); @@ -2872,11 +2864,11 @@ static void delayed_ref_async_start(struct btrfs_work *work) if (trans->transid > async->transid) goto end; - ret = btrfs_run_delayed_refs(trans, async->root, async->count); + ret = btrfs_run_delayed_refs(trans, fs_info, async->count); if (ret) async->error = ret; end: - ret = btrfs_end_transaction(trans, async->root); + ret = btrfs_end_transaction(trans); if (ret && !async->error) async->error = ret; done: @@ -2886,7 +2878,7 @@ done: kfree(async); } -int btrfs_async_run_delayed_refs(struct btrfs_root *root, +int btrfs_async_run_delayed_refs(struct btrfs_fs_info *fs_info, unsigned long count, u64 transid, int wait) { struct async_delayed_refs *async; @@ -2896,7 +2888,7 @@ int btrfs_async_run_delayed_refs(struct btrfs_root *root, if (!async) return -ENOMEM; - async->root = root->fs_info->tree_root; + async->root = fs_info->tree_root; async->count = count; async->error = 0; async->transid = transid; @@ -2909,7 +2901,7 @@ int btrfs_async_run_delayed_refs(struct btrfs_root *root, btrfs_init_work(&async->work, btrfs_extent_refs_helper, delayed_ref_async_start, NULL, NULL); - btrfs_queue_work(root->fs_info->extent_workers, &async->work); + btrfs_queue_work(fs_info->extent_workers, &async->work); if (wait) { wait_for_completion(&async->wait); @@ -2931,7 +2923,7 @@ int btrfs_async_run_delayed_refs(struct btrfs_root *root, * Returns <0 on error and aborts the transaction */ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, - struct btrfs_root *root, unsigned long count) + struct btrfs_fs_info *fs_info, unsigned long count) { struct rb_node *node; struct btrfs_delayed_ref_root *delayed_refs; @@ -2944,12 +2936,9 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, if (trans->aborted) return 0; - if (test_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &root->fs_info->flags)) + if (test_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags)) return 0; - if (root == root->fs_info->extent_root) - root = root->fs_info->tree_root; - delayed_refs = &trans->transaction->delayed_refs; if (count == 0) count = atomic_read(&delayed_refs->num_entries) * 2; @@ -2959,7 +2948,7 @@ again: delayed_refs->run_delayed_start = find_middle(&delayed_refs->root); #endif trans->can_flush_pending_bgs = false; - ret = __btrfs_run_delayed_refs(trans, root, count); + ret = __btrfs_run_delayed_refs(trans, fs_info, count); if (ret < 0) { btrfs_abort_transaction(trans, ret); return ret; @@ -2967,7 +2956,7 @@ again: if (run_all) { if (!list_empty(&trans->new_bgs)) - btrfs_create_pending_block_groups(trans, root); + btrfs_create_pending_block_groups(trans, fs_info); spin_lock(&delayed_refs->lock); node = rb_first(&delayed_refs->href_root); @@ -3012,7 +3001,7 @@ out: } int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, u64 flags, int level, int is_data) { @@ -3029,7 +3018,7 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, extent_op->is_data = is_data ? true : false; extent_op->level = level; - ret = btrfs_add_delayed_extent_op(root->fs_info, trans, bytenr, + ret = btrfs_add_delayed_extent_op(fs_info, trans, bytenr, num_bytes, extent_op); if (ret) btrfs_free_delayed_extent_op(extent_op); @@ -3103,7 +3092,8 @@ static noinline int check_committed_ref(struct btrfs_trans_handle *trans, struct btrfs_path *path, u64 objectid, u64 offset, u64 bytenr) { - struct btrfs_root *extent_root = root->fs_info->extent_root; + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_root *extent_root = fs_info->extent_root; struct extent_buffer *leaf; struct btrfs_extent_data_ref *ref; struct btrfs_extent_inline_ref *iref; @@ -3210,6 +3200,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, struct extent_buffer *buf, int full_backref, int inc) { + struct btrfs_fs_info *fs_info = root->fs_info; u64 bytenr; u64 num_bytes; u64 parent; @@ -3220,11 +3211,12 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, int i; int level; int ret = 0; - int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, + int (*process_func)(struct btrfs_trans_handle *, + struct btrfs_fs_info *, u64, u64, u64, u64, u64, u64); - if (btrfs_is_testing(root->fs_info)) + if (btrfs_is_testing(fs_info)) return 0; ref_root = btrfs_header_owner(buf); @@ -3260,15 +3252,15 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, num_bytes = btrfs_file_extent_disk_num_bytes(buf, fi); key.offset -= btrfs_file_extent_offset(buf, fi); - ret = process_func(trans, root, bytenr, num_bytes, + ret = process_func(trans, fs_info, bytenr, num_bytes, parent, ref_root, key.objectid, key.offset); if (ret) goto fail; } else { bytenr = btrfs_node_blockptr(buf, i); - num_bytes = root->nodesize; - ret = process_func(trans, root, bytenr, num_bytes, + num_bytes = fs_info->nodesize; + ret = process_func(trans, fs_info, bytenr, num_bytes, parent, ref_root, level - 1, 0); if (ret) goto fail; @@ -3292,12 +3284,12 @@ int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, } static int write_one_cache_group(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, struct btrfs_path *path, struct btrfs_block_group_cache *cache) { int ret; - struct btrfs_root *extent_root = root->fs_info->extent_root; + struct btrfs_root *extent_root = fs_info->extent_root; unsigned long bi; struct extent_buffer *leaf; @@ -3319,22 +3311,20 @@ fail: } static struct btrfs_block_group_cache * -next_block_group(struct btrfs_root *root, +next_block_group(struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *cache) { struct rb_node *node; - spin_lock(&root->fs_info->block_group_cache_lock); + spin_lock(&fs_info->block_group_cache_lock); /* If our block group was removed, we need a full search. */ if (RB_EMPTY_NODE(&cache->cache_node)) { const u64 next_bytenr = cache->key.objectid + cache->key.offset; - spin_unlock(&root->fs_info->block_group_cache_lock); + spin_unlock(&fs_info->block_group_cache_lock); btrfs_put_block_group(cache); - cache = btrfs_lookup_first_block_group(root->fs_info, - next_bytenr); - return cache; + cache = btrfs_lookup_first_block_group(fs_info, next_bytenr); return cache; } node = rb_next(&cache->cache_node); btrfs_put_block_group(cache); @@ -3344,7 +3334,7 @@ next_block_group(struct btrfs_root *root, btrfs_get_block_group(cache); } else cache = NULL; - spin_unlock(&root->fs_info->block_group_cache_lock); + spin_unlock(&fs_info->block_group_cache_lock); return cache; } @@ -3352,7 +3342,8 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group, struct btrfs_trans_handle *trans, struct btrfs_path *path) { - struct btrfs_root *root = block_group->fs_info->tree_root; + struct btrfs_fs_info *fs_info = block_group->fs_info; + struct btrfs_root *root = fs_info->tree_root; struct inode *inode = NULL; u64 alloc_hint = 0; int dcs = BTRFS_DC_ERROR; @@ -3425,8 +3416,8 @@ again: WARN_ON(ret); if (i_size_read(inode) > 0) { - ret = btrfs_check_trunc_cache_free_space(root, - &root->fs_info->global_block_rsv); + ret = btrfs_check_trunc_cache_free_space(fs_info, + &fs_info->global_block_rsv); if (ret) goto out_put; @@ -3437,7 +3428,7 @@ again: spin_lock(&block_group->lock); if (block_group->cached != BTRFS_CACHE_FINISHED || - !btrfs_test_opt(root->fs_info, SPACE_CACHE)) { + !btrfs_test_opt(fs_info, SPACE_CACHE)) { /* * don't bother trying to write stuff out _if_ * a) we're not cached, @@ -3506,14 +3497,14 @@ out: } int btrfs_setup_space_cache(struct btrfs_trans_handle *trans, - struct btrfs_root *root) + struct btrfs_fs_info *fs_info) { struct btrfs_block_group_cache *cache, *tmp; struct btrfs_transaction *cur_trans = trans->transaction; struct btrfs_path *path; if (list_empty(&cur_trans->dirty_bgs) || - !btrfs_test_opt(root->fs_info, SPACE_CACHE)) + !btrfs_test_opt(fs_info, SPACE_CACHE)) return 0; path = btrfs_alloc_path(); @@ -3544,7 +3535,7 @@ int btrfs_setup_space_cache(struct btrfs_trans_handle *trans, * we're still allowing others to join the commit. */ int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans, - struct btrfs_root *root) + struct btrfs_fs_info *fs_info) { struct btrfs_block_group_cache *cache; struct btrfs_transaction *cur_trans = trans->transaction; @@ -3569,7 +3560,7 @@ again: * make sure all the block groups on our dirty list actually * exist */ - btrfs_create_pending_block_groups(trans, root); + btrfs_create_pending_block_groups(trans, fs_info); if (!path) { path = btrfs_alloc_path(); @@ -3594,9 +3585,7 @@ again: */ if (!list_empty(&cache->io_list)) { list_del_init(&cache->io_list); - btrfs_wait_cache_io(root, trans, cache, - &cache->io_ctl, path, - cache->key.objectid); + btrfs_wait_cache_io(trans, cache, path); btrfs_put_block_group(cache); } @@ -3619,7 +3608,8 @@ again: if (cache->disk_cache_state == BTRFS_DC_SETUP) { cache->io_ctl.inode = NULL; - ret = btrfs_write_out_cache(root, trans, cache, path); + ret = btrfs_write_out_cache(fs_info, trans, + cache, path); if (ret == 0 && cache->io_ctl.inode) { num_started++; should_put = 0; @@ -3638,7 +3628,8 @@ again: } } if (!ret) { - ret = write_one_cache_group(trans, root, path, cache); + ret = write_one_cache_group(trans, fs_info, + path, cache); /* * Our block group might still be attached to the list * of new block groups in the transaction handle of some @@ -3683,7 +3674,7 @@ again: * go through delayed refs for all the stuff we've just kicked off * and then loop back (just once) */ - ret = btrfs_run_delayed_refs(trans, root, 0); + ret = btrfs_run_delayed_refs(trans, fs_info, 0); if (!ret && loops == 0) { loops++; spin_lock(&cur_trans->dirty_bgs_lock); @@ -3698,7 +3689,7 @@ again: } spin_unlock(&cur_trans->dirty_bgs_lock); } else if (ret < 0) { - btrfs_cleanup_dirty_bgs(cur_trans, root); + btrfs_cleanup_dirty_bgs(cur_trans, fs_info); } btrfs_free_path(path); @@ -3706,7 +3697,7 @@ again: } int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, - struct btrfs_root *root) + struct btrfs_fs_info *fs_info) { struct btrfs_block_group_cache *cache; struct btrfs_transaction *cur_trans = trans->transaction; @@ -3749,9 +3740,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, if (!list_empty(&cache->io_list)) { spin_unlock(&cur_trans->dirty_bgs_lock); list_del_init(&cache->io_list); - btrfs_wait_cache_io(root, trans, cache, - &cache->io_ctl, path, - cache->key.objectid); + btrfs_wait_cache_io(trans, cache, path); btrfs_put_block_group(cache); spin_lock(&cur_trans->dirty_bgs_lock); } @@ -3767,11 +3756,13 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, cache_save_setup(cache, trans, path); if (!ret) - ret = btrfs_run_delayed_refs(trans, root, (unsigned long) -1); + ret = btrfs_run_delayed_refs(trans, fs_info, + (unsigned long) -1); if (!ret && cache->disk_cache_state == BTRFS_DC_SETUP) { cache->io_ctl.inode = NULL; - ret = btrfs_write_out_cache(root, trans, cache, path); + ret = btrfs_write_out_cache(fs_info, trans, + cache, path); if (ret == 0 && cache->io_ctl.inode) { num_started++; should_put = 0; @@ -3785,7 +3776,8 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, } } if (!ret) { - ret = write_one_cache_group(trans, root, path, cache); + ret = write_one_cache_group(trans, fs_info, + path, cache); /* * One of the free space endio workers might have * created a new block group while updating a free space @@ -3802,8 +3794,8 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, if (ret == -ENOENT) { wait_event(cur_trans->writer_wait, atomic_read(&cur_trans->num_writers) == 1); - ret = write_one_cache_group(trans, root, path, - cache); + ret = write_one_cache_group(trans, fs_info, + path, cache); } if (ret) btrfs_abort_transaction(trans, ret); @@ -3820,8 +3812,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, cache = list_first_entry(io, struct btrfs_block_group_cache, io_list); list_del_init(&cache->io_list); - btrfs_wait_cache_io(root, trans, cache, - &cache->io_ctl, path, cache->key.objectid); + btrfs_wait_cache_io(trans, cache, path); btrfs_put_block_group(cache); } @@ -3829,12 +3820,12 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, return ret; } -int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr) +int btrfs_extent_readonly(struct btrfs_fs_info *fs_info, u64 bytenr) { struct btrfs_block_group_cache *block_group; int readonly = 0; - block_group = btrfs_lookup_block_group(root->fs_info, bytenr); + block_group = btrfs_lookup_block_group(fs_info, bytenr); if (!block_group || block_group->ro) readonly = 1; if (block_group) @@ -4043,9 +4034,9 @@ static u64 get_restripe_target(struct btrfs_fs_info *fs_info, u64 flags) * progress (either running or paused) picks the target profile (if it's * already available), otherwise falls back to plain reducing. */ -static u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) +static u64 btrfs_reduce_alloc_profile(struct btrfs_fs_info *fs_info, u64 flags) { - u64 num_devices = root->fs_info->fs_devices->rw_devices; + u64 num_devices = fs_info->fs_devices->rw_devices; u64 target; u64 raid_type; u64 allowed = 0; @@ -4054,16 +4045,16 @@ static u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) * see if restripe for this chunk_type is in progress, if so * try to reduce to the target profile */ - spin_lock(&root->fs_info->balance_lock); - target = get_restripe_target(root->fs_info, flags); + spin_lock(&fs_info->balance_lock); + target = get_restripe_target(fs_info, flags); if (target) { /* pick target profile only if it's already available */ if ((flags & target) & BTRFS_EXTENDED_PROFILE_MASK) { - spin_unlock(&root->fs_info->balance_lock); + spin_unlock(&fs_info->balance_lock); return extended_to_chunk(target); } } - spin_unlock(&root->fs_info->balance_lock); + spin_unlock(&fs_info->balance_lock); /* First, mask out the RAID levels which aren't possible */ for (raid_type = 0; raid_type < BTRFS_NR_RAID_TYPES; raid_type++) { @@ -4088,39 +4079,40 @@ static u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) return extended_to_chunk(flags | allowed); } -static u64 get_alloc_profile(struct btrfs_root *root, u64 orig_flags) +static u64 get_alloc_profile(struct btrfs_fs_info *fs_info, u64 orig_flags) { unsigned seq; u64 flags; do { flags = orig_flags; - seq = read_seqbegin(&root->fs_info->profiles_lock); + seq = read_seqbegin(&fs_info->profiles_lock); if (flags & BTRFS_BLOCK_GROUP_DATA) - flags |= root->fs_info->avail_data_alloc_bits; + flags |= fs_info->avail_data_alloc_bits; else if (flags & BTRFS_BLOCK_GROUP_SYSTEM) - flags |= root->fs_info->avail_system_alloc_bits; + flags |= fs_info->avail_system_alloc_bits; else if (flags & BTRFS_BLOCK_GROUP_METADATA) - flags |= root->fs_info->avail_metadata_alloc_bits; - } while (read_seqretry(&root->fs_info->profiles_lock, seq)); + flags |= fs_info->avail_metadata_alloc_bits; + } while (read_seqretry(&fs_info->profiles_lock, seq)); - return btrfs_reduce_alloc_profile(root, flags); + return btrfs_reduce_alloc_profile(fs_info, flags); } u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data) { + struct btrfs_fs_info *fs_info = root->fs_info; u64 flags; u64 ret; if (data) flags = BTRFS_BLOCK_GROUP_DATA; - else if (root == root->fs_info->chunk_root) + else if (root == fs_info->chunk_root) flags = BTRFS_BLOCK_GROUP_SYSTEM; else flags = BTRFS_BLOCK_GROUP_METADATA; - ret = get_alloc_profile(root, flags); + ret = get_alloc_profile(fs_info, flags); return ret; } @@ -4135,7 +4127,7 @@ int btrfs_alloc_data_chunk_ondemand(struct inode *inode, u64 bytes) int have_pinned_space; /* make sure bytes are sectorsize aligned */ - bytes = ALIGN(bytes, root->sectorsize); + bytes = ALIGN(bytes, fs_info->sectorsize); if (btrfs_is_free_space_inode(inode)) { need_commit = 0; @@ -4181,10 +4173,9 @@ alloc: if (IS_ERR(trans)) return PTR_ERR(trans); - ret = do_chunk_alloc(trans, root->fs_info->extent_root, - alloc_target, + ret = do_chunk_alloc(trans, fs_info, alloc_target, CHUNK_ALLOC_NO_FORCE); - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); if (ret < 0) { if (ret != -ENOSPC) return ret; @@ -4213,12 +4204,13 @@ alloc: /* commit the current transaction and try again */ commit_trans: if (need_commit && - !atomic_read(&root->fs_info->open_ioctl_trans)) { + !atomic_read(&fs_info->open_ioctl_trans)) { need_commit--; if (need_commit > 0) { btrfs_start_delalloc_roots(fs_info, 0, -1); - btrfs_wait_ordered_roots(fs_info, -1, 0, (u64)-1); + btrfs_wait_ordered_roots(fs_info, -1, 0, + (u64)-1); } trans = btrfs_join_transaction(root); @@ -4228,7 +4220,7 @@ commit_trans: test_bit(BTRFS_TRANS_HAVE_FREE_BGS, &trans->transaction->flags) || need_commit > 0) { - ret = btrfs_commit_transaction(trans, root); + ret = btrfs_commit_transaction(trans); if (ret) return ret; /* @@ -4236,21 +4228,21 @@ commit_trans: * operations. Wait for it to finish so that * more space is released. */ - mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex); - mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex); + mutex_lock(&fs_info->cleaner_delayed_iput_mutex); + mutex_unlock(&fs_info->cleaner_delayed_iput_mutex); goto again; } else { - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); } } - trace_btrfs_space_reservation(root->fs_info, + trace_btrfs_space_reservation(fs_info, "space_info:enospc", data_sinfo->flags, bytes, 1); return -ENOSPC; } data_sinfo->bytes_may_use += bytes; - trace_btrfs_space_reservation(root->fs_info, "space_info", + trace_btrfs_space_reservation(fs_info, "space_info", data_sinfo->flags, bytes, 1); spin_unlock(&data_sinfo->lock); @@ -4264,13 +4256,13 @@ commit_trans: */ int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len) { - struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); int ret; /* align the range */ - len = round_up(start + len, root->sectorsize) - - round_down(start, root->sectorsize); - start = round_down(start, root->sectorsize); + len = round_up(start + len, fs_info->sectorsize) - + round_down(start, fs_info->sectorsize); + start = round_down(start, fs_info->sectorsize); ret = btrfs_alloc_data_chunk_ondemand(inode, len); if (ret < 0) @@ -4294,21 +4286,21 @@ int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len) void btrfs_free_reserved_data_space_noquota(struct inode *inode, u64 start, u64 len) { - struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_space_info *data_sinfo; /* Make sure the range is aligned to sectorsize */ - len = round_up(start + len, root->sectorsize) - - round_down(start, root->sectorsize); - start = round_down(start, root->sectorsize); + len = round_up(start + len, fs_info->sectorsize) - + round_down(start, fs_info->sectorsize); + start = round_down(start, fs_info->sectorsize); - data_sinfo = root->fs_info->data_sinfo; + data_sinfo = fs_info->data_sinfo; spin_lock(&data_sinfo->lock); if (WARN_ON(data_sinfo->bytes_may_use < len)) data_sinfo->bytes_may_use = 0; else data_sinfo->bytes_may_use -= len; - trace_btrfs_space_reservation(root->fs_info, "space_info", + trace_btrfs_space_reservation(fs_info, "space_info", data_sinfo->flags, len, 0); spin_unlock(&data_sinfo->lock); } @@ -4322,6 +4314,13 @@ void btrfs_free_reserved_data_space_noquota(struct inode *inode, u64 start, */ void btrfs_free_reserved_data_space(struct inode *inode, u64 start, u64 len) { + struct btrfs_root *root = BTRFS_I(inode)->root; + + /* Make sure the range is aligned to sectorsize */ + len = round_up(start + len, root->fs_info->sectorsize) - + round_down(start, root->fs_info->sectorsize); + start = round_down(start, root->fs_info->sectorsize); + btrfs_free_reserved_data_space_noquota(inode, start, len); btrfs_qgroup_free_data(inode, start, len); } @@ -4344,10 +4343,10 @@ static inline u64 calc_global_rsv_need_space(struct btrfs_block_rsv *global) return (global->size << 1); } -static int should_alloc_chunk(struct btrfs_root *root, +static int should_alloc_chunk(struct btrfs_fs_info *fs_info, struct btrfs_space_info *sinfo, int force) { - struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv; + struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly; u64 num_allocated = sinfo->bytes_used + sinfo->bytes_reserved; u64 thresh; @@ -4368,7 +4367,7 @@ static int should_alloc_chunk(struct btrfs_root *root, * about 1% of the FS size. */ if (force == CHUNK_ALLOC_LIMITED) { - thresh = btrfs_super_total_bytes(root->fs_info->super_copy); + thresh = btrfs_super_total_bytes(fs_info->super_copy); thresh = max_t(u64, SZ_64M, div_factor_fine(thresh, 1)); if (num_bytes - num_allocated < thresh) @@ -4380,7 +4379,7 @@ static int should_alloc_chunk(struct btrfs_root *root, return 1; } -static u64 get_profile_num_devs(struct btrfs_root *root, u64 type) +static u64 get_profile_num_devs(struct btrfs_fs_info *fs_info, u64 type) { u64 num_dev; @@ -4388,7 +4387,7 @@ static u64 get_profile_num_devs(struct btrfs_root *root, u64 type) BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6)) - num_dev = root->fs_info->fs_devices->rw_devices; + num_dev = fs_info->fs_devices->rw_devices; else if (type & BTRFS_BLOCK_GROUP_RAID1) num_dev = 2; else @@ -4403,8 +4402,7 @@ static u64 get_profile_num_devs(struct btrfs_root *root, u64 type) * removing a chunk. */ void check_system_chunk(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - u64 type) + struct btrfs_fs_info *fs_info, u64 type) { struct btrfs_space_info *info; u64 left; @@ -4416,43 +4414,43 @@ void check_system_chunk(struct btrfs_trans_handle *trans, * Needed because we can end up allocating a system chunk and for an * atomic and race free space reservation in the chunk block reserve. */ - ASSERT(mutex_is_locked(&root->fs_info->chunk_mutex)); + ASSERT(mutex_is_locked(&fs_info->chunk_mutex)); - info = __find_space_info(root->fs_info, BTRFS_BLOCK_GROUP_SYSTEM); + info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM); spin_lock(&info->lock); left = info->total_bytes - info->bytes_used - info->bytes_pinned - info->bytes_reserved - info->bytes_readonly - info->bytes_may_use; spin_unlock(&info->lock); - num_devs = get_profile_num_devs(root, type); + num_devs = get_profile_num_devs(fs_info, type); /* num_devs device items to update and 1 chunk item to add or remove */ - thresh = btrfs_calc_trunc_metadata_size(root, num_devs) + - btrfs_calc_trans_metadata_size(root, 1); + thresh = btrfs_calc_trunc_metadata_size(fs_info, num_devs) + + btrfs_calc_trans_metadata_size(fs_info, 1); - if (left < thresh && btrfs_test_opt(root->fs_info, ENOSPC_DEBUG)) { - btrfs_info(root->fs_info, "left=%llu, need=%llu, flags=%llu", - left, thresh, type); - dump_space_info(root->fs_info, info, 0, 0); + if (left < thresh && btrfs_test_opt(fs_info, ENOSPC_DEBUG)) { + btrfs_info(fs_info, "left=%llu, need=%llu, flags=%llu", + left, thresh, type); + dump_space_info(fs_info, info, 0, 0); } if (left < thresh) { u64 flags; - flags = btrfs_get_alloc_profile(root->fs_info->chunk_root, 0); + flags = btrfs_get_alloc_profile(fs_info->chunk_root, 0); /* * Ignore failure to create system chunk. We might end up not * needing it, as we might not need to COW all nodes/leafs from * the paths we visit in the chunk tree (they were already COWed * or created in the current transaction for example). */ - ret = btrfs_alloc_chunk(trans, root, flags); + ret = btrfs_alloc_chunk(trans, fs_info, flags); } if (!ret) { - ret = btrfs_block_rsv_add(root->fs_info->chunk_root, - &root->fs_info->chunk_block_rsv, + ret = btrfs_block_rsv_add(fs_info->chunk_root, + &fs_info->chunk_block_rsv, thresh, BTRFS_RESERVE_NO_FLUSH); if (!ret) trans->chunk_bytes_reserved += thresh; @@ -4469,10 +4467,9 @@ void check_system_chunk(struct btrfs_trans_handle *trans, * - return errors including -ENOSPC otherwise. */ static int do_chunk_alloc(struct btrfs_trans_handle *trans, - struct btrfs_root *extent_root, u64 flags, int force) + struct btrfs_fs_info *fs_info, u64 flags, int force) { struct btrfs_space_info *space_info; - struct btrfs_fs_info *fs_info = extent_root->fs_info; int wait_for_alloc = 0; int ret = 0; @@ -4480,10 +4477,9 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, if (trans->allocating_chunk) return -ENOSPC; - space_info = __find_space_info(extent_root->fs_info, flags); + space_info = __find_space_info(fs_info, flags); if (!space_info) { - ret = update_space_info(extent_root->fs_info, flags, - 0, 0, 0, &space_info); + ret = update_space_info(fs_info, flags, 0, 0, 0, &space_info); BUG_ON(ret); /* -ENOMEM */ } BUG_ON(!space_info); /* Logic error */ @@ -4493,7 +4489,7 @@ again: if (force < space_info->force_alloc) force = space_info->force_alloc; if (space_info->full) { - if (should_alloc_chunk(extent_root, space_info, force)) + if (should_alloc_chunk(fs_info, space_info, force)) ret = -ENOSPC; else ret = 0; @@ -4501,7 +4497,7 @@ again: return ret; } - if (!should_alloc_chunk(extent_root, space_info, force)) { + if (!should_alloc_chunk(fs_info, space_info, force)) { spin_unlock(&space_info->lock); return 0; } else if (space_info->chunk_alloc) { @@ -4551,9 +4547,9 @@ again: * Check if we have enough space in SYSTEM chunk because we may need * to update devices. */ - check_system_chunk(trans, extent_root, flags); + check_system_chunk(trans, fs_info, flags); - ret = btrfs_alloc_chunk(trans, extent_root, flags); + ret = btrfs_alloc_chunk(trans, fs_info, flags); trans->allocating_chunk = false; spin_lock(&space_info->lock); @@ -4585,7 +4581,7 @@ out: */ if (trans->can_flush_pending_bgs && trans->chunk_bytes_reserved >= (u64)SZ_2M) { - btrfs_create_pending_block_groups(trans, extent_root); + btrfs_create_pending_block_groups(trans, fs_info); btrfs_trans_release_chunk_metadata(trans); } return ret; @@ -4595,7 +4591,8 @@ static int can_overcommit(struct btrfs_root *root, struct btrfs_space_info *space_info, u64 bytes, enum btrfs_reserve_flush_enum flush) { - struct btrfs_block_rsv *global_rsv; + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; u64 profile; u64 space_size; u64 avail; @@ -4605,8 +4602,6 @@ static int can_overcommit(struct btrfs_root *root, if (space_info->flags & BTRFS_BLOCK_GROUP_DATA) return 0; - BUG_ON(root->fs_info == NULL); - global_rsv = &root->fs_info->global_block_rsv; profile = btrfs_get_alloc_profile(root, 0); used = space_info->bytes_used + space_info->bytes_reserved + space_info->bytes_pinned + space_info->bytes_readonly; @@ -4625,9 +4620,9 @@ static int can_overcommit(struct btrfs_root *root, used += space_info->bytes_may_use; - spin_lock(&root->fs_info->free_chunk_lock); - avail = root->fs_info->free_chunk_space; - spin_unlock(&root->fs_info->free_chunk_lock); + spin_lock(&fs_info->free_chunk_lock); + avail = fs_info->free_chunk_space; + spin_unlock(&fs_info->free_chunk_lock); /* * If we have dup, raid1 or raid10 then only half of the free @@ -4655,10 +4650,10 @@ static int can_overcommit(struct btrfs_root *root, return 0; } -static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root, +static void btrfs_writeback_inodes_sb_nr(struct btrfs_fs_info *fs_info, unsigned long nr_pages, int nr_items) { - struct super_block *sb = root->fs_info->sb; + struct super_block *sb = fs_info->sb; if (down_read_trylock(&sb->s_umount)) { writeback_inodes_sb_nr(sb, nr_pages, WB_REASON_FS_FREE_SPACE); @@ -4671,19 +4666,19 @@ static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root, * the filesystem is readonly(all dirty pages are written to * the disk). */ - btrfs_start_delalloc_roots(root->fs_info, 0, nr_items); + btrfs_start_delalloc_roots(fs_info, 0, nr_items); if (!current->journal_info) - btrfs_wait_ordered_roots(root->fs_info, nr_items, - 0, (u64)-1); + btrfs_wait_ordered_roots(fs_info, nr_items, 0, (u64)-1); } } -static inline int calc_reclaim_items_nr(struct btrfs_root *root, u64 to_reclaim) +static inline int calc_reclaim_items_nr(struct btrfs_fs_info *fs_info, + u64 to_reclaim) { u64 bytes; int nr; - bytes = btrfs_calc_trans_metadata_size(root, 1); + bytes = btrfs_calc_trans_metadata_size(fs_info, 1); nr = (int)div64_u64(to_reclaim, bytes); if (!nr) nr = 1; @@ -4698,6 +4693,7 @@ static inline int calc_reclaim_items_nr(struct btrfs_root *root, u64 to_reclaim) static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, bool wait_ordered) { + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_block_rsv *block_rsv; struct btrfs_space_info *space_info; struct btrfs_trans_handle *trans; @@ -4710,21 +4706,20 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, enum btrfs_reserve_flush_enum flush; /* Calc the number of the pages we need flush for space reservation */ - items = calc_reclaim_items_nr(root, to_reclaim); + items = calc_reclaim_items_nr(fs_info, to_reclaim); to_reclaim = (u64)items * EXTENT_SIZE_PER_ITEM; trans = (struct btrfs_trans_handle *)current->journal_info; - block_rsv = &root->fs_info->delalloc_block_rsv; + block_rsv = &fs_info->delalloc_block_rsv; space_info = block_rsv->space_info; delalloc_bytes = percpu_counter_sum_positive( - &root->fs_info->delalloc_bytes); + &fs_info->delalloc_bytes); if (delalloc_bytes == 0) { if (trans) return; if (wait_ordered) - btrfs_wait_ordered_roots(root->fs_info, items, - 0, (u64)-1); + btrfs_wait_ordered_roots(fs_info, items, 0, (u64)-1); return; } @@ -4732,12 +4727,12 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, while (delalloc_bytes && loops < 3) { max_reclaim = min(delalloc_bytes, to_reclaim); nr_pages = max_reclaim >> PAGE_SHIFT; - btrfs_writeback_inodes_sb_nr(root, nr_pages, items); + btrfs_writeback_inodes_sb_nr(fs_info, nr_pages, items); /* * We need to wait for the async pages to actually start before * we do anything. */ - max_reclaim = atomic_read(&root->fs_info->async_delalloc_pages); + max_reclaim = atomic_read(&fs_info->async_delalloc_pages); if (!max_reclaim) goto skip_async; @@ -4746,8 +4741,8 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, else max_reclaim -= nr_pages; - wait_event(root->fs_info->async_submit_wait, - atomic_read(&root->fs_info->async_delalloc_pages) <= + wait_event(fs_info->async_submit_wait, + atomic_read(&fs_info->async_delalloc_pages) <= (int)max_reclaim); skip_async: if (!trans) @@ -4768,15 +4763,14 @@ skip_async: loops++; if (wait_ordered && !trans) { - btrfs_wait_ordered_roots(root->fs_info, items, - 0, (u64)-1); + btrfs_wait_ordered_roots(fs_info, items, 0, (u64)-1); } else { time_left = schedule_timeout_killable(1); if (time_left) break; } delalloc_bytes = percpu_counter_sum_positive( - &root->fs_info->delalloc_bytes); + &fs_info->delalloc_bytes); } } @@ -4794,7 +4788,8 @@ static int may_commit_transaction(struct btrfs_root *root, struct btrfs_space_info *space_info, u64 bytes, int force) { - struct btrfs_block_rsv *delayed_rsv = &root->fs_info->delayed_block_rsv; + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_block_rsv *delayed_rsv = &fs_info->delayed_block_rsv; struct btrfs_trans_handle *trans; trans = (struct btrfs_trans_handle *)current->journal_info; @@ -4829,7 +4824,7 @@ commit: if (IS_ERR(trans)) return -ENOSPC; - return btrfs_commit_transaction(trans, root); + return btrfs_commit_transaction(trans); } struct reserve_ticket { @@ -4843,6 +4838,7 @@ static int flush_space(struct btrfs_root *root, struct btrfs_space_info *space_info, u64 num_bytes, u64 orig_bytes, int state) { + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_trans_handle *trans; int nr; int ret = 0; @@ -4851,7 +4847,7 @@ static int flush_space(struct btrfs_root *root, case FLUSH_DELAYED_ITEMS_NR: case FLUSH_DELAYED_ITEMS: if (state == FLUSH_DELAYED_ITEMS_NR) - nr = calc_reclaim_items_nr(root, num_bytes) * 2; + nr = calc_reclaim_items_nr(fs_info, num_bytes) * 2; else nr = -1; @@ -4860,8 +4856,8 @@ static int flush_space(struct btrfs_root *root, ret = PTR_ERR(trans); break; } - ret = btrfs_run_delayed_items_nr(trans, root, nr); - btrfs_end_transaction(trans, root); + ret = btrfs_run_delayed_items_nr(trans, fs_info, nr); + btrfs_end_transaction(trans); break; case FLUSH_DELALLOC: case FLUSH_DELALLOC_WAIT: @@ -4874,10 +4870,10 @@ static int flush_space(struct btrfs_root *root, ret = PTR_ERR(trans); break; } - ret = do_chunk_alloc(trans, root->fs_info->extent_root, + ret = do_chunk_alloc(trans, fs_info, btrfs_get_alloc_profile(root, 0), CHUNK_ALLOC_NO_FORCE); - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); if (ret > 0 || ret == -ENOSPC) ret = 0; break; @@ -4889,7 +4885,7 @@ static int flush_space(struct btrfs_root *root, break; } - trace_btrfs_flush_space(root->fs_info, space_info->flags, num_bytes, + trace_btrfs_flush_space(fs_info, space_info->flags, num_bytes, orig_bytes, state, ret); return ret; } @@ -4935,6 +4931,7 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_root *root, static inline int need_do_async_reclaim(struct btrfs_space_info *space_info, struct btrfs_root *root, u64 used) { + struct btrfs_fs_info *fs_info = root->fs_info; u64 thresh = div_factor_fine(space_info->total_bytes, 98); /* If we're just plain full then async reclaim just slows us down. */ @@ -4944,9 +4941,8 @@ static inline int need_do_async_reclaim(struct btrfs_space_info *space_info, if (!btrfs_calc_reclaim_metadata_size(root, space_info)) return 0; - return (used >= thresh && !btrfs_fs_closing(root->fs_info) && - !test_bit(BTRFS_FS_STATE_REMOUNTING, - &root->fs_info->fs_state)); + return (used >= thresh && !btrfs_fs_closing(fs_info) && + !test_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state)); } static void wake_all_tickets(struct list_head *head) @@ -5126,6 +5122,7 @@ static int __reserve_metadata_bytes(struct btrfs_root *root, u64 orig_bytes, enum btrfs_reserve_flush_enum flush) { + struct btrfs_fs_info *fs_info = root->fs_info; struct reserve_ticket ticket; u64 used; int ret = 0; @@ -5146,15 +5143,13 @@ static int __reserve_metadata_bytes(struct btrfs_root *root, */ if (used + orig_bytes <= space_info->total_bytes) { space_info->bytes_may_use += orig_bytes; - trace_btrfs_space_reservation(root->fs_info, "space_info", - space_info->flags, orig_bytes, - 1); + trace_btrfs_space_reservation(fs_info, "space_info", + space_info->flags, orig_bytes, 1); ret = 0; } else if (can_overcommit(root, space_info, orig_bytes, flush)) { space_info->bytes_may_use += orig_bytes; - trace_btrfs_space_reservation(root->fs_info, "space_info", - space_info->flags, orig_bytes, - 1); + trace_btrfs_space_reservation(fs_info, "space_info", + space_info->flags, orig_bytes, 1); ret = 0; } @@ -5173,7 +5168,7 @@ static int __reserve_metadata_bytes(struct btrfs_root *root, list_add_tail(&ticket.list, &space_info->tickets); if (!space_info->flush) { space_info->flush = 1; - trace_btrfs_trigger_flush(root->fs_info, + trace_btrfs_trigger_flush(fs_info, space_info->flags, orig_bytes, flush, "enospc"); @@ -5191,15 +5186,13 @@ static int __reserve_metadata_bytes(struct btrfs_root *root, * which means we won't have fs_info->fs_root set, so don't do * the async reclaim as we will panic. */ - if (!test_bit(BTRFS_FS_LOG_RECOVERING, &root->fs_info->flags) && + if (!test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags) && need_do_async_reclaim(space_info, root, used) && - !work_busy(&root->fs_info->async_reclaim_work)) { - trace_btrfs_trigger_flush(root->fs_info, - space_info->flags, - orig_bytes, flush, - "preempt"); + !work_busy(&fs_info->async_reclaim_work)) { + trace_btrfs_trigger_flush(fs_info, space_info->flags, + orig_bytes, flush, "preempt"); queue_work(system_unbound_wq, - &root->fs_info->async_reclaim_work); + &fs_info->async_reclaim_work); } } spin_unlock(&space_info->lock); @@ -5207,19 +5200,19 @@ static int __reserve_metadata_bytes(struct btrfs_root *root, return ret; if (flush == BTRFS_RESERVE_FLUSH_ALL) - return wait_reserve_ticket(root->fs_info, space_info, &ticket, + return wait_reserve_ticket(fs_info, space_info, &ticket, orig_bytes); ret = 0; - priority_reclaim_metadata_space(root->fs_info, space_info, &ticket); + priority_reclaim_metadata_space(fs_info, space_info, &ticket); spin_lock(&space_info->lock); if (ticket.bytes) { if (ticket.bytes < orig_bytes) { u64 num_bytes = orig_bytes - ticket.bytes; space_info->bytes_may_use -= num_bytes; - trace_btrfs_space_reservation(root->fs_info, - "space_info", space_info->flags, - num_bytes, 0); + trace_btrfs_space_reservation(fs_info, "space_info", + space_info->flags, + num_bytes, 0); } list_del_init(&ticket.list); @@ -5249,22 +5242,20 @@ static int reserve_metadata_bytes(struct btrfs_root *root, u64 orig_bytes, enum btrfs_reserve_flush_enum flush) { + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; int ret; ret = __reserve_metadata_bytes(root, block_rsv->space_info, orig_bytes, flush); if (ret == -ENOSPC && unlikely(root->orphan_cleanup_state == ORPHAN_CLEANUP_STARTED)) { - struct btrfs_block_rsv *global_rsv = - &root->fs_info->global_block_rsv; - if (block_rsv != global_rsv && !block_rsv_use_bytes(global_rsv, orig_bytes)) ret = 0; } if (ret == -ENOSPC) - trace_btrfs_space_reservation(root->fs_info, - "space_info:enospc", + trace_btrfs_space_reservation(fs_info, "space_info:enospc", block_rsv->space_info->flags, orig_bytes, 1); return ret; @@ -5274,18 +5265,19 @@ static struct btrfs_block_rsv *get_block_rsv( const struct btrfs_trans_handle *trans, const struct btrfs_root *root) { + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_block_rsv *block_rsv = NULL; if (test_bit(BTRFS_ROOT_REF_COWS, &root->state) || - (root == root->fs_info->csum_root && trans->adding_csums) || - (root == root->fs_info->uuid_root)) + (root == fs_info->csum_root && trans->adding_csums) || + (root == fs_info->uuid_root)) block_rsv = trans->block_rsv; if (!block_rsv) block_rsv = root->block_rsv; if (!block_rsv) - block_rsv = &root->fs_info->empty_block_rsv; + block_rsv = &fs_info->empty_block_rsv; return block_rsv; } @@ -5507,11 +5499,10 @@ void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, unsigned short type) rsv->type = type; } -struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root, +struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_fs_info *fs_info, unsigned short type) { struct btrfs_block_rsv *block_rsv; - struct btrfs_fs_info *fs_info = root->fs_info; block_rsv = kmalloc(sizeof(*block_rsv), GFP_NOFS); if (!block_rsv) @@ -5523,12 +5514,12 @@ struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root, return block_rsv; } -void btrfs_free_block_rsv(struct btrfs_root *root, +void btrfs_free_block_rsv(struct btrfs_fs_info *fs_info, struct btrfs_block_rsv *rsv) { if (!rsv) return; - btrfs_block_rsv_release(root, rsv, (u64)-1); + btrfs_block_rsv_release(fs_info, rsv, (u64)-1); kfree(rsv); } @@ -5555,8 +5546,7 @@ int btrfs_block_rsv_add(struct btrfs_root *root, return ret; } -int btrfs_block_rsv_check(struct btrfs_root *root, - struct btrfs_block_rsv *block_rsv, int min_factor) +int btrfs_block_rsv_check(struct btrfs_block_rsv *block_rsv, int min_factor) { u64 num_bytes = 0; int ret = -ENOSPC; @@ -5603,16 +5593,16 @@ int btrfs_block_rsv_refill(struct btrfs_root *root, return ret; } -void btrfs_block_rsv_release(struct btrfs_root *root, +void btrfs_block_rsv_release(struct btrfs_fs_info *fs_info, struct btrfs_block_rsv *block_rsv, u64 num_bytes) { - struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv; + struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; + if (global_rsv == block_rsv || block_rsv->space_info != global_rsv->space_info) global_rsv = NULL; - block_rsv_release_bytes(root->fs_info, block_rsv, global_rsv, - num_bytes); + block_rsv_release_bytes(fs_info, block_rsv, global_rsv, num_bytes); } static void update_global_block_rsv(struct btrfs_fs_info *fs_info) @@ -5707,7 +5697,7 @@ static void release_global_block_rsv(struct btrfs_fs_info *fs_info) } void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, - struct btrfs_root *root) + struct btrfs_fs_info *fs_info) { if (!trans->block_rsv) return; @@ -5715,9 +5705,10 @@ void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, if (!trans->bytes_reserved) return; - trace_btrfs_space_reservation(root->fs_info, "transaction", + trace_btrfs_space_reservation(fs_info, "transaction", trans->transid, trans->bytes_reserved, 0); - btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved); + btrfs_block_rsv_release(fs_info, trans->block_rsv, + trans->bytes_reserved); trans->bytes_reserved = 0; } @@ -5743,6 +5734,7 @@ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans) int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans, struct inode *inode) { + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; /* * We always use trans->block_rsv here as we will have reserved space @@ -5758,19 +5750,22 @@ int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans, * added it, so this takes the reservation so we can release it later * when we are truly done with the orphan item. */ - u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1); - trace_btrfs_space_reservation(root->fs_info, "orphan", + u64 num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1); + + trace_btrfs_space_reservation(fs_info, "orphan", btrfs_ino(inode), num_bytes, 1); return btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1); } void btrfs_orphan_release_metadata(struct inode *inode) { + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; - u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1); - trace_btrfs_space_reservation(root->fs_info, "orphan", + u64 num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1); + + trace_btrfs_space_reservation(fs_info, "orphan", btrfs_ino(inode), num_bytes, 0); - btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes); + btrfs_block_rsv_release(fs_info, root->orphan_block_rsv, num_bytes); } /* @@ -5795,11 +5790,12 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, { u64 num_bytes; int ret; - struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv; + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; - if (test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags)) { + if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) { /* One for parent inode, two for dir entries */ - num_bytes = 3 * root->nodesize; + num_bytes = 3 * fs_info->nodesize; ret = btrfs_qgroup_reserve_meta(root, num_bytes); if (ret) return ret; @@ -5809,8 +5805,8 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, *qgroup_reserved = num_bytes; - num_bytes = btrfs_calc_trans_metadata_size(root, items); - rsv->space_info = __find_space_info(root->fs_info, + num_bytes = btrfs_calc_trans_metadata_size(fs_info, items); + rsv->space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA); ret = btrfs_block_rsv_add(root, rsv, num_bytes, BTRFS_RESERVE_FLUSH_ALL); @@ -5824,11 +5820,11 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, return ret; } -void btrfs_subvolume_release_metadata(struct btrfs_root *root, +void btrfs_subvolume_release_metadata(struct btrfs_fs_info *fs_info, struct btrfs_block_rsv *rsv, u64 qgroup_reserved) { - btrfs_block_rsv_release(root, rsv, (u64)-1); + btrfs_block_rsv_release(fs_info, rsv, (u64)-1); } /** @@ -5894,35 +5890,38 @@ static unsigned drop_outstanding_extent(struct inode *inode, u64 num_bytes) static u64 calc_csum_metadata_size(struct inode *inode, u64 num_bytes, int reserve) { - struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); u64 old_csums, num_csums; if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM && BTRFS_I(inode)->csum_bytes == 0) return 0; - old_csums = btrfs_csum_bytes_to_leaves(root, BTRFS_I(inode)->csum_bytes); + old_csums = btrfs_csum_bytes_to_leaves(fs_info, + BTRFS_I(inode)->csum_bytes); if (reserve) BTRFS_I(inode)->csum_bytes += num_bytes; else BTRFS_I(inode)->csum_bytes -= num_bytes; - num_csums = btrfs_csum_bytes_to_leaves(root, BTRFS_I(inode)->csum_bytes); + num_csums = btrfs_csum_bytes_to_leaves(fs_info, + BTRFS_I(inode)->csum_bytes); /* No change, no need to reserve more */ if (old_csums == num_csums) return 0; if (reserve) - return btrfs_calc_trans_metadata_size(root, + return btrfs_calc_trans_metadata_size(fs_info, num_csums - old_csums); - return btrfs_calc_trans_metadata_size(root, old_csums - num_csums); + return btrfs_calc_trans_metadata_size(fs_info, old_csums - num_csums); } int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) { + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; - struct btrfs_block_rsv *block_rsv = &root->fs_info->delalloc_block_rsv; + struct btrfs_block_rsv *block_rsv = &fs_info->delalloc_block_rsv; u64 to_reserve = 0; u64 csum_bytes; unsigned nr_extents = 0; @@ -5949,13 +5948,13 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) } if (flush != BTRFS_RESERVE_NO_FLUSH && - btrfs_transaction_in_commit(root->fs_info)) + btrfs_transaction_in_commit(fs_info)) schedule_timeout(1); if (delalloc_lock) mutex_lock(&BTRFS_I(inode)->delalloc_mutex); - num_bytes = ALIGN(num_bytes, root->sectorsize); + num_bytes = ALIGN(num_bytes, fs_info->sectorsize); spin_lock(&BTRFS_I(inode)->lock); nr_extents = (unsigned)div64_u64(num_bytes + @@ -5970,28 +5969,29 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) BTRFS_I(inode)->reserved_extents; /* We always want to reserve a slot for updating the inode. */ - to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents + 1); + to_reserve = btrfs_calc_trans_metadata_size(fs_info, nr_extents + 1); to_reserve += calc_csum_metadata_size(inode, num_bytes, 1); csum_bytes = BTRFS_I(inode)->csum_bytes; spin_unlock(&BTRFS_I(inode)->lock); - if (test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags)) { + if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) { ret = btrfs_qgroup_reserve_meta(root, - nr_extents * root->nodesize); + nr_extents * fs_info->nodesize); if (ret) goto out_fail; } ret = btrfs_block_rsv_add(root, block_rsv, to_reserve, flush); if (unlikely(ret)) { - btrfs_qgroup_free_meta(root, nr_extents * root->nodesize); + btrfs_qgroup_free_meta(root, + nr_extents * fs_info->nodesize); goto out_fail; } spin_lock(&BTRFS_I(inode)->lock); if (test_and_set_bit(BTRFS_INODE_DELALLOC_META_RESERVED, &BTRFS_I(inode)->runtime_flags)) { - to_reserve -= btrfs_calc_trans_metadata_size(root, 1); + to_reserve -= btrfs_calc_trans_metadata_size(fs_info, 1); release_extra = true; } BTRFS_I(inode)->reserved_extents += nr_extents; @@ -6001,12 +6001,11 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); if (to_reserve) - trace_btrfs_space_reservation(root->fs_info, "delalloc", + trace_btrfs_space_reservation(fs_info, "delalloc", btrfs_ino(inode), to_reserve, 1); if (release_extra) - btrfs_block_rsv_release(root, block_rsv, - btrfs_calc_trans_metadata_size(root, - 1)); + btrfs_block_rsv_release(fs_info, block_rsv, + btrfs_calc_trans_metadata_size(fs_info, 1)); return 0; out_fail: @@ -6061,11 +6060,11 @@ out_fail: } spin_unlock(&BTRFS_I(inode)->lock); if (dropped) - to_free += btrfs_calc_trans_metadata_size(root, dropped); + to_free += btrfs_calc_trans_metadata_size(fs_info, dropped); if (to_free) { - btrfs_block_rsv_release(root, block_rsv, to_free); - trace_btrfs_space_reservation(root->fs_info, "delalloc", + btrfs_block_rsv_release(fs_info, block_rsv, to_free); + trace_btrfs_space_reservation(fs_info, "delalloc", btrfs_ino(inode), to_free, 0); } if (delalloc_lock) @@ -6084,11 +6083,11 @@ out_fail: */ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes) { - struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); u64 to_free = 0; unsigned dropped; - num_bytes = ALIGN(num_bytes, root->sectorsize); + num_bytes = ALIGN(num_bytes, fs_info->sectorsize); spin_lock(&BTRFS_I(inode)->lock); dropped = drop_outstanding_extent(inode, num_bytes); @@ -6096,16 +6095,15 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes) to_free = calc_csum_metadata_size(inode, num_bytes, 0); spin_unlock(&BTRFS_I(inode)->lock); if (dropped > 0) - to_free += btrfs_calc_trans_metadata_size(root, dropped); + to_free += btrfs_calc_trans_metadata_size(fs_info, dropped); - if (btrfs_is_testing(root->fs_info)) + if (btrfs_is_testing(fs_info)) return; - trace_btrfs_space_reservation(root->fs_info, "delalloc", + trace_btrfs_space_reservation(fs_info, "delalloc", btrfs_ino(inode), to_free, 0); - btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv, - to_free); + btrfs_block_rsv_release(fs_info, &fs_info->delalloc_block_rsv, to_free); } /** @@ -6166,11 +6164,10 @@ void btrfs_delalloc_release_space(struct inode *inode, u64 start, u64 len) } static int update_block_group(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 bytenr, + struct btrfs_fs_info *info, u64 bytenr, u64 num_bytes, int alloc) { struct btrfs_block_group_cache *cache = NULL; - struct btrfs_fs_info *info = root->fs_info; u64 total = num_bytes; u64 old_val; u64 byte_in_group; @@ -6211,7 +6208,7 @@ static int update_block_group(struct btrfs_trans_handle *trans, spin_lock(&cache->space_info->lock); spin_lock(&cache->lock); - if (btrfs_test_opt(root->fs_info, SPACE_CACHE) && + if (btrfs_test_opt(info, SPACE_CACHE) && cache->disk_cache_state < BTRFS_DC_CLEAR) cache->disk_cache_state = BTRFS_DC_CLEAR; @@ -6236,7 +6233,7 @@ static int update_block_group(struct btrfs_trans_handle *trans, spin_unlock(&cache->lock); spin_unlock(&cache->space_info->lock); - trace_btrfs_space_reservation(root->fs_info, "pinned", + trace_btrfs_space_reservation(info, "pinned", cache->space_info->flags, num_bytes, 1); set_extent_dirty(info->pinned_extents, @@ -6276,19 +6273,19 @@ static int update_block_group(struct btrfs_trans_handle *trans, return 0; } -static u64 first_logical_byte(struct btrfs_root *root, u64 search_start) +static u64 first_logical_byte(struct btrfs_fs_info *fs_info, u64 search_start) { struct btrfs_block_group_cache *cache; u64 bytenr; - spin_lock(&root->fs_info->block_group_cache_lock); - bytenr = root->fs_info->first_logical_byte; - spin_unlock(&root->fs_info->block_group_cache_lock); + spin_lock(&fs_info->block_group_cache_lock); + bytenr = fs_info->first_logical_byte; + spin_unlock(&fs_info->block_group_cache_lock); if (bytenr < (u64)-1) return bytenr; - cache = btrfs_lookup_first_block_group(root->fs_info, search_start); + cache = btrfs_lookup_first_block_group(fs_info, search_start); if (!cache) return 0; @@ -6298,7 +6295,7 @@ static u64 first_logical_byte(struct btrfs_root *root, u64 search_start) return bytenr; } -static int pin_down_extent(struct btrfs_root *root, +static int pin_down_extent(struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *cache, u64 bytenr, u64 num_bytes, int reserved) { @@ -6313,9 +6310,9 @@ static int pin_down_extent(struct btrfs_root *root, spin_unlock(&cache->lock); spin_unlock(&cache->space_info->lock); - trace_btrfs_space_reservation(root->fs_info, "pinned", + trace_btrfs_space_reservation(fs_info, "pinned", cache->space_info->flags, num_bytes, 1); - set_extent_dirty(root->fs_info->pinned_extents, bytenr, + set_extent_dirty(fs_info->pinned_extents, bytenr, bytenr + num_bytes - 1, GFP_NOFS | __GFP_NOFAIL); return 0; } @@ -6323,15 +6320,15 @@ static int pin_down_extent(struct btrfs_root *root, /* * this function must be called within transaction */ -int btrfs_pin_extent(struct btrfs_root *root, +int btrfs_pin_extent(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, int reserved) { struct btrfs_block_group_cache *cache; - cache = btrfs_lookup_block_group(root->fs_info, bytenr); + cache = btrfs_lookup_block_group(fs_info, bytenr); BUG_ON(!cache); /* Logic error */ - pin_down_extent(root, cache, bytenr, num_bytes, reserved); + pin_down_extent(fs_info, cache, bytenr, num_bytes, reserved); btrfs_put_block_group(cache); return 0; @@ -6340,13 +6337,13 @@ int btrfs_pin_extent(struct btrfs_root *root, /* * this function must be called within transaction */ -int btrfs_pin_extent_for_log_replay(struct btrfs_root *root, +int btrfs_pin_extent_for_log_replay(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes) { struct btrfs_block_group_cache *cache; int ret; - cache = btrfs_lookup_block_group(root->fs_info, bytenr); + cache = btrfs_lookup_block_group(fs_info, bytenr); if (!cache) return -EINVAL; @@ -6358,7 +6355,7 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_root *root, */ cache_block_group(cache, 1); - pin_down_extent(root, cache, bytenr, num_bytes, 0); + pin_down_extent(fs_info, cache, bytenr, num_bytes, 0); /* remove us from the free space cache (if we're there at all) */ ret = btrfs_remove_free_space(cache, bytenr, num_bytes); @@ -6366,13 +6363,14 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_root *root, return ret; } -static int __exclude_logged_extent(struct btrfs_root *root, u64 start, u64 num_bytes) +static int __exclude_logged_extent(struct btrfs_fs_info *fs_info, + u64 start, u64 num_bytes) { int ret; struct btrfs_block_group_cache *block_group; struct btrfs_caching_control *caching_ctl; - block_group = btrfs_lookup_block_group(root->fs_info, start); + block_group = btrfs_lookup_block_group(fs_info, start); if (!block_group) return -EINVAL; @@ -6387,7 +6385,7 @@ static int __exclude_logged_extent(struct btrfs_root *root, u64 start, u64 num_b mutex_lock(&caching_ctl->mutex); if (start >= caching_ctl->progress) { - ret = add_excluded_extent(root, start, num_bytes); + ret = add_excluded_extent(fs_info, start, num_bytes); } else if (start + num_bytes <= caching_ctl->progress) { ret = btrfs_remove_free_space(block_group, start, num_bytes); @@ -6401,7 +6399,7 @@ static int __exclude_logged_extent(struct btrfs_root *root, u64 start, u64 num_b num_bytes = (start + num_bytes) - caching_ctl->progress; start = caching_ctl->progress; - ret = add_excluded_extent(root, start, num_bytes); + ret = add_excluded_extent(fs_info, start, num_bytes); } out_lock: mutex_unlock(&caching_ctl->mutex); @@ -6411,7 +6409,7 @@ out_lock: return ret; } -int btrfs_exclude_logged_extents(struct btrfs_root *log, +int btrfs_exclude_logged_extents(struct btrfs_fs_info *fs_info, struct extent_buffer *eb) { struct btrfs_file_extent_item *item; @@ -6419,7 +6417,7 @@ int btrfs_exclude_logged_extents(struct btrfs_root *log, int found_type; int i; - if (!btrfs_fs_incompat(log->fs_info, MIXED_GROUPS)) + if (!btrfs_fs_incompat(fs_info, MIXED_GROUPS)) return 0; for (i = 0; i < btrfs_header_nritems(eb); i++) { @@ -6434,7 +6432,7 @@ int btrfs_exclude_logged_extents(struct btrfs_root *log, continue; key.objectid = btrfs_file_extent_disk_bytenr(eb, item); key.offset = btrfs_file_extent_disk_num_bytes(eb, item); - __exclude_logged_extent(log, key.objectid, key.offset); + __exclude_logged_extent(fs_info, key.objectid, key.offset); } return 0; @@ -6499,16 +6497,9 @@ void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg) * @num_bytes: The number of bytes in question * @delalloc: The blocks are allocated for the delalloc write * - * This is called by the allocator when it reserves space. Metadata - * reservations should be called with RESERVE_ALLOC so we do the proper - * ENOSPC accounting. For data we handle the reservation through clearing the - * delalloc bits in the io_tree. We have to do this since we could end up - * allocating less disk space for the amount of data we have reserved in the - * case of compression. - * - * If this is a reservation and the block group has become read only we cannot - * make the reservation and return -EAGAIN, otherwise this function always - * succeeds. + * This is called by the allocator when it reserves space. If this is a + * reservation and the block group has become read only we cannot make the + * reservation and return -EAGAIN, otherwise this function always succeeds. */ static int btrfs_add_reserved_bytes(struct btrfs_block_group_cache *cache, u64 ram_bytes, u64 num_bytes, int delalloc) @@ -6568,9 +6559,8 @@ static int btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache, return ret; } void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, - struct btrfs_root *root) + struct btrfs_fs_info *fs_info) { - struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_caching_control *next; struct btrfs_caching_control *caching_ctl; struct btrfs_block_group_cache *cache; @@ -6604,11 +6594,11 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, * what it should be based on the mount options. */ static struct btrfs_free_cluster * -fetch_cluster_info(struct btrfs_root *root, struct btrfs_space_info *space_info, - u64 *empty_cluster) +fetch_cluster_info(struct btrfs_fs_info *fs_info, + struct btrfs_space_info *space_info, u64 *empty_cluster) { struct btrfs_free_cluster *ret = NULL; - bool ssd = btrfs_test_opt(root->fs_info, SSD); + bool ssd = btrfs_test_opt(fs_info, SSD); *empty_cluster = 0; if (btrfs_mixed_space_info(space_info)) @@ -6617,20 +6607,20 @@ fetch_cluster_info(struct btrfs_root *root, struct btrfs_space_info *space_info, if (ssd) *empty_cluster = SZ_2M; if (space_info->flags & BTRFS_BLOCK_GROUP_METADATA) { - ret = &root->fs_info->meta_alloc_cluster; + ret = &fs_info->meta_alloc_cluster; if (!ssd) *empty_cluster = SZ_64K; } else if ((space_info->flags & BTRFS_BLOCK_GROUP_DATA) && ssd) { - ret = &root->fs_info->data_alloc_cluster; + ret = &fs_info->data_alloc_cluster; } return ret; } -static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end, +static int unpin_extent_range(struct btrfs_fs_info *fs_info, + u64 start, u64 end, const bool return_free_space) { - struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_block_group_cache *cache = NULL; struct btrfs_space_info *space_info; struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; @@ -6650,7 +6640,7 @@ static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end, cache = btrfs_lookup_block_group(fs_info, start); BUG_ON(!cache); /* Logic error */ - cluster = fetch_cluster_info(root, + cluster = fetch_cluster_info(fs_info, cache->space_info, &empty_cluster); empty_cluster <<= 1; @@ -6729,9 +6719,8 @@ static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end, } int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, - struct btrfs_root *root) + struct btrfs_fs_info *fs_info) { - struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_block_group_cache *block_group, *tmp; struct list_head *deleted_bgs; struct extent_io_tree *unpin; @@ -6753,12 +6742,12 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, break; } - if (btrfs_test_opt(root->fs_info, DISCARD)) - ret = btrfs_discard_extent(root, start, + if (btrfs_test_opt(fs_info, DISCARD)) + ret = btrfs_discard_extent(fs_info, start, end + 1 - start, NULL); clear_extent_dirty(unpin, start, end); - unpin_extent_range(root, start, end, true); + unpin_extent_range(fs_info, start, end, true); mutex_unlock(&fs_info->unused_bg_unpin_mutex); cond_resched(); } @@ -6774,7 +6763,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, ret = -EROFS; if (!trans->aborted) - ret = btrfs_discard_extent(root, + ret = btrfs_discard_extent(fs_info, block_group->key.objectid, block_group->key.offset, &trimmed); @@ -6816,7 +6805,7 @@ static void add_pinned_bytes(struct btrfs_fs_info *fs_info, u64 num_bytes, static int __btrfs_free_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *info, struct btrfs_delayed_ref_node *node, u64 parent, u64 root_objectid, u64 owner_objectid, u64 owner_offset, int refs_to_drop, @@ -6824,7 +6813,6 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, { struct btrfs_key key; struct btrfs_path *path; - struct btrfs_fs_info *info = root->fs_info; struct btrfs_root *extent_root = info->extent_root; struct extent_buffer *leaf; struct btrfs_extent_item *ei; @@ -6839,8 +6827,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, u64 bytenr = node->bytenr; u64 num_bytes = node->num_bytes; int last_ref = 0; - bool skinny_metadata = btrfs_fs_incompat(root->fs_info, - SKINNY_METADATA); + bool skinny_metadata = btrfs_fs_incompat(info, SKINNY_METADATA); path = btrfs_alloc_path(); if (!path) @@ -6937,8 +6924,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, "umm, got %d back from search, was looking for %llu", ret, bytenr); if (ret > 0) - btrfs_print_leaf(extent_root, - path->nodes[0]); + btrfs_print_leaf(info, path->nodes[0]); } if (ret < 0) { btrfs_abort_transaction(trans, ret); @@ -6947,7 +6933,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, extent_slot = path->slots[0]; } } else if (WARN_ON(ret == -ENOENT)) { - btrfs_print_leaf(extent_root, path->nodes[0]); + btrfs_print_leaf(info, path->nodes[0]); btrfs_err(info, "unable to find ref byte nr %llu parent %llu root %llu owner %llu offset %llu", bytenr, parent, root_objectid, owner_objectid, @@ -6984,7 +6970,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, btrfs_err(info, "umm, got %d back from search, was looking for %llu", ret, bytenr); - btrfs_print_leaf(extent_root, path->nodes[0]); + btrfs_print_leaf(info, path->nodes[0]); } if (ret < 0) { btrfs_abort_transaction(trans, ret); @@ -7040,7 +7026,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, goto out; } } - add_pinned_bytes(root->fs_info, -num_bytes, owner_objectid, + add_pinned_bytes(info, -num_bytes, owner_objectid, root_objectid); } else { if (found_extent) { @@ -7065,21 +7051,20 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, btrfs_release_path(path); if (is_data) { - ret = btrfs_del_csums(trans, root, bytenr, num_bytes); + ret = btrfs_del_csums(trans, info, bytenr, num_bytes); if (ret) { btrfs_abort_transaction(trans, ret); goto out; } } - ret = add_to_free_space_tree(trans, root->fs_info, bytenr, - num_bytes); + ret = add_to_free_space_tree(trans, info, bytenr, num_bytes); if (ret) { btrfs_abort_transaction(trans, ret); goto out; } - ret = update_block_group(trans, root, bytenr, num_bytes, 0); + ret = update_block_group(trans, info, bytenr, num_bytes, 0); if (ret) { btrfs_abort_transaction(trans, ret); goto out; @@ -7099,7 +7084,7 @@ out: * removes it from the tree. */ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 bytenr) + u64 bytenr) { struct btrfs_delayed_ref_head *head; struct btrfs_delayed_ref_root *delayed_refs; @@ -7169,15 +7154,17 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, struct extent_buffer *buf, u64 parent, int last_ref) { + struct btrfs_fs_info *fs_info = root->fs_info; int pin = 1; int ret; if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { - ret = btrfs_add_delayed_tree_ref(root->fs_info, trans, - buf->start, buf->len, - parent, root->root_key.objectid, - btrfs_header_level(buf), - BTRFS_DROP_DELAYED_REF, NULL); + ret = btrfs_add_delayed_tree_ref(fs_info, trans, + buf->start, buf->len, + parent, + root->root_key.objectid, + btrfs_header_level(buf), + BTRFS_DROP_DELAYED_REF, NULL); BUG_ON(ret); /* -ENOMEM */ } @@ -7188,15 +7175,16 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, struct btrfs_block_group_cache *cache; if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { - ret = check_ref_cleanup(trans, root, buf->start); + ret = check_ref_cleanup(trans, buf->start); if (!ret) goto out; } - cache = btrfs_lookup_block_group(root->fs_info, buf->start); + cache = btrfs_lookup_block_group(fs_info, buf->start); if (btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { - pin_down_extent(root, cache, buf->start, buf->len, 1); + pin_down_extent(fs_info, cache, buf->start, + buf->len, 1); btrfs_put_block_group(cache); goto out; } @@ -7206,13 +7194,12 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, btrfs_add_free_space(cache, buf->start, buf->len); btrfs_free_reserved_bytes(cache, buf->len, 0); btrfs_put_block_group(cache); - trace_btrfs_reserved_extent_free(root, buf->start, buf->len); + trace_btrfs_reserved_extent_free(fs_info, buf->start, buf->len); pin = 0; } out: if (pin) - add_pinned_bytes(root->fs_info, buf->len, - btrfs_header_level(buf), + add_pinned_bytes(fs_info, buf->len, btrfs_header_level(buf), root->root_key.objectid); /* @@ -7223,17 +7210,17 @@ out: } /* Can return -ENOMEM */ -int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, +int btrfs_free_extent(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, u64 owner, u64 offset) { int ret; - struct btrfs_fs_info *fs_info = root->fs_info; if (btrfs_is_testing(fs_info)) return 0; - add_pinned_bytes(root->fs_info, num_bytes, owner, root_objectid); + add_pinned_bytes(fs_info, num_bytes, owner, root_objectid); /* * tree log blocks never actually go into the extent allocation @@ -7242,7 +7229,7 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, if (root_objectid == BTRFS_TREE_LOG_OBJECTID) { WARN_ON(owner >= BTRFS_FIRST_FREE_OBJECTID); /* unlocks the pinned mutex */ - btrfs_pin_extent(root, bytenr, num_bytes, 1); + btrfs_pin_extent(fs_info, bytenr, num_bytes, 1); ret = 0; } else if (owner < BTRFS_FIRST_FREE_OBJECTID) { ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, @@ -7433,8 +7420,9 @@ static noinline int find_free_extent(struct btrfs_root *orig_root, u64 hint_byte, struct btrfs_key *ins, u64 flags, int delalloc) { + struct btrfs_fs_info *fs_info = orig_root->fs_info; int ret = 0; - struct btrfs_root *root = orig_root->fs_info->extent_root; + struct btrfs_root *root = fs_info->extent_root; struct btrfs_free_cluster *last_ptr = NULL; struct btrfs_block_group_cache *block_group = NULL; u64 search_start = 0; @@ -7450,16 +7438,16 @@ static noinline int find_free_extent(struct btrfs_root *orig_root, bool orig_have_caching_bg = false; bool full_search = false; - WARN_ON(num_bytes < root->sectorsize); + WARN_ON(num_bytes < fs_info->sectorsize); ins->type = BTRFS_EXTENT_ITEM_KEY; ins->objectid = 0; ins->offset = 0; - trace_find_free_extent(orig_root, num_bytes, empty_size, flags); + trace_find_free_extent(fs_info, num_bytes, empty_size, flags); - space_info = __find_space_info(root->fs_info, flags); + space_info = __find_space_info(fs_info, flags); if (!space_info) { - btrfs_err(root->fs_info, "No space info for %llu", flags); + btrfs_err(fs_info, "No space info for %llu", flags); return -ENOSPC; } @@ -7486,7 +7474,7 @@ static noinline int find_free_extent(struct btrfs_root *orig_root, spin_unlock(&space_info->lock); } - last_ptr = fetch_cluster_info(orig_root, space_info, &empty_cluster); + last_ptr = fetch_cluster_info(fs_info, space_info, &empty_cluster); if (last_ptr) { spin_lock(&last_ptr->lock); if (last_ptr->block_group) @@ -7503,11 +7491,10 @@ static noinline int find_free_extent(struct btrfs_root *orig_root, spin_unlock(&last_ptr->lock); } - search_start = max(search_start, first_logical_byte(root, 0)); + search_start = max(search_start, first_logical_byte(fs_info, 0)); search_start = max(search_start, hint_byte); if (search_start == hint_byte) { - block_group = btrfs_lookup_block_group(root->fs_info, - search_start); + block_group = btrfs_lookup_block_group(fs_info, search_start); /* * we don't want to use the block group if it doesn't match our * allocation bits, or if its not cached. @@ -7615,7 +7602,7 @@ have_block_group: if (offset) { /* we have a block, we're done */ spin_unlock(&last_ptr->refill_lock); - trace_btrfs_reserve_extent_cluster(root, + trace_btrfs_reserve_extent_cluster(fs_info, used_block_group, search_start, num_bytes); if (used_block_group != block_group) { @@ -7671,7 +7658,7 @@ refill_cluster: block_group->full_stripe_len); /* allocate a cluster in this block group */ - ret = btrfs_find_space_cluster(root, block_group, + ret = btrfs_find_space_cluster(fs_info, block_group, last_ptr, search_start, num_bytes, aligned_cluster); @@ -7688,7 +7675,7 @@ refill_cluster: if (offset) { /* we found one, proceed */ spin_unlock(&last_ptr->refill_lock); - trace_btrfs_reserve_extent_cluster(root, + trace_btrfs_reserve_extent_cluster(fs_info, block_group, search_start, num_bytes); goto checks; @@ -7760,7 +7747,7 @@ unclustered_alloc: goto loop; } checks: - search_start = ALIGN(offset, root->stripesize); + search_start = ALIGN(offset, fs_info->stripesize); /* move on to the next group */ if (search_start + num_bytes > @@ -7786,7 +7773,7 @@ checks: ins->objectid = search_start; ins->offset = num_bytes; - trace_btrfs_reserve_extent(orig_root, block_group, + trace_btrfs_reserve_extent(fs_info, block_group, search_start, num_bytes); btrfs_release_block_group(block_group, delalloc); break; @@ -7847,7 +7834,7 @@ loop: goto out; } - ret = do_chunk_alloc(trans, root, flags, + ret = do_chunk_alloc(trans, fs_info, flags, CHUNK_ALLOC_FORCE); /* @@ -7867,7 +7854,7 @@ loop: else ret = 0; if (!exist) - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); if (ret) goto out; } @@ -7959,7 +7946,7 @@ int btrfs_reserve_extent(struct btrfs_root *root, u64 ram_bytes, flags = btrfs_get_alloc_profile(root, is_data); again: - WARN_ON(num_bytes < root->sectorsize); + WARN_ON(num_bytes < fs_info->sectorsize); ret = find_free_extent(root, ram_bytes, num_bytes, empty_size, hint_byte, ins, flags, delalloc); if (!ret && !is_data) { @@ -7967,7 +7954,8 @@ again: } else if (ret == -ENOSPC) { if (!final_tried && ins->offset) { num_bytes = min(num_bytes >> 1, ins->offset); - num_bytes = round_down(num_bytes, root->sectorsize); + num_bytes = round_down(num_bytes, + fs_info->sectorsize); num_bytes = max(num_bytes, min_alloc_size); ram_bytes = num_bytes; if (num_bytes == min_alloc_size) @@ -7977,7 +7965,7 @@ again: struct btrfs_space_info *sinfo; sinfo = __find_space_info(fs_info, flags); - btrfs_err(root->fs_info, + btrfs_err(fs_info, "allocation failed flags %llu, wanted %llu", flags, num_bytes); if (sinfo) @@ -7988,54 +7976,53 @@ again: return ret; } -static int __btrfs_free_reserved_extent(struct btrfs_root *root, +static int __btrfs_free_reserved_extent(struct btrfs_fs_info *fs_info, u64 start, u64 len, int pin, int delalloc) { struct btrfs_block_group_cache *cache; int ret = 0; - cache = btrfs_lookup_block_group(root->fs_info, start); + cache = btrfs_lookup_block_group(fs_info, start); if (!cache) { - btrfs_err(root->fs_info, "Unable to find block group for %llu", - start); + btrfs_err(fs_info, "Unable to find block group for %llu", + start); return -ENOSPC; } if (pin) - pin_down_extent(root, cache, start, len, 1); + pin_down_extent(fs_info, cache, start, len, 1); else { - if (btrfs_test_opt(root->fs_info, DISCARD)) - ret = btrfs_discard_extent(root, start, len, NULL); + if (btrfs_test_opt(fs_info, DISCARD)) + ret = btrfs_discard_extent(fs_info, start, len, NULL); btrfs_add_free_space(cache, start, len); btrfs_free_reserved_bytes(cache, len, delalloc); - trace_btrfs_reserved_extent_free(root, start, len); + trace_btrfs_reserved_extent_free(fs_info, start, len); } btrfs_put_block_group(cache); return ret; } -int btrfs_free_reserved_extent(struct btrfs_root *root, +int btrfs_free_reserved_extent(struct btrfs_fs_info *fs_info, u64 start, u64 len, int delalloc) { - return __btrfs_free_reserved_extent(root, start, len, 0, delalloc); + return __btrfs_free_reserved_extent(fs_info, start, len, 0, delalloc); } -int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, +int btrfs_free_and_pin_reserved_extent(struct btrfs_fs_info *fs_info, u64 start, u64 len) { - return __btrfs_free_reserved_extent(root, start, len, 1, 0); + return __btrfs_free_reserved_extent(fs_info, start, len, 1, 0); } static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, u64 parent, u64 root_objectid, u64 flags, u64 owner, u64 offset, struct btrfs_key *ins, int ref_mod) { int ret; - struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_extent_item *extent_item; struct btrfs_extent_inline_ref *iref; struct btrfs_path *path; @@ -8094,24 +8081,23 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, if (ret) return ret; - ret = update_block_group(trans, root, ins->objectid, ins->offset, 1); + ret = update_block_group(trans, fs_info, ins->objectid, ins->offset, 1); if (ret) { /* -ENOENT, logic error */ btrfs_err(fs_info, "update block group failed for %llu %llu", ins->objectid, ins->offset); BUG(); } - trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset); + trace_btrfs_reserved_extent_alloc(fs_info, ins->objectid, ins->offset); return ret; } static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, u64 parent, u64 root_objectid, u64 flags, struct btrfs_disk_key *key, int level, struct btrfs_key *ins) { int ret; - struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_extent_item *extent_item; struct btrfs_tree_block_info *block_info; struct btrfs_extent_inline_ref *iref; @@ -8119,16 +8105,15 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, struct extent_buffer *leaf; u32 size = sizeof(*extent_item) + sizeof(*iref); u64 num_bytes = ins->offset; - bool skinny_metadata = btrfs_fs_incompat(root->fs_info, - SKINNY_METADATA); + bool skinny_metadata = btrfs_fs_incompat(fs_info, SKINNY_METADATA); if (!skinny_metadata) size += sizeof(*block_info); path = btrfs_alloc_path(); if (!path) { - btrfs_free_and_pin_reserved_extent(root, ins->objectid, - root->nodesize); + btrfs_free_and_pin_reserved_extent(fs_info, ins->objectid, + fs_info->nodesize); return -ENOMEM; } @@ -8137,8 +8122,8 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, ins, size); if (ret) { btrfs_free_path(path); - btrfs_free_and_pin_reserved_extent(root, ins->objectid, - root->nodesize); + btrfs_free_and_pin_reserved_extent(fs_info, ins->objectid, + fs_info->nodesize); return ret; } @@ -8152,7 +8137,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, if (skinny_metadata) { iref = (struct btrfs_extent_inline_ref *)(extent_item + 1); - num_bytes = root->nodesize; + num_bytes = fs_info->nodesize; } else { block_info = (struct btrfs_tree_block_info *)(extent_item + 1); btrfs_set_tree_block_key(leaf, block_info, key); @@ -8179,29 +8164,30 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, if (ret) return ret; - ret = update_block_group(trans, root, ins->objectid, root->nodesize, - 1); + ret = update_block_group(trans, fs_info, ins->objectid, + fs_info->nodesize, 1); if (ret) { /* -ENOENT, logic error */ btrfs_err(fs_info, "update block group failed for %llu %llu", ins->objectid, ins->offset); BUG(); } - trace_btrfs_reserved_extent_alloc(root, ins->objectid, root->nodesize); + trace_btrfs_reserved_extent_alloc(fs_info, ins->objectid, + fs_info->nodesize); return ret; } int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 root_objectid, u64 owner, u64 offset, u64 ram_bytes, struct btrfs_key *ins) { + struct btrfs_fs_info *fs_info = trans->fs_info; int ret; BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID); - ret = btrfs_add_delayed_data_ref(root->fs_info, trans, ins->objectid, + ret = btrfs_add_delayed_data_ref(fs_info, trans, ins->objectid, ins->offset, 0, root_objectid, owner, offset, ram_bytes, BTRFS_ADD_DELAYED_EXTENT, @@ -8215,7 +8201,7 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans, * space cache bits as well */ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *root, + struct btrfs_fs_info *fs_info, u64 root_objectid, u64 owner, u64 offset, struct btrfs_key *ins) { @@ -8227,13 +8213,14 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, * Mixed block groups will exclude before processing the log so we only * need to do the exclude dance if this fs isn't mixed. */ - if (!btrfs_fs_incompat(root->fs_info, MIXED_GROUPS)) { - ret = __exclude_logged_extent(root, ins->objectid, ins->offset); + if (!btrfs_fs_incompat(fs_info, MIXED_GROUPS)) { + ret = __exclude_logged_extent(fs_info, ins->objectid, + ins->offset); if (ret) return ret; } - block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid); + block_group = btrfs_lookup_block_group(fs_info, ins->objectid); if (!block_group) return -EINVAL; @@ -8245,7 +8232,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, spin_unlock(&block_group->lock); spin_unlock(&space_info->lock); - ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, + ret = alloc_reserved_file_extent(trans, fs_info, 0, root_objectid, 0, owner, offset, ins, 1); btrfs_put_block_group(block_group); return ret; @@ -8255,16 +8242,17 @@ static struct extent_buffer * btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, int level) { + struct btrfs_fs_info *fs_info = root->fs_info; struct extent_buffer *buf; - buf = btrfs_find_create_tree_block(root, bytenr); + buf = btrfs_find_create_tree_block(fs_info, bytenr); if (IS_ERR(buf)) return buf; btrfs_set_header_generation(buf, trans->transid); btrfs_set_buffer_lockdep_class(root->root_key.objectid, buf, level); btrfs_tree_lock(buf); - clean_tree_block(trans, root->fs_info, buf); + clean_tree_block(trans, fs_info, buf); clear_bit(EXTENT_BUFFER_STALE, &buf->bflags); btrfs_set_lock_blocking(buf); @@ -8296,8 +8284,9 @@ static struct btrfs_block_rsv * use_block_rsv(struct btrfs_trans_handle *trans, struct btrfs_root *root, u32 blocksize) { + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_block_rsv *block_rsv; - struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv; + struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; int ret; bool global_updated = false; @@ -8315,11 +8304,11 @@ again: if (block_rsv->type == BTRFS_BLOCK_RSV_GLOBAL && !global_updated) { global_updated = true; - update_global_block_rsv(root->fs_info); + update_global_block_rsv(fs_info); goto again; } - if (btrfs_test_opt(root->fs_info, ENOSPC_DEBUG)) { + if (btrfs_test_opt(fs_info, ENOSPC_DEBUG)) { static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL * 10, /*DEFAULT_RATELIMIT_BURST*/ 1); @@ -8363,18 +8352,18 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, struct btrfs_disk_key *key, int level, u64 hint, u64 empty_size) { + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_key ins; struct btrfs_block_rsv *block_rsv; struct extent_buffer *buf; struct btrfs_delayed_extent_op *extent_op; u64 flags = 0; int ret; - u32 blocksize = root->nodesize; - bool skinny_metadata = btrfs_fs_incompat(root->fs_info, - SKINNY_METADATA); + u32 blocksize = fs_info->nodesize; + bool skinny_metadata = btrfs_fs_incompat(fs_info, SKINNY_METADATA); #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS - if (btrfs_is_testing(root->fs_info)) { + if (btrfs_is_testing(fs_info)) { buf = btrfs_init_new_buffer(trans, root, root->alloc_bytenr, level); if (!IS_ERR(buf)) @@ -8421,7 +8410,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, extent_op->is_data = false; extent_op->level = level; - ret = btrfs_add_delayed_tree_ref(root->fs_info, trans, + ret = btrfs_add_delayed_tree_ref(fs_info, trans, ins.objectid, ins.offset, parent, root_objectid, level, BTRFS_ADD_DELAYED_EXTENT, @@ -8436,9 +8425,9 @@ out_free_delayed: out_free_buf: free_extent_buffer(buf); out_free_reserved: - btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 0); + btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset, 0); out_unuse: - unuse_block_rsv(root->fs_info, block_rsv, blocksize); + unuse_block_rsv(fs_info, block_rsv, blocksize); return ERR_PTR(ret); } @@ -8464,6 +8453,7 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans, struct walk_control *wc, struct btrfs_path *path) { + struct btrfs_fs_info *fs_info = root->fs_info; u64 bytenr; u64 generation; u64 refs; @@ -8481,7 +8471,7 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans, } else { wc->reada_count = wc->reada_count * 3 / 2; wc->reada_count = min_t(int, wc->reada_count, - BTRFS_NODEPTRS_PER_BLOCK(root)); + BTRFS_NODEPTRS_PER_BLOCK(fs_info)); } eb = path->nodes[wc->level]; @@ -8503,7 +8493,7 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans, continue; /* We don't lock the tree block, it's OK to be racy here */ - ret = btrfs_lookup_extent_info(trans, root, bytenr, + ret = btrfs_lookup_extent_info(trans, fs_info, bytenr, wc->level - 1, 1, &refs, &flags); /* We don't care about errors in readahead. */ @@ -8532,226 +8522,12 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans, continue; } reada: - readahead_tree_block(root, bytenr); + readahead_tree_block(fs_info, bytenr); nread++; } wc->reada_slot = slot; } -static int account_leaf_items(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct extent_buffer *eb) -{ - int nr = btrfs_header_nritems(eb); - int i, extent_type, ret; - struct btrfs_key key; - struct btrfs_file_extent_item *fi; - u64 bytenr, num_bytes; - - /* We can be called directly from walk_up_proc() */ - if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags)) - return 0; - - for (i = 0; i < nr; i++) { - btrfs_item_key_to_cpu(eb, &key, i); - - if (key.type != BTRFS_EXTENT_DATA_KEY) - continue; - - fi = btrfs_item_ptr(eb, i, struct btrfs_file_extent_item); - /* filter out non qgroup-accountable extents */ - extent_type = btrfs_file_extent_type(eb, fi); - - if (extent_type == BTRFS_FILE_EXTENT_INLINE) - continue; - - bytenr = btrfs_file_extent_disk_bytenr(eb, fi); - if (!bytenr) - continue; - - num_bytes = btrfs_file_extent_disk_num_bytes(eb, fi); - - ret = btrfs_qgroup_insert_dirty_extent(trans, root->fs_info, - bytenr, num_bytes, GFP_NOFS); - if (ret) - return ret; - } - return 0; -} - -/* - * Walk up the tree from the bottom, freeing leaves and any interior - * nodes which have had all slots visited. If a node (leaf or - * interior) is freed, the node above it will have it's slot - * incremented. The root node will never be freed. - * - * At the end of this function, we should have a path which has all - * slots incremented to the next position for a search. If we need to - * read a new node it will be NULL and the node above it will have the - * correct slot selected for a later read. - * - * If we increment the root nodes slot counter past the number of - * elements, 1 is returned to signal completion of the search. - */ -static int adjust_slots_upwards(struct btrfs_root *root, - struct btrfs_path *path, int root_level) -{ - int level = 0; - int nr, slot; - struct extent_buffer *eb; - - if (root_level == 0) - return 1; - - while (level <= root_level) { - eb = path->nodes[level]; - nr = btrfs_header_nritems(eb); - path->slots[level]++; - slot = path->slots[level]; - if (slot >= nr || level == 0) { - /* - * Don't free the root - we will detect this - * condition after our loop and return a - * positive value for caller to stop walking the tree. - */ - if (level != root_level) { - btrfs_tree_unlock_rw(eb, path->locks[level]); - path->locks[level] = 0; - - free_extent_buffer(eb); - path->nodes[level] = NULL; - path->slots[level] = 0; - } - } else { - /* - * We have a valid slot to walk back down - * from. Stop here so caller can process these - * new nodes. - */ - break; - } - - level++; - } - - eb = path->nodes[root_level]; - if (path->slots[root_level] >= btrfs_header_nritems(eb)) - return 1; - - return 0; -} - -/* - * root_eb is the subtree root and is locked before this function is called. - */ -static int account_shared_subtree(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct extent_buffer *root_eb, - u64 root_gen, - int root_level) -{ - int ret = 0; - int level; - struct extent_buffer *eb = root_eb; - struct btrfs_path *path = NULL; - - BUG_ON(root_level < 0 || root_level > BTRFS_MAX_LEVEL); - BUG_ON(root_eb == NULL); - - if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags)) - return 0; - - if (!extent_buffer_uptodate(root_eb)) { - ret = btrfs_read_buffer(root_eb, root_gen); - if (ret) - goto out; - } - - if (root_level == 0) { - ret = account_leaf_items(trans, root, root_eb); - goto out; - } - - path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; - - /* - * Walk down the tree. Missing extent blocks are filled in as - * we go. Metadata is accounted every time we read a new - * extent block. - * - * When we reach a leaf, we account for file extent items in it, - * walk back up the tree (adjusting slot pointers as we go) - * and restart the search process. - */ - extent_buffer_get(root_eb); /* For path */ - path->nodes[root_level] = root_eb; - path->slots[root_level] = 0; - path->locks[root_level] = 0; /* so release_path doesn't try to unlock */ -walk_down: - level = root_level; - while (level >= 0) { - if (path->nodes[level] == NULL) { - int parent_slot; - u64 child_gen; - u64 child_bytenr; - - /* We need to get child blockptr/gen from - * parent before we can read it. */ - eb = path->nodes[level + 1]; - parent_slot = path->slots[level + 1]; - child_bytenr = btrfs_node_blockptr(eb, parent_slot); - child_gen = btrfs_node_ptr_generation(eb, parent_slot); - - eb = read_tree_block(root, child_bytenr, child_gen); - if (IS_ERR(eb)) { - ret = PTR_ERR(eb); - goto out; - } else if (!extent_buffer_uptodate(eb)) { - free_extent_buffer(eb); - ret = -EIO; - goto out; - } - - path->nodes[level] = eb; - path->slots[level] = 0; - - btrfs_tree_read_lock(eb); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); - path->locks[level] = BTRFS_READ_LOCK_BLOCKING; - - ret = btrfs_qgroup_insert_dirty_extent(trans, - root->fs_info, child_bytenr, - root->nodesize, GFP_NOFS); - if (ret) - goto out; - } - - if (level == 0) { - ret = account_leaf_items(trans, root, path->nodes[level]); - if (ret) - goto out; - - /* Nonzero return here means we completed our search */ - ret = adjust_slots_upwards(root, path, root_level); - if (ret) - break; - - /* Restart search with new slots */ - goto walk_down; - } - - level--; - } - - ret = 0; -out: - btrfs_free_path(path); - - return ret; -} - /* * helper to process tree block while walking down the tree. * @@ -8765,6 +8541,7 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct walk_control *wc, int lookup_info) { + struct btrfs_fs_info *fs_info = root->fs_info; int level = wc->level; struct extent_buffer *eb = path->nodes[level]; u64 flag = BTRFS_BLOCK_FLAG_FULL_BACKREF; @@ -8782,7 +8559,7 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, ((wc->stage == DROP_REFERENCE && wc->refs[level] != 1) || (wc->stage == UPDATE_BACKREF && !(wc->flags[level] & flag)))) { BUG_ON(!path->locks[level]); - ret = btrfs_lookup_extent_info(trans, root, + ret = btrfs_lookup_extent_info(trans, fs_info, eb->start, level, 1, &wc->refs[level], &wc->flags[level]); @@ -8810,7 +8587,7 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, BUG_ON(ret); /* -ENOMEM */ ret = btrfs_dec_ref(trans, root, eb, 0); BUG_ON(ret); /* -ENOMEM */ - ret = btrfs_set_disk_extent_flags(trans, root, eb->start, + ret = btrfs_set_disk_extent_flags(trans, fs_info, eb->start, eb->len, flag, btrfs_header_level(eb), 0); BUG_ON(ret); /* -ENOMEM */ @@ -8846,6 +8623,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct walk_control *wc, int *lookup_info) { + struct btrfs_fs_info *fs_info = root->fs_info; u64 bytenr; u64 generation; u64 parent; @@ -8871,11 +8649,11 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, } bytenr = btrfs_node_blockptr(path->nodes[level], path->slots[level]); - blocksize = root->nodesize; + blocksize = fs_info->nodesize; - next = btrfs_find_tree_block(root->fs_info, bytenr); + next = find_extent_buffer(fs_info, bytenr); if (!next) { - next = btrfs_find_create_tree_block(root, bytenr); + next = btrfs_find_create_tree_block(fs_info, bytenr); if (IS_ERR(next)) return PTR_ERR(next); @@ -8886,14 +8664,14 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, btrfs_tree_lock(next); btrfs_set_lock_blocking(next); - ret = btrfs_lookup_extent_info(trans, root, bytenr, level - 1, 1, + ret = btrfs_lookup_extent_info(trans, fs_info, bytenr, level - 1, 1, &wc->refs[level - 1], &wc->flags[level - 1]); if (ret < 0) goto out_unlock; if (unlikely(wc->refs[level - 1] == 0)) { - btrfs_err(root->fs_info, "Missing references."); + btrfs_err(fs_info, "Missing references."); ret = -EIO; goto out_unlock; } @@ -8935,7 +8713,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, if (!next) { if (reada && level == 1) reada_walk_down(trans, root, wc, path); - next = read_tree_block(root, bytenr, generation); + next = read_tree_block(fs_info, bytenr, generation); if (IS_ERR(next)) { return PTR_ERR(next); } else if (!extent_buffer_uptodate(next)) { @@ -8980,16 +8758,17 @@ skip: } if (need_account) { - ret = account_shared_subtree(trans, root, next, - generation, level - 1); + ret = btrfs_qgroup_trace_subtree(trans, root, next, + generation, level - 1); if (ret) { - btrfs_err_rl(root->fs_info, + btrfs_err_rl(fs_info, "Error %d accounting shared subtree. Quota is out of sync, rescan required.", ret); } } - ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, - root->root_key.objectid, level - 1, 0); + ret = btrfs_free_extent(trans, fs_info, bytenr, blocksize, + parent, root->root_key.objectid, + level - 1, 0); if (ret) goto out_unlock; } @@ -9021,6 +8800,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct walk_control *wc) { + struct btrfs_fs_info *fs_info = root->fs_info; int ret; int level = wc->level; struct extent_buffer *eb = path->nodes[level]; @@ -9050,7 +8830,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, btrfs_set_lock_blocking(eb); path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; - ret = btrfs_lookup_extent_info(trans, root, + ret = btrfs_lookup_extent_info(trans, fs_info, eb->start, level, 1, &wc->refs[level], &wc->flags[level]); @@ -9078,9 +8858,9 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, else ret = btrfs_dec_ref(trans, root, eb, 0); BUG_ON(ret); /* -ENOMEM */ - ret = account_leaf_items(trans, root, eb); + ret = btrfs_qgroup_trace_leaf_items(trans, fs_info, eb); if (ret) { - btrfs_err_rl(root->fs_info, + btrfs_err_rl(fs_info, "error %d accounting leaf items. Quota is out of sync, rescan required.", ret); } @@ -9092,7 +8872,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, btrfs_set_lock_blocking(eb); path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; } - clean_tree_block(trans, root->fs_info, eb); + clean_tree_block(trans, fs_info, eb); } if (eb == root->node) { @@ -9270,7 +9050,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, btrfs_set_lock_blocking(path->nodes[level]); path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; - ret = btrfs_lookup_extent_info(trans, root, + ret = btrfs_lookup_extent_info(trans, fs_info, path->nodes[level]->start, level, 1, &wc->refs[level], &wc->flags[level]); @@ -9296,7 +9076,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, wc->update_ref = update_ref; wc->keep_locks = 0; wc->for_reloc = for_reloc; - wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); + wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(fs_info); while (1) { @@ -9326,8 +9106,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root, } BUG_ON(wc->level == 0); - if (btrfs_should_end_transaction(trans, tree_root) || - (!for_reloc && btrfs_need_cleaner_sleep(root))) { + if (btrfs_should_end_transaction(trans) || + (!for_reloc && btrfs_need_cleaner_sleep(fs_info))) { ret = btrfs_update_root(trans, tree_root, &root->root_key, root_item); @@ -9337,8 +9117,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root, goto out_end_trans; } - btrfs_end_transaction_throttle(trans, tree_root); - if (!for_reloc && btrfs_need_cleaner_sleep(root)) { + btrfs_end_transaction_throttle(trans); + if (!for_reloc && btrfs_need_cleaner_sleep(fs_info)) { btrfs_debug(fs_info, "drop snapshot early exit"); err = -EAGAIN; @@ -9391,7 +9171,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, } root_dropped = true; out_end_trans: - btrfs_end_transaction_throttle(trans, tree_root); + btrfs_end_transaction_throttle(trans); out_free: kfree(wc); btrfs_free_path(path); @@ -9421,6 +9201,7 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, struct extent_buffer *node, struct extent_buffer *parent) { + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_path *path; struct walk_control *wc; int level; @@ -9460,7 +9241,7 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, wc->update_ref = 0; wc->keep_locks = 1; wc->for_reloc = 1; - wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); + wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(fs_info); while (1) { wret = walk_down_tree(trans, root, path, wc); @@ -9481,7 +9262,7 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, return ret; } -static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) +static u64 update_block_group_flags(struct btrfs_fs_info *fs_info, u64 flags) { u64 num_devices; u64 stripped; @@ -9490,11 +9271,11 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) * if restripe for this chunk_type is on pick target profile and * return, otherwise do the usual balance */ - stripped = get_restripe_target(root->fs_info, flags); + stripped = get_restripe_target(fs_info, flags); if (stripped) return extended_to_chunk(stripped); - num_devices = root->fs_info->fs_devices->rw_devices; + num_devices = fs_info->fs_devices->rw_devices; stripped = BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6 | @@ -9579,6 +9360,7 @@ int btrfs_inc_block_group_ro(struct btrfs_root *root, struct btrfs_block_group_cache *cache) { + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_trans_handle *trans; u64 alloc_flags; int ret; @@ -9593,14 +9375,14 @@ again: * block groups cache has started writing. If it already started, * back off and let this transaction commit */ - mutex_lock(&root->fs_info->ro_block_group_mutex); + mutex_lock(&fs_info->ro_block_group_mutex); if (test_bit(BTRFS_TRANS_DIRTY_BG_RUN, &trans->transaction->flags)) { u64 transid = trans->transid; - mutex_unlock(&root->fs_info->ro_block_group_mutex); - btrfs_end_transaction(trans, root); + mutex_unlock(&fs_info->ro_block_group_mutex); + btrfs_end_transaction(trans); - ret = btrfs_wait_for_commit(root, transid); + ret = btrfs_wait_for_commit(fs_info, transid); if (ret) return ret; goto again; @@ -9610,9 +9392,9 @@ again: * if we are changing raid levels, try to allocate a corresponding * block group with the new raid level. */ - alloc_flags = update_block_group_flags(root, cache->flags); + alloc_flags = update_block_group_flags(fs_info, cache->flags); if (alloc_flags != cache->flags) { - ret = do_chunk_alloc(trans, root, alloc_flags, + ret = do_chunk_alloc(trans, fs_info, alloc_flags, CHUNK_ALLOC_FORCE); /* * ENOSPC is allowed here, we may have enough space @@ -9628,31 +9410,31 @@ again: ret = inc_block_group_ro(cache, 0); if (!ret) goto out; - alloc_flags = get_alloc_profile(root, cache->space_info->flags); - ret = do_chunk_alloc(trans, root, alloc_flags, + alloc_flags = get_alloc_profile(fs_info, cache->space_info->flags); + ret = do_chunk_alloc(trans, fs_info, alloc_flags, CHUNK_ALLOC_FORCE); if (ret < 0) goto out; ret = inc_block_group_ro(cache, 0); out: if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM) { - alloc_flags = update_block_group_flags(root, cache->flags); - lock_chunks(root->fs_info->chunk_root); - check_system_chunk(trans, root, alloc_flags); - unlock_chunks(root->fs_info->chunk_root); + alloc_flags = update_block_group_flags(fs_info, cache->flags); + mutex_lock(&fs_info->chunk_mutex); + check_system_chunk(trans, fs_info, alloc_flags); + mutex_unlock(&fs_info->chunk_mutex); } - mutex_unlock(&root->fs_info->ro_block_group_mutex); + mutex_unlock(&fs_info->ro_block_group_mutex); - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); return ret; } int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 type) + struct btrfs_fs_info *fs_info, u64 type) { - u64 alloc_flags = get_alloc_profile(root, type); - return do_chunk_alloc(trans, root, alloc_flags, - CHUNK_ALLOC_FORCE); + u64 alloc_flags = get_alloc_profile(fs_info, type); + + return do_chunk_alloc(trans, fs_info, alloc_flags, CHUNK_ALLOC_FORCE); } /* @@ -9696,8 +9478,7 @@ u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo) return free_bytes; } -void btrfs_dec_block_group_ro(struct btrfs_root *root, - struct btrfs_block_group_cache *cache) +void btrfs_dec_block_group_ro(struct btrfs_block_group_cache *cache) { struct btrfs_space_info *sinfo = cache->space_info; u64 num_bytes; @@ -9723,11 +9504,12 @@ void btrfs_dec_block_group_ro(struct btrfs_root *root, * @return - -1 if it's not a good idea to relocate this block group, 0 if its * ok to go ahead and try. */ -int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) +int btrfs_can_relocate(struct btrfs_fs_info *fs_info, u64 bytenr) { + struct btrfs_root *root = fs_info->extent_root; struct btrfs_block_group_cache *block_group; struct btrfs_space_info *space_info; - struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; + struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; struct btrfs_device *device; struct btrfs_trans_handle *trans; u64 min_free; @@ -9739,14 +9521,14 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) int full = 0; int ret = 0; - debug = btrfs_test_opt(root->fs_info, ENOSPC_DEBUG); + debug = btrfs_test_opt(fs_info, ENOSPC_DEBUG); - block_group = btrfs_lookup_block_group(root->fs_info, bytenr); + block_group = btrfs_lookup_block_group(fs_info, bytenr); /* odd, couldn't find the block group, leave it alone */ if (!block_group) { if (debug) - btrfs_warn(root->fs_info, + btrfs_warn(fs_info, "can't find block group for bytenr %llu", bytenr); return -1; @@ -9796,7 +9578,7 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) * 3: raid0 * 4: single */ - target = get_restripe_target(root->fs_info, block_group->flags); + target = get_restripe_target(fs_info, block_group->flags); if (target) { index = __get_raid_index(extended_to_chunk(target)); } else { @@ -9806,9 +9588,9 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) */ if (full) { if (debug) - btrfs_warn(root->fs_info, - "no space to alloc new chunk for block group %llu", - block_group->key.objectid); + btrfs_warn(fs_info, + "no space to alloc new chunk for block group %llu", + block_group->key.objectid); goto out; } @@ -9836,7 +9618,7 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) goto out; } - mutex_lock(&root->fs_info->chunk_mutex); + mutex_lock(&fs_info->chunk_mutex); list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { u64 dev_offset; @@ -9858,19 +9640,21 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) } } if (debug && ret == -1) - btrfs_warn(root->fs_info, - "no space to allocate a new chunk for block group %llu", - block_group->key.objectid); - mutex_unlock(&root->fs_info->chunk_mutex); - btrfs_end_transaction(trans, root); + btrfs_warn(fs_info, + "no space to allocate a new chunk for block group %llu", + block_group->key.objectid); + mutex_unlock(&fs_info->chunk_mutex); + btrfs_end_transaction(trans); out: btrfs_put_block_group(block_group); return ret; } -static int find_first_block_group(struct btrfs_root *root, - struct btrfs_path *path, struct btrfs_key *key) +static int find_first_block_group(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, + struct btrfs_key *key) { + struct btrfs_root *root = fs_info->extent_root; int ret = 0; struct btrfs_key found_key; struct extent_buffer *leaf; @@ -9904,7 +9688,7 @@ static int find_first_block_group(struct btrfs_root *root, found_key.offset); read_unlock(&em_tree->lock); if (!em) { - btrfs_err(root->fs_info, + btrfs_err(fs_info, "logical %llu len %llu found bg but no related chunk", found_key.objectid, found_key.offset); ret = -ENOENT; @@ -9934,8 +9718,7 @@ void btrfs_put_block_group_cache(struct btrfs_fs_info *info) if (block_group->iref) break; spin_unlock(&block_group->lock); - block_group = next_block_group(info->tree_root, - block_group); + block_group = next_block_group(info, block_group); } if (!block_group) { if (last == 0) @@ -10003,7 +9786,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) */ if (block_group->cached == BTRFS_CACHE_NO || block_group->cached == BTRFS_CACHE_ERROR) - free_excluded_extents(info->extent_root, block_group); + free_excluded_extents(info, block_group); btrfs_remove_free_space_cache(block_group); ASSERT(list_empty(&block_group->dirty_list)); @@ -10094,7 +9877,8 @@ out_err: } static struct btrfs_block_group_cache * -btrfs_create_block_group_cache(struct btrfs_root *root, u64 start, u64 size) +btrfs_create_block_group_cache(struct btrfs_fs_info *fs_info, + u64 start, u64 size) { struct btrfs_block_group_cache *cache; @@ -10113,11 +9897,11 @@ btrfs_create_block_group_cache(struct btrfs_root *root, u64 start, u64 size) cache->key.offset = size; cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; - cache->sectorsize = root->sectorsize; - cache->fs_info = root->fs_info; - cache->full_stripe_len = btrfs_full_stripe_len(root, - &root->fs_info->mapping_tree, - start); + cache->sectorsize = fs_info->sectorsize; + cache->fs_info = fs_info; + cache->full_stripe_len = btrfs_full_stripe_len(fs_info, + &fs_info->mapping_tree, + start); set_free_space_tree_thresholds(cache); atomic_set(&cache->count, 1); @@ -10136,12 +9920,11 @@ btrfs_create_block_group_cache(struct btrfs_root *root, u64 start, u64 size) return cache; } -int btrfs_read_block_groups(struct btrfs_root *root) +int btrfs_read_block_groups(struct btrfs_fs_info *info) { struct btrfs_path *path; int ret; struct btrfs_block_group_cache *cache; - struct btrfs_fs_info *info = root->fs_info; struct btrfs_space_info *space_info; struct btrfs_key key; struct btrfs_key found_key; @@ -10154,7 +9937,6 @@ int btrfs_read_block_groups(struct btrfs_root *root) feature = btrfs_super_incompat_flags(info->super_copy); mixed = !!(feature & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS); - root = info->extent_root; key.objectid = 0; key.offset = 0; key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; @@ -10163,15 +9945,15 @@ int btrfs_read_block_groups(struct btrfs_root *root) return -ENOMEM; path->reada = READA_FORWARD; - cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy); - if (btrfs_test_opt(root->fs_info, SPACE_CACHE) && - btrfs_super_generation(root->fs_info->super_copy) != cache_gen) + cache_gen = btrfs_super_cache_generation(info->super_copy); + if (btrfs_test_opt(info, SPACE_CACHE) && + btrfs_super_generation(info->super_copy) != cache_gen) need_clear = 1; - if (btrfs_test_opt(root->fs_info, CLEAR_CACHE)) + if (btrfs_test_opt(info, CLEAR_CACHE)) need_clear = 1; while (1) { - ret = find_first_block_group(root, path, &key); + ret = find_first_block_group(info, path, &key); if (ret > 0) break; if (ret != 0) @@ -10180,7 +9962,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); - cache = btrfs_create_block_group_cache(root, found_key.objectid, + cache = btrfs_create_block_group_cache(info, found_key.objectid, found_key.offset); if (!cache) { ret = -ENOMEM; @@ -10198,7 +9980,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) * b) Setting 'dirty flag' makes sure that we flush * the new space cache info onto disk. */ - if (btrfs_test_opt(root->fs_info, SPACE_CACHE)) + if (btrfs_test_opt(info, SPACE_CACHE)) cache->disk_cache_state = BTRFS_DC_CLEAR; } @@ -10224,13 +10006,13 @@ int btrfs_read_block_groups(struct btrfs_root *root) * info has super bytes accounted for, otherwise we'll think * we have more space than we actually do. */ - ret = exclude_super_stripes(root, cache); + ret = exclude_super_stripes(info, cache); if (ret) { /* * We may have excluded something, so call this just in * case. */ - free_excluded_extents(root, cache); + free_excluded_extents(info, cache); btrfs_put_block_group(cache); goto error; } @@ -10245,25 +10027,25 @@ int btrfs_read_block_groups(struct btrfs_root *root) if (found_key.offset == btrfs_block_group_used(&cache->item)) { cache->last_byte_to_unpin = (u64)-1; cache->cached = BTRFS_CACHE_FINISHED; - free_excluded_extents(root, cache); + free_excluded_extents(info, cache); } else if (btrfs_block_group_used(&cache->item) == 0) { cache->last_byte_to_unpin = (u64)-1; cache->cached = BTRFS_CACHE_FINISHED; - add_new_free_space(cache, root->fs_info, + add_new_free_space(cache, info, found_key.objectid, found_key.objectid + found_key.offset); - free_excluded_extents(root, cache); + free_excluded_extents(info, cache); } - ret = btrfs_add_block_group_cache(root->fs_info, cache); + ret = btrfs_add_block_group_cache(info, cache); if (ret) { btrfs_remove_free_space_cache(cache); btrfs_put_block_group(cache); goto error; } - trace_btrfs_add_block_group(root->fs_info, cache, 0); + trace_btrfs_add_block_group(info, cache, 0); ret = update_space_info(info, cache->flags, found_key.offset, btrfs_block_group_used(&cache->item), cache->bytes_super, &space_info); @@ -10282,8 +10064,8 @@ int btrfs_read_block_groups(struct btrfs_root *root) __link_block_group(space_info, cache); - set_avail_alloc_bits(root->fs_info, cache->flags); - if (btrfs_chunk_readonly(root, cache->key.objectid)) { + set_avail_alloc_bits(info, cache->flags); + if (btrfs_chunk_readonly(info, cache->key.objectid)) { inc_block_group_ro(cache, 1); } else if (btrfs_block_group_used(&cache->item) == 0) { spin_lock(&info->unused_bgs_lock); @@ -10297,8 +10079,8 @@ int btrfs_read_block_groups(struct btrfs_root *root) } } - list_for_each_entry_rcu(space_info, &root->fs_info->space_info, list) { - if (!(get_alloc_profile(root, space_info->flags) & + list_for_each_entry_rcu(space_info, &info->space_info, list) { + if (!(get_alloc_profile(info, space_info->flags) & (BTRFS_BLOCK_GROUP_RAID10 | BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID5 | @@ -10327,10 +10109,10 @@ error: } void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans, - struct btrfs_root *root) + struct btrfs_fs_info *fs_info) { struct btrfs_block_group_cache *block_group, *tmp; - struct btrfs_root *extent_root = root->fs_info->extent_root; + struct btrfs_root *extent_root = fs_info->extent_root; struct btrfs_block_group_item item; struct btrfs_key key; int ret = 0; @@ -10350,11 +10132,11 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans, sizeof(item)); if (ret) btrfs_abort_transaction(trans, ret); - ret = btrfs_finish_chunk_alloc(trans, extent_root, - key.objectid, key.offset); + ret = btrfs_finish_chunk_alloc(trans, fs_info, key.objectid, + key.offset); if (ret) btrfs_abort_transaction(trans, ret); - add_block_group_free_space(trans, root->fs_info, block_group); + add_block_group_free_space(trans, fs_info, block_group); /* already aborted the transaction if it failed. */ next: list_del_init(&block_group->bg_list); @@ -10363,18 +10145,16 @@ next: } int btrfs_make_block_group(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 bytes_used, + struct btrfs_fs_info *fs_info, u64 bytes_used, u64 type, u64 chunk_objectid, u64 chunk_offset, u64 size) { - int ret; - struct btrfs_root *extent_root; struct btrfs_block_group_cache *cache; - extent_root = root->fs_info->extent_root; + int ret; - btrfs_set_log_full_commit(root->fs_info, trans); + btrfs_set_log_full_commit(fs_info, trans); - cache = btrfs_create_block_group_cache(root, chunk_offset, size); + cache = btrfs_create_block_group_cache(fs_info, chunk_offset, size); if (!cache) return -ENOMEM; @@ -10386,28 +10166,27 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, cache->last_byte_to_unpin = (u64)-1; cache->cached = BTRFS_CACHE_FINISHED; cache->needs_free_space = 1; - ret = exclude_super_stripes(root, cache); + ret = exclude_super_stripes(fs_info, cache); if (ret) { /* * We may have excluded something, so call this just in * case. */ - free_excluded_extents(root, cache); + free_excluded_extents(fs_info, cache); btrfs_put_block_group(cache); return ret; } - add_new_free_space(cache, root->fs_info, chunk_offset, - chunk_offset + size); + add_new_free_space(cache, fs_info, chunk_offset, chunk_offset + size); - free_excluded_extents(root, cache); + free_excluded_extents(fs_info, cache); #ifdef CONFIG_BTRFS_DEBUG - if (btrfs_should_fragment_free_space(root, cache)) { + if (btrfs_should_fragment_free_space(cache)) { u64 new_bytes_used = size - bytes_used; bytes_used += new_bytes_used >> 1; - fragment_free_space(root, cache); + fragment_free_space(cache); } #endif /* @@ -10415,7 +10194,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, * assigned to our block group, but don't update its counters just yet. * We want our bg to be added to the rbtree with its ->space_info set. */ - ret = update_space_info(root->fs_info, cache->flags, 0, 0, 0, + ret = update_space_info(fs_info, cache->flags, 0, 0, 0, &cache->space_info); if (ret) { btrfs_remove_free_space_cache(cache); @@ -10423,7 +10202,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, return ret; } - ret = btrfs_add_block_group_cache(root->fs_info, cache); + ret = btrfs_add_block_group_cache(fs_info, cache); if (ret) { btrfs_remove_free_space_cache(cache); btrfs_put_block_group(cache); @@ -10434,26 +10213,26 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, * Now that our block group has its ->space_info set and is inserted in * the rbtree, update the space info's counters. */ - trace_btrfs_add_block_group(root->fs_info, cache, 1); - ret = update_space_info(root->fs_info, cache->flags, size, bytes_used, + trace_btrfs_add_block_group(fs_info, cache, 1); + ret = update_space_info(fs_info, cache->flags, size, bytes_used, cache->bytes_super, &cache->space_info); if (ret) { btrfs_remove_free_space_cache(cache); - spin_lock(&root->fs_info->block_group_cache_lock); + spin_lock(&fs_info->block_group_cache_lock); rb_erase(&cache->cache_node, - &root->fs_info->block_group_cache_tree); + &fs_info->block_group_cache_tree); RB_CLEAR_NODE(&cache->cache_node); - spin_unlock(&root->fs_info->block_group_cache_lock); + spin_unlock(&fs_info->block_group_cache_lock); btrfs_put_block_group(cache); return ret; } - update_global_block_rsv(root->fs_info); + update_global_block_rsv(fs_info); __link_block_group(cache->space_info, cache); list_add_tail(&cache->bg_list, &trans->new_bgs); - set_avail_alloc_bits(extent_root->fs_info, type); + set_avail_alloc_bits(fs_info, type); return 0; } @@ -10473,13 +10252,14 @@ static void clear_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) } int btrfs_remove_block_group(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 group_start, + struct btrfs_fs_info *fs_info, u64 group_start, struct extent_map *em) { + struct btrfs_root *root = fs_info->extent_root; struct btrfs_path *path; struct btrfs_block_group_cache *block_group; struct btrfs_free_cluster *cluster; - struct btrfs_root *tree_root = root->fs_info->tree_root; + struct btrfs_root *tree_root = fs_info->tree_root; struct btrfs_key key; struct inode *inode; struct kobject *kobj = NULL; @@ -10489,9 +10269,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, struct btrfs_caching_control *caching_ctl = NULL; bool remove_em; - root = root->fs_info->extent_root; - - block_group = btrfs_lookup_block_group(root->fs_info, group_start); + block_group = btrfs_lookup_block_group(fs_info, group_start); BUG_ON(!block_group); BUG_ON(!block_group->ro); @@ -10499,7 +10277,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, * Free the reserved super bytes from this block group before * remove it. */ - free_excluded_extents(root, block_group); + free_excluded_extents(fs_info, block_group); memcpy(&key, &block_group->key, sizeof(key)); index = get_block_group_index(block_group); @@ -10511,7 +10289,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, factor = 1; /* make sure this block group isn't part of an allocation cluster */ - cluster = &root->fs_info->data_alloc_cluster; + cluster = &fs_info->data_alloc_cluster; spin_lock(&cluster->refill_lock); btrfs_return_cluster_to_free_space(block_group, cluster); spin_unlock(&cluster->refill_lock); @@ -10520,7 +10298,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, * make sure this block group isn't part of a metadata * allocation cluster */ - cluster = &root->fs_info->meta_alloc_cluster; + cluster = &fs_info->meta_alloc_cluster; spin_lock(&cluster->refill_lock); btrfs_return_cluster_to_free_space(block_group, cluster); spin_unlock(&cluster->refill_lock); @@ -10549,9 +10327,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, WARN_ON(!IS_ERR(inode) && inode != block_group->io_ctl.inode); spin_unlock(&trans->transaction->dirty_bgs_lock); - 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); spin_lock(&trans->transaction->dirty_bgs_lock); } @@ -10600,14 +10376,14 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, btrfs_release_path(path); } - spin_lock(&root->fs_info->block_group_cache_lock); + spin_lock(&fs_info->block_group_cache_lock); rb_erase(&block_group->cache_node, - &root->fs_info->block_group_cache_tree); + &fs_info->block_group_cache_tree); RB_CLEAR_NODE(&block_group->cache_node); - if (root->fs_info->first_logical_byte == block_group->key.objectid) - root->fs_info->first_logical_byte = (u64)-1; - spin_unlock(&root->fs_info->block_group_cache_lock); + if (fs_info->first_logical_byte == block_group->key.objectid) + fs_info->first_logical_byte = (u64)-1; + spin_unlock(&fs_info->block_group_cache_lock); down_write(&block_group->space_info->groups_sem); /* @@ -10618,7 +10394,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, if (list_empty(&block_group->space_info->block_groups[index])) { kobj = block_group->space_info->block_group_kobjs[index]; block_group->space_info->block_group_kobjs[index] = NULL; - clear_avail_alloc_bits(root->fs_info, block_group->flags); + clear_avail_alloc_bits(fs_info, block_group->flags); } up_write(&block_group->space_info->groups_sem); if (kobj) { @@ -10631,12 +10407,12 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, if (block_group->cached == BTRFS_CACHE_STARTED) wait_block_group_cache_done(block_group); if (block_group->has_caching_ctl) { - down_write(&root->fs_info->commit_root_sem); + down_write(&fs_info->commit_root_sem); if (!caching_ctl) { struct btrfs_caching_control *ctl; list_for_each_entry(ctl, - &root->fs_info->caching_block_groups, list) + &fs_info->caching_block_groups, list) if (ctl->block_group == block_group) { caching_ctl = ctl; atomic_inc(&caching_ctl->count); @@ -10645,7 +10421,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, } if (caching_ctl) list_del_init(&caching_ctl->list); - up_write(&root->fs_info->commit_root_sem); + up_write(&fs_info->commit_root_sem); if (caching_ctl) { /* Once for the caching bgs list and once for us. */ put_caching_control(caching_ctl); @@ -10666,7 +10442,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, spin_lock(&block_group->space_info->lock); list_del_init(&block_group->ro_list); - if (btrfs_test_opt(root->fs_info, ENOSPC_DEBUG)) { + if (btrfs_test_opt(fs_info, ENOSPC_DEBUG)) { WARN_ON(block_group->space_info->total_bytes < block_group->key.offset); WARN_ON(block_group->space_info->bytes_readonly @@ -10682,7 +10458,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, memcpy(&key, &block_group->key, sizeof(key)); - lock_chunks(root); + mutex_lock(&fs_info->chunk_mutex); if (!list_empty(&em->list)) { /* We're in the transaction->pending_chunks list. */ free_extent_map(em); @@ -10730,14 +10506,14 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, * sees the em, either in the pending_chunks list or in the * pinned_chunks list. */ - list_move_tail(&em->list, &root->fs_info->pinned_chunks); + list_move_tail(&em->list, &fs_info->pinned_chunks); } spin_unlock(&block_group->lock); if (remove_em) { struct extent_map_tree *em_tree; - em_tree = &root->fs_info->mapping_tree.map_tree; + em_tree = &fs_info->mapping_tree.map_tree; write_lock(&em_tree->lock); /* * The em might be in the pending_chunks list, so make sure the @@ -10750,9 +10526,9 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, free_extent_map(em); } - unlock_chunks(root); + mutex_unlock(&fs_info->chunk_mutex); - ret = remove_block_group_free_space(trans, root->fs_info, block_group); + ret = remove_block_group_free_space(trans, fs_info, block_group); if (ret) goto out; @@ -10820,7 +10596,6 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) { struct btrfs_block_group_cache *block_group; struct btrfs_space_info *space_info; - struct btrfs_root *root = fs_info->extent_root; struct btrfs_trans_handle *trans; int ret = 0; @@ -10881,7 +10656,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) trans = btrfs_start_trans_remove_block_group(fs_info, block_group->key.objectid); if (IS_ERR(trans)) { - btrfs_dec_block_group_ro(root, block_group); + btrfs_dec_block_group_ro(block_group); ret = PTR_ERR(trans); goto next; } @@ -10908,14 +10683,14 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) EXTENT_DIRTY); if (ret) { mutex_unlock(&fs_info->unused_bg_unpin_mutex); - btrfs_dec_block_group_ro(root, block_group); + btrfs_dec_block_group_ro(block_group); goto end_trans; } ret = clear_extent_bits(&fs_info->freed_extents[1], start, end, EXTENT_DIRTY); if (ret) { mutex_unlock(&fs_info->unused_bg_unpin_mutex); - btrfs_dec_block_group_ro(root, block_group); + btrfs_dec_block_group_ro(block_group); goto end_trans; } mutex_unlock(&fs_info->unused_bg_unpin_mutex); @@ -10934,7 +10709,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) spin_unlock(&space_info->lock); /* DISCARD can flip during remount */ - trimming = btrfs_test_opt(root->fs_info, DISCARD); + trimming = btrfs_test_opt(fs_info, DISCARD); /* Implicit trim during transaction commit. */ if (trimming) @@ -10944,7 +10719,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) * Btrfs_remove_chunk will abort the transaction if things go * horribly wrong. */ - ret = btrfs_remove_chunk(trans, root, + ret = btrfs_remove_chunk(trans, fs_info, block_group->key.objectid); if (ret) { @@ -10971,7 +10746,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) btrfs_get_block_group(block_group); } end_trans: - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); next: mutex_unlock(&fs_info->delete_unused_bgs_mutex); btrfs_put_block_group(block_group); @@ -11018,9 +10793,10 @@ out: return ret; } -int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) +int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info, + u64 start, u64 end) { - return unpin_extent_range(root, start, end, false); + return unpin_extent_range(fs_info, start, end, false); } /* @@ -11060,7 +10836,7 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, ret = 0; while (1) { - struct btrfs_fs_info *fs_info = device->dev_root->fs_info; + struct btrfs_fs_info *fs_info = device->fs_info; struct btrfs_transaction *trans; u64 bytes; @@ -11110,9 +10886,8 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, return ret; } -int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) +int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) { - struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_block_group_cache *cache = NULL; struct btrfs_device *device; struct list_head *devices; @@ -11167,11 +10942,11 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) } } - cache = next_block_group(fs_info->tree_root, cache); + cache = next_block_group(fs_info, cache); } - mutex_lock(&root->fs_info->fs_devices->device_list_mutex); - devices = &root->fs_info->fs_devices->alloc_list; + mutex_lock(&fs_info->fs_devices->device_list_mutex); + devices = &fs_info->fs_devices->alloc_list; list_for_each_entry(device, devices, dev_alloc_list) { ret = btrfs_trim_free_extents(device, range->minlen, &group_trimmed); @@ -11180,7 +10955,7 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) trimmed += group_trimmed; } - mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); + mutex_unlock(&fs_info->fs_devices->device_list_mutex); range->len = trimmed; return ret; |