Lines Matching full:wc
5234 * @wc: the walk control for this deletion
5236 * @refs: the number of refs for wc->level - 1
5237 * @flags: the flags for wc->level - 1
5241 * wc->level should be read and walked into, or if we can simply delete our
5249 static bool visit_node_for_delete(struct btrfs_root *root, struct walk_control *wc, in visit_node_for_delete() argument
5254 int level = wc->level; in visit_node_for_delete()
5257 ASSERT(wc->refs[level - 1] > 0); in visit_node_for_delete()
5263 if (wc->stage == UPDATE_BACKREF) { in visit_node_for_delete()
5273 if (wc->refs[level - 1] == 1) in visit_node_for_delete()
5288 if (!wc->update_ref || generation <= btrfs_root_origin_generation(root)) in visit_node_for_delete()
5296 if (btrfs_comp_cpu_keys(&key, &wc->update_progress) < 0) in visit_node_for_delete()
5305 struct walk_control *wc, in reada_walk_down() argument
5319 if (path->slots[wc->level] < wc->reada_slot) { in reada_walk_down()
5320 wc->reada_count = wc->reada_count * 2 / 3; in reada_walk_down()
5321 wc->reada_count = max(wc->reada_count, 2); in reada_walk_down()
5323 wc->reada_count = wc->reada_count * 3 / 2; in reada_walk_down()
5324 wc->reada_count = min_t(int, wc->reada_count, in reada_walk_down()
5328 eb = path->nodes[wc->level]; in reada_walk_down()
5331 for (slot = path->slots[wc->level]; slot < nritems; slot++) { in reada_walk_down()
5332 if (nread >= wc->reada_count) in reada_walk_down()
5339 if (slot == path->slots[wc->level]) in reada_walk_down()
5342 if (wc->stage == UPDATE_BACKREF && in reada_walk_down()
5348 wc->level - 1, 1, &refs, in reada_walk_down()
5364 if (!visit_node_for_delete(root, wc, eb, flags, slot)) in reada_walk_down()
5370 wc->reada_slot = slot; in reada_walk_down()
5376 * when wc->stage == UPDATE_BACKREF, this function updates
5384 struct walk_control *wc) in walk_down_proc() argument
5387 int level = wc->level; in walk_down_proc()
5392 if (wc->stage == UPDATE_BACKREF && btrfs_header_owner(eb) != btrfs_root_id(root)) in walk_down_proc()
5399 if (wc->lookup_info && in walk_down_proc()
5400 ((wc->stage == DROP_REFERENCE && wc->refs[level] != 1) || in walk_down_proc()
5401 (wc->stage == UPDATE_BACKREF && !(wc->flags[level] & flag)))) { in walk_down_proc()
5405 &wc->refs[level], in walk_down_proc()
5406 &wc->flags[level], in walk_down_proc()
5410 if (unlikely(wc->refs[level] == 0)) { in walk_down_proc()
5417 if (wc->stage == DROP_REFERENCE) { in walk_down_proc()
5418 if (wc->refs[level] > 1) in walk_down_proc()
5421 if (path->locks[level] && !wc->keep_locks) { in walk_down_proc()
5428 /* wc->stage == UPDATE_BACKREF */ in walk_down_proc()
5429 if (!(wc->flags[level] & flag)) { in walk_down_proc()
5446 wc->flags[level] |= flag; in walk_down_proc()
5534 struct walk_control *wc, in check_next_block_uptodate() argument
5539 int level = wc->level; in check_next_block_uptodate()
5557 reada_walk_down(trans, root, wc, path); in check_next_block_uptodate()
5564 wc->lookup_info = 1; in check_next_block_uptodate()
5569 * If we determine that we don't have to visit wc->level - 1 then we need to
5579 struct btrfs_path *path, struct walk_control *wc, in maybe_drop_reference() argument
5589 int level = wc->level; in maybe_drop_reference()
5593 if (wc->stage == UPDATE_BACKREF) in maybe_drop_reference()
5596 if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) { in maybe_drop_reference()
5612 if (wc->restarted) { in maybe_drop_reference()
5618 wc->restarted = 0; in maybe_drop_reference()
5627 wc->refs[level - 1] > 1) { in maybe_drop_reference()
5645 wc->drop_level = level; in maybe_drop_reference()
5646 find_next_key(path, level, &wc->drop_progress); in maybe_drop_reference()
5655 * when wc->stage == DROP_REFERENCE, this function checks
5658 * rooted at the block, this function changes wc->stage to
5668 struct walk_control *wc) in do_walk_down() argument
5675 int level = wc->level; in do_walk_down()
5685 if (wc->stage == UPDATE_BACKREF && in do_walk_down()
5687 wc->lookup_info = 1; in do_walk_down()
5701 &wc->refs[level - 1], in do_walk_down()
5702 &wc->flags[level - 1], in do_walk_down()
5707 if (unlikely(wc->refs[level - 1] == 0)) { in do_walk_down()
5713 wc->lookup_info = 0; in do_walk_down()
5716 if (!visit_node_for_delete(root, wc, path->nodes[level], in do_walk_down()
5717 wc->flags[level - 1], path->slots[level])) in do_walk_down()
5725 if (wc->stage == DROP_REFERENCE && wc->refs[level - 1] > 1) { in do_walk_down()
5726 wc->stage = UPDATE_BACKREF; in do_walk_down()
5727 wc->shared_level = level - 1; in do_walk_down()
5730 ret = check_next_block_uptodate(trans, root, path, wc, next); in do_walk_down()
5744 wc->level = level; in do_walk_down()
5745 if (wc->level == 1) in do_walk_down()
5746 wc->reada_slot = 0; in do_walk_down()
5749 ret = maybe_drop_reference(trans, root, path, wc, next, owner_root); in do_walk_down()
5752 wc->refs[level - 1] = 0; in do_walk_down()
5753 wc->flags[level - 1] = 0; in do_walk_down()
5754 wc->lookup_info = 1; in do_walk_down()
5767 * when wc->stage == DROP_REFERENCE, this function drops
5770 * when wc->stage == UPDATE_BACKREF, this function changes
5771 * wc->stage back to DROP_REFERENCE if we changed wc->stage
5779 struct walk_control *wc) in walk_up_proc() argument
5783 int level = wc->level; in walk_up_proc()
5787 if (wc->stage == UPDATE_BACKREF) { in walk_up_proc()
5788 ASSERT(wc->shared_level >= level); in walk_up_proc()
5789 if (level < wc->shared_level) in walk_up_proc()
5792 ret = find_next_key(path, level + 1, &wc->update_progress); in walk_up_proc()
5794 wc->update_ref = 0; in walk_up_proc()
5796 wc->stage = DROP_REFERENCE; in walk_up_proc()
5797 wc->shared_level = -1; in walk_up_proc()
5812 &wc->refs[level], in walk_up_proc()
5813 &wc->flags[level], in walk_up_proc()
5820 if (unlikely(wc->refs[level] == 0)) { in walk_up_proc()
5826 if (wc->refs[level] == 1) { in walk_up_proc()
5834 /* wc->stage == DROP_REFERENCE */ in walk_up_proc()
5835 ASSERT(path->locks[level] || wc->refs[level] == 1); in walk_up_proc()
5837 if (wc->refs[level] == 1) { in walk_up_proc()
5839 if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) in walk_up_proc()
5865 if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) in walk_up_proc()
5870 if (wc->flags[level + 1] & BTRFS_BLOCK_FLAG_FULL_BACKREF) in walk_up_proc()
5878 wc->refs[level] == 1); in walk_up_proc()
5882 wc->refs[level] = 0; in walk_up_proc()
5883 wc->flags[level] = 0; in walk_up_proc()
5896 * wc->level. At this point path->nodes[wc->level] should be populated and
5905 * our current path->nodes[wc->level]. For DROP_REFERENCE that means dropping
5916 struct walk_control *wc) in walk_down_tree() argument
5918 int level = wc->level; in walk_down_tree()
5921 wc->lookup_info = 1; in walk_down_tree()
5923 ret = walk_down_proc(trans, root, path, wc); in walk_down_tree()
5934 ret = do_walk_down(trans, root, path, wc); in walk_down_tree()
5940 level = wc->level; in walk_down_tree()
5951 * UPDATE_BACKREF. If we wc->level is currently less than our wc->shared_level
5954 * wc->shared_level. Once we're at or above our wc->shared_level we can switch
5965 struct walk_control *wc, int max_level) in walk_up_tree() argument
5967 int level = wc->level; in walk_up_tree()
5972 wc->level = level; in walk_up_tree()
5978 ret = walk_up_proc(trans, root, path, wc); in walk_up_tree()
6018 struct walk_control *wc; in btrfs_drop_snapshot() local
6034 wc = kzalloc(sizeof(*wc), GFP_NOFS); in btrfs_drop_snapshot()
6035 if (!wc) { in btrfs_drop_snapshot()
6074 memset(&wc->update_progress, 0, in btrfs_drop_snapshot()
6075 sizeof(wc->update_progress)); in btrfs_drop_snapshot()
6078 memcpy(&wc->update_progress, &key, in btrfs_drop_snapshot()
6079 sizeof(wc->update_progress)); in btrfs_drop_snapshot()
6109 level, 1, &wc->refs[level], in btrfs_drop_snapshot()
6110 &wc->flags[level], NULL); in btrfs_drop_snapshot()
6114 BUG_ON(wc->refs[level] == 0); in btrfs_drop_snapshot()
6121 WARN_ON(wc->refs[level] != 1); in btrfs_drop_snapshot()
6126 wc->restarted = test_bit(BTRFS_ROOT_DEAD_TREE, &root->state); in btrfs_drop_snapshot()
6127 wc->level = level; in btrfs_drop_snapshot()
6128 wc->shared_level = -1; in btrfs_drop_snapshot()
6129 wc->stage = DROP_REFERENCE; in btrfs_drop_snapshot()
6130 wc->update_ref = update_ref; in btrfs_drop_snapshot()
6131 wc->keep_locks = 0; in btrfs_drop_snapshot()
6132 wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(fs_info); in btrfs_drop_snapshot()
6136 ret = walk_down_tree(trans, root, path, wc); in btrfs_drop_snapshot()
6142 ret = walk_up_tree(trans, root, path, wc, BTRFS_MAX_LEVEL); in btrfs_drop_snapshot()
6149 BUG_ON(wc->stage != DROP_REFERENCE); in btrfs_drop_snapshot()
6154 if (wc->stage == DROP_REFERENCE) { in btrfs_drop_snapshot()
6155 wc->drop_level = wc->level; in btrfs_drop_snapshot()
6156 btrfs_node_key_to_cpu(path->nodes[wc->drop_level], in btrfs_drop_snapshot()
6157 &wc->drop_progress, in btrfs_drop_snapshot()
6158 path->slots[wc->drop_level]); in btrfs_drop_snapshot()
6161 &wc->drop_progress); in btrfs_drop_snapshot()
6162 btrfs_set_root_drop_level(root_item, wc->drop_level); in btrfs_drop_snapshot()
6164 BUG_ON(wc->level == 0); in btrfs_drop_snapshot()
6248 kfree(wc); in btrfs_drop_snapshot()
6291 struct walk_control *wc; in btrfs_drop_subtree() local
6302 wc = kzalloc(sizeof(*wc), GFP_NOFS); in btrfs_drop_subtree()
6303 if (!wc) { in btrfs_drop_subtree()
6320 wc->refs[parent_level] = 1; in btrfs_drop_subtree()
6321 wc->flags[parent_level] = BTRFS_BLOCK_FLAG_FULL_BACKREF; in btrfs_drop_subtree()
6322 wc->level = level; in btrfs_drop_subtree()
6323 wc->shared_level = -1; in btrfs_drop_subtree()
6324 wc->stage = DROP_REFERENCE; in btrfs_drop_subtree()
6325 wc->update_ref = 0; in btrfs_drop_subtree()
6326 wc->keep_locks = 1; in btrfs_drop_subtree()
6327 wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(fs_info); in btrfs_drop_subtree()
6330 ret = walk_down_tree(trans, root, path, wc); in btrfs_drop_subtree()
6334 ret = walk_up_tree(trans, root, path, wc, parent_level); in btrfs_drop_subtree()
6342 kfree(wc); in btrfs_drop_subtree()