Lines Matching full:wc
5277 * @wc: the walk control for this deletion
5279 * @refs: the number of refs for wc->level - 1
5280 * @flags: the flags for wc->level - 1
5284 * wc->level should be read and walked into, or if we can simply delete our
5292 static bool visit_node_for_delete(struct btrfs_root *root, struct walk_control *wc, in visit_node_for_delete() argument
5297 int level = wc->level; in visit_node_for_delete()
5300 ASSERT(wc->refs[level - 1] > 0); in visit_node_for_delete()
5306 if (wc->stage == UPDATE_BACKREF) { in visit_node_for_delete()
5316 if (wc->refs[level - 1] == 1) in visit_node_for_delete()
5331 if (!wc->update_ref || generation <= btrfs_root_origin_generation(root)) in visit_node_for_delete()
5339 if (btrfs_comp_cpu_keys(&key, &wc->update_progress) < 0) in visit_node_for_delete()
5348 struct walk_control *wc, in reada_walk_down() argument
5362 if (path->slots[wc->level] < wc->reada_slot) { in reada_walk_down()
5363 wc->reada_count = wc->reada_count * 2 / 3; in reada_walk_down()
5364 wc->reada_count = max(wc->reada_count, 2); in reada_walk_down()
5366 wc->reada_count = wc->reada_count * 3 / 2; in reada_walk_down()
5367 wc->reada_count = min_t(int, wc->reada_count, in reada_walk_down()
5371 eb = path->nodes[wc->level]; in reada_walk_down()
5374 for (slot = path->slots[wc->level]; slot < nritems; slot++) { in reada_walk_down()
5375 if (nread >= wc->reada_count) in reada_walk_down()
5382 if (slot == path->slots[wc->level]) in reada_walk_down()
5385 if (wc->stage == UPDATE_BACKREF && in reada_walk_down()
5391 wc->level - 1, 1, &refs, in reada_walk_down()
5407 if (!visit_node_for_delete(root, wc, eb, flags, slot)) in reada_walk_down()
5413 wc->reada_slot = slot; in reada_walk_down()
5419 * when wc->stage == UPDATE_BACKREF, this function updates
5427 struct walk_control *wc) in walk_down_proc() argument
5430 int level = wc->level; in walk_down_proc()
5435 if (wc->stage == UPDATE_BACKREF && btrfs_header_owner(eb) != btrfs_root_id(root)) in walk_down_proc()
5442 if (wc->lookup_info && in walk_down_proc()
5443 ((wc->stage == DROP_REFERENCE && wc->refs[level] != 1) || in walk_down_proc()
5444 (wc->stage == UPDATE_BACKREF && !(wc->flags[level] & flag)))) { in walk_down_proc()
5448 &wc->refs[level], in walk_down_proc()
5449 &wc->flags[level], in walk_down_proc()
5453 if (unlikely(wc->refs[level] == 0)) { in walk_down_proc()
5460 if (wc->stage == DROP_REFERENCE) { in walk_down_proc()
5461 if (wc->refs[level] > 1) in walk_down_proc()
5464 if (path->locks[level] && !wc->keep_locks) { in walk_down_proc()
5471 /* wc->stage == UPDATE_BACKREF */ in walk_down_proc()
5472 if (!(wc->flags[level] & flag)) { in walk_down_proc()
5489 wc->flags[level] |= flag; in walk_down_proc()
5575 struct walk_control *wc, in check_next_block_uptodate() argument
5580 int level = wc->level; in check_next_block_uptodate()
5598 reada_walk_down(trans, root, wc, path); in check_next_block_uptodate()
5605 wc->lookup_info = 1; in check_next_block_uptodate()
5610 * If we determine that we don't have to visit wc->level - 1 then we need to
5620 struct btrfs_path *path, struct walk_control *wc, in maybe_drop_reference() argument
5630 int level = wc->level; in maybe_drop_reference()
5634 if (wc->stage == UPDATE_BACKREF) in maybe_drop_reference()
5637 if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) { in maybe_drop_reference()
5653 if (wc->restarted) { in maybe_drop_reference()
5659 wc->restarted = 0; in maybe_drop_reference()
5668 wc->refs[level - 1] > 1) { in maybe_drop_reference()
5686 wc->drop_level = level; in maybe_drop_reference()
5687 find_next_key(path, level, &wc->drop_progress); in maybe_drop_reference()
5696 * when wc->stage == DROP_REFERENCE, this function checks
5699 * rooted at the block, this function changes wc->stage to
5709 struct walk_control *wc) in do_walk_down() argument
5716 int level = wc->level; in do_walk_down()
5726 if (wc->stage == UPDATE_BACKREF && in do_walk_down()
5728 wc->lookup_info = 1; in do_walk_down()
5742 &wc->refs[level - 1], in do_walk_down()
5743 &wc->flags[level - 1], in do_walk_down()
5748 if (unlikely(wc->refs[level - 1] == 0)) { in do_walk_down()
5754 wc->lookup_info = 0; in do_walk_down()
5757 if (!visit_node_for_delete(root, wc, path->nodes[level], in do_walk_down()
5758 wc->flags[level - 1], path->slots[level])) in do_walk_down()
5766 if (wc->stage == DROP_REFERENCE && wc->refs[level - 1] > 1) { in do_walk_down()
5767 wc->stage = UPDATE_BACKREF; in do_walk_down()
5768 wc->shared_level = level - 1; in do_walk_down()
5771 ret = check_next_block_uptodate(trans, root, path, wc, next); in do_walk_down()
5785 wc->level = level; in do_walk_down()
5786 if (wc->level == 1) in do_walk_down()
5787 wc->reada_slot = 0; in do_walk_down()
5790 ret = maybe_drop_reference(trans, root, path, wc, next, owner_root); in do_walk_down()
5793 wc->refs[level - 1] = 0; in do_walk_down()
5794 wc->flags[level - 1] = 0; in do_walk_down()
5795 wc->lookup_info = 1; in do_walk_down()
5808 * when wc->stage == DROP_REFERENCE, this function drops
5811 * when wc->stage == UPDATE_BACKREF, this function changes
5812 * wc->stage back to DROP_REFERENCE if we changed wc->stage
5820 struct walk_control *wc) in walk_up_proc() argument
5824 int level = wc->level; in walk_up_proc()
5828 if (wc->stage == UPDATE_BACKREF) { in walk_up_proc()
5829 ASSERT(wc->shared_level >= level); in walk_up_proc()
5830 if (level < wc->shared_level) in walk_up_proc()
5833 ret = find_next_key(path, level + 1, &wc->update_progress); in walk_up_proc()
5835 wc->update_ref = 0; in walk_up_proc()
5837 wc->stage = DROP_REFERENCE; in walk_up_proc()
5838 wc->shared_level = -1; in walk_up_proc()
5853 &wc->refs[level], in walk_up_proc()
5854 &wc->flags[level], in walk_up_proc()
5861 if (unlikely(wc->refs[level] == 0)) { in walk_up_proc()
5867 if (wc->refs[level] == 1) { in walk_up_proc()
5875 /* wc->stage == DROP_REFERENCE */ in walk_up_proc()
5876 ASSERT(path->locks[level] || wc->refs[level] == 1); in walk_up_proc()
5878 if (wc->refs[level] == 1) { in walk_up_proc()
5880 if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) { in walk_up_proc()
5911 if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) in walk_up_proc()
5916 if (wc->flags[level + 1] & BTRFS_BLOCK_FLAG_FULL_BACKREF) in walk_up_proc()
5924 wc->refs[level] == 1); in walk_up_proc()
5928 wc->refs[level] = 0; in walk_up_proc()
5929 wc->flags[level] = 0; in walk_up_proc()
5942 * wc->level. At this point path->nodes[wc->level] should be populated and
5951 * our current path->nodes[wc->level]. For DROP_REFERENCE that means dropping
5962 struct walk_control *wc) in walk_down_tree() argument
5964 int level = wc->level; in walk_down_tree()
5967 wc->lookup_info = 1; in walk_down_tree()
5969 ret = walk_down_proc(trans, root, path, wc); in walk_down_tree()
5980 ret = do_walk_down(trans, root, path, wc); in walk_down_tree()
5986 level = wc->level; in walk_down_tree()
5997 * UPDATE_BACKREF. If we wc->level is currently less than our wc->shared_level
6000 * wc->shared_level. Once we're at or above our wc->shared_level we can switch
6011 struct walk_control *wc, int max_level) in walk_up_tree() argument
6013 int level = wc->level; in walk_up_tree()
6018 wc->level = level; in walk_up_tree()
6024 ret = walk_up_proc(trans, root, path, wc); in walk_up_tree()
6064 struct walk_control *wc; in btrfs_drop_snapshot() local
6080 wc = kzalloc(sizeof(*wc), GFP_NOFS); in btrfs_drop_snapshot()
6081 if (!wc) { in btrfs_drop_snapshot()
6120 memset(&wc->update_progress, 0, in btrfs_drop_snapshot()
6121 sizeof(wc->update_progress)); in btrfs_drop_snapshot()
6124 memcpy(&wc->update_progress, &key, in btrfs_drop_snapshot()
6125 sizeof(wc->update_progress)); in btrfs_drop_snapshot()
6155 level, 1, &wc->refs[level], in btrfs_drop_snapshot()
6156 &wc->flags[level], NULL); in btrfs_drop_snapshot()
6160 BUG_ON(wc->refs[level] == 0); in btrfs_drop_snapshot()
6167 WARN_ON(wc->refs[level] != 1); in btrfs_drop_snapshot()
6172 wc->restarted = test_bit(BTRFS_ROOT_DEAD_TREE, &root->state); in btrfs_drop_snapshot()
6173 wc->level = level; in btrfs_drop_snapshot()
6174 wc->shared_level = -1; in btrfs_drop_snapshot()
6175 wc->stage = DROP_REFERENCE; in btrfs_drop_snapshot()
6176 wc->update_ref = update_ref; in btrfs_drop_snapshot()
6177 wc->keep_locks = 0; in btrfs_drop_snapshot()
6178 wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(fs_info); in btrfs_drop_snapshot()
6182 ret = walk_down_tree(trans, root, path, wc); in btrfs_drop_snapshot()
6188 ret = walk_up_tree(trans, root, path, wc, BTRFS_MAX_LEVEL); in btrfs_drop_snapshot()
6195 BUG_ON(wc->stage != DROP_REFERENCE); in btrfs_drop_snapshot()
6200 if (wc->stage == DROP_REFERENCE) { in btrfs_drop_snapshot()
6201 wc->drop_level = wc->level; in btrfs_drop_snapshot()
6202 btrfs_node_key_to_cpu(path->nodes[wc->drop_level], in btrfs_drop_snapshot()
6203 &wc->drop_progress, in btrfs_drop_snapshot()
6204 path->slots[wc->drop_level]); in btrfs_drop_snapshot()
6207 &wc->drop_progress); in btrfs_drop_snapshot()
6208 btrfs_set_root_drop_level(root_item, wc->drop_level); in btrfs_drop_snapshot()
6210 BUG_ON(wc->level == 0); in btrfs_drop_snapshot()
6294 kfree(wc); in btrfs_drop_snapshot()
6337 struct walk_control *wc; in btrfs_drop_subtree() local
6348 wc = kzalloc(sizeof(*wc), GFP_NOFS); in btrfs_drop_subtree()
6349 if (!wc) in btrfs_drop_subtree()
6364 wc->refs[parent_level] = 1; in btrfs_drop_subtree()
6365 wc->flags[parent_level] = BTRFS_BLOCK_FLAG_FULL_BACKREF; in btrfs_drop_subtree()
6366 wc->level = level; in btrfs_drop_subtree()
6367 wc->shared_level = -1; in btrfs_drop_subtree()
6368 wc->stage = DROP_REFERENCE; in btrfs_drop_subtree()
6369 wc->update_ref = 0; in btrfs_drop_subtree()
6370 wc->keep_locks = 1; in btrfs_drop_subtree()
6371 wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(fs_info); in btrfs_drop_subtree()
6374 ret = walk_down_tree(trans, root, path, wc); in btrfs_drop_subtree()
6378 ret = walk_up_tree(trans, root, path, wc, parent_level); in btrfs_drop_subtree()
6386 kfree(wc); in btrfs_drop_subtree()