// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2009 Oracle.  All rights reserved.
 */

#include <linux/sched.h>
#include <linux/pagemap.h>
#include <linux/writeback.h>
#include <linux/blkdev.h>
#include <linux/rbtree.h>
#include <linux/slab.h>
#include <linux/error-injection.h>
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
#include "volumes.h"
#include "locking.h"
#include "btrfs_inode.h"
#include "async-thread.h"
#include "free-space-cache.h"
#include "qgroup.h"
#include "print-tree.h"
#include "delalloc-space.h"
#include "block-group.h"
#include "backref.h"
#include "misc.h"
#include "subpage.h"
#include "zoned.h"
#include "inode-item.h"
#include "space-info.h"
#include "fs.h"
#include "accessors.h"
#include "extent-tree.h"
#include "root-tree.h"
#include "file-item.h"
#include "relocation.h"
#include "super.h"
#include "tree-checker.h"
#include "raid-stripe-tree.h"
#include "free-space-tree.h"

/*
 * Relocation overview
 *
 * [What does relocation do]
 *
 * The objective of relocation is to relocate all extents of the target block
 * group to other block groups.
 * This is utilized by resize (shrink only), profile converting, compacting
 * space, or balance routine to spread chunks over devices.
 *
 * 		Before		|		After
 * ------------------------------------------------------------------
 *  BG A: 10 data extents	| BG A: deleted
 *  BG B:  2 data extents	| BG B: 10 data extents (2 old + 8 relocated)
 *  BG C:  1 extents		| BG C:  3 data extents (1 old + 2 relocated)
 *
 * [How does relocation work]
 *
 * 1.   Mark the target block group read-only
 *      New extents won't be allocated from the target block group.
 *
 * 2.1  Record each extent in the target block group
 *      To build a proper map of extents to be relocated.
 *
 * 2.2  Build data reloc tree and reloc trees
 *      Data reloc tree will contain an inode, recording all newly relocated
 *      data extents.
 *      There will be only one data reloc tree for one data block group.
 *
 *      Reloc tree will be a special snapshot of its source tree, containing
 *      relocated tree blocks.
 *      Each tree referring to a tree block in target block group will get its
 *      reloc tree built.
 *
 * 2.3  Swap source tree with its corresponding reloc tree
 *      Each involved tree only refers to new extents after swap.
 *
 * 3.   Cleanup reloc trees and data reloc tree.
 *      As old extents in the target block group are still referenced by reloc
 *      trees, we need to clean them up before really freeing the target block
 *      group.
 *
 * The main complexity is in steps 2.2 and 2.3.
 *
 * The entry point of relocation is relocate_block_group() function.
 */

#define RELOCATION_RESERVED_NODES	256
/*
 * map address of tree root to tree
 */
struct mapping_node {
	union {
		/* Use rb_simple_node for search/insert */
		struct {
			struct rb_node rb_node;
			u64 bytenr;
		};

		struct rb_simple_node simple_node;
	};
	void *data;
};

struct mapping_tree {
	struct rb_root rb_root;
	spinlock_t lock;
};

/*
 * present a tree block to process
 */
struct tree_block {
	union {
		/* Use rb_simple_node for search/insert */
		struct {
			struct rb_node rb_node;
			u64 bytenr;
		};

		struct rb_simple_node simple_node;
	};
	u64 owner;
	struct btrfs_key key;
	u8 level;
	bool key_ready;
};

#define MAX_EXTENTS 128

struct file_extent_cluster {
	u64 start;
	u64 end;
	u64 boundary[MAX_EXTENTS];
	unsigned int nr;
	u64 owning_root;
};

/* Stages of data relocation. */
enum reloc_stage {
	MOVE_DATA_EXTENTS,
	UPDATE_DATA_PTRS
};

struct reloc_control {
	/* block group to relocate */
	struct btrfs_block_group *block_group;
	/* extent tree */
	struct btrfs_root *extent_root;
	/* inode for moving data */
	struct inode *data_inode;

	struct btrfs_block_rsv *block_rsv;

	struct btrfs_backref_cache backref_cache;

	struct file_extent_cluster cluster;
	/* tree blocks have been processed */
	struct extent_io_tree processed_blocks;
	/* map start of tree root to corresponding reloc tree */
	struct mapping_tree reloc_root_tree;
	/* list of reloc trees */
	struct list_head reloc_roots;
	/* list of subvolume trees that get relocated */
	struct list_head dirty_subvol_roots;
	/* size of metadata reservation for merging reloc trees */
	u64 merging_rsv_size;
	/* size of relocated tree nodes */
	u64 nodes_relocated;
	/* reserved size for block group relocation*/
	u64 reserved_bytes;

	u64 search_start;
	u64 extents_found;

	enum reloc_stage stage;
	bool create_reloc_tree;
	bool merge_reloc_tree;
	bool found_file_extent;
};

static void mark_block_processed(struct reloc_control *rc,
				 struct btrfs_backref_node *node)
{
	u32 blocksize;

	if (node->level == 0 ||
	    in_range(node->bytenr, rc->block_group->start,
		     rc->block_group->length)) {
		blocksize = rc->extent_root->fs_info->nodesize;
		btrfs_set_extent_bit(&rc->processed_blocks, node->bytenr,
				     node->bytenr + blocksize - 1, EXTENT_DIRTY,
				     NULL);
	}
	node->processed = 1;
}

/*
 * walk up backref nodes until reach node presents tree root
 */
static struct btrfs_backref_node *walk_up_backref(
		struct btrfs_backref_node *node,
		struct btrfs_backref_edge *edges[], int *index)
{
	struct btrfs_backref_edge *edge;
	int idx = *index;

	while (!list_empty(&node->upper)) {
		edge = list_first_entry(&node->upper, struct btrfs_backref_edge,
					list[LOWER]);
		edges[idx++] = edge;
		node = edge->node[UPPER];
	}
	BUG_ON(node->detached);
	*index = idx;
	return node;
}

/*
 * walk down backref nodes to find start of next reference path
 */
static struct btrfs_backref_node *walk_down_backref(
		struct btrfs_backref_edge *edges[], int *index)
{
	struct btrfs_backref_edge *edge;
	struct btrfs_backref_node *lower;
	int idx = *index;

	while (idx > 0) {
		edge = edges[idx - 1];
		lower = edge->node[LOWER];
		if (list_is_last(&edge->list[LOWER], &lower->upper)) {
			idx--;
			continue;
		}
		edge = list_first_entry(&edge->list[LOWER], struct btrfs_backref_edge,
					list[LOWER]);
		edges[idx - 1] = edge;
		*index = idx;
		return edge->node[UPPER];
	}
	*index = 0;
	return NULL;
}

static bool reloc_root_is_dead(const struct btrfs_root *root)
{
	/*
	 * Pair with set_bit/clear_bit in clean_dirty_subvols and
	 * btrfs_update_reloc_root. We need to see the updated bit before
	 * trying to access reloc_root
	 */
	smp_rmb();
	if (test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state))
		return true;
	return false;
}

/*
 * Check if this subvolume tree has valid reloc tree.
 *
 * Reloc tree after swap is considered dead, thus not considered as valid.
 * This is enough for most callers, as they don't distinguish dead reloc root
 * from no reloc root.  But btrfs_should_ignore_reloc_root() below is a
 * special case.
 */
static bool have_reloc_root(const struct btrfs_root *root)
{
	if (reloc_root_is_dead(root))
		return false;
	if (!root->reloc_root)
		return false;
	return true;
}

bool btrfs_should_ignore_reloc_root(const struct btrfs_root *root)
{
	struct btrfs_root *reloc_root;

	if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
		return false;

	/* This root has been merged with its reloc tree, we can ignore it */
	if (reloc_root_is_dead(root))
		return true;

	reloc_root = root->reloc_root;
	if (!reloc_root)
		return false;

	if (btrfs_header_generation(reloc_root->commit_root) ==
	    root->fs_info->running_transaction->transid)
		return false;
	/*
	 * If there is reloc tree and it was created in previous transaction
	 * backref lookup can find the reloc tree, so backref node for the fs
	 * tree root is useless for relocation.
	 */
	return true;
}

/*
 * find reloc tree by address of tree root
 */
struct btrfs_root *find_reloc_root(struct btrfs_fs_info *fs_info, u64 bytenr)
{
	struct reloc_control *rc = fs_info->reloc_ctl;
	struct rb_node *rb_node;
	struct mapping_node *node;
	struct btrfs_root *root = NULL;

	ASSERT(rc);
	spin_lock(&rc->reloc_root_tree.lock);
	rb_node = rb_simple_search(&rc->reloc_root_tree.rb_root, bytenr);
	if (rb_node) {
		node = rb_entry(rb_node, struct mapping_node, rb_node);
		root = node->data;
	}
	spin_unlock(&rc->reloc_root_tree.lock);
	return btrfs_grab_root(root);
}

/*
 * For useless nodes, do two major clean ups:
 *
 * - Cleanup the children edges and nodes
 *   If child node is also orphan (no parent) during cleanup, then the child
 *   node will also be cleaned up.
 *
 * - Freeing up leaves (level 0), keeps nodes detached
 *   For nodes, the node is still cached as "detached"
 *
 * Return false if @node is not in the @useless_nodes list.
 * Return true if @node is in the @useless_nodes list.
 */
static bool handle_useless_nodes(struct reloc_control *rc,
				 struct btrfs_backref_node *node)
{
	struct btrfs_backref_cache *cache = &rc->backref_cache;
	struct list_head *useless_node = &cache->useless_node;
	bool ret = false;

	while (!list_empty(useless_node)) {
		struct btrfs_backref_node *cur;

		cur = list_first_entry(useless_node, struct btrfs_backref_node,
				 list);
		list_del_init(&cur->list);

		/* Only tree root nodes can be added to @useless_nodes */
		ASSERT(list_empty(&cur->upper));

		if (cur == node)
			ret = true;

		/* Cleanup the lower edges */
		while (!list_empty(&cur->lower)) {
			struct btrfs_backref_edge *edge;
			struct btrfs_backref_node *lower;

			edge = list_first_entry(&cur->lower, struct btrfs_backref_edge,
						list[UPPER]);
			list_del(&edge->list[UPPER]);
			list_del(&edge->list[LOWER]);
			lower = edge->node[LOWER];
			btrfs_backref_free_edge(cache, edge);

			/* Child node is also orphan, queue for cleanup */
			if (list_empty(&lower->upper))
				list_add(&lower->list, useless_node);
		}
		/* Mark this block processed for relocation */
		mark_block_processed(rc, cur);

		/*
		 * Backref nodes for tree leaves are deleted from the cache.
		 * Backref nodes for upper level tree blocks are left in the
		 * cache to avoid unnecessary backref lookup.
		 */
		if (cur->level > 0) {
			cur->detached = 1;
		} else {
			rb_erase(&cur->rb_node, &cache->rb_root);
			btrfs_backref_free_node(cache, cur);
		}
	}
	return ret;
}

/*
 * Build backref tree for a given tree block. Root of the backref tree
 * corresponds the tree block, leaves of the backref tree correspond roots of
 * b-trees that reference the tree block.
 *
 * The basic idea of this function is check backrefs of a given block to find
 * upper level blocks that reference the block, and then check backrefs of
 * these upper level blocks recursively. The recursion stops when tree root is
 * reached or backrefs for the block is cached.
 *
 * NOTE: if we find that backrefs for a block are cached, we know backrefs for
 * all upper level blocks that directly/indirectly reference the block are also
 * cached.
 */
static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
			struct btrfs_trans_handle *trans,
			struct reloc_control *rc, struct btrfs_key *node_key,
			int level, u64 bytenr)
{
	struct btrfs_backref_iter *iter;
	struct btrfs_backref_cache *cache = &rc->backref_cache;
	/* For searching parent of TREE_BLOCK_REF */
	struct btrfs_path *path;
	struct btrfs_backref_node *cur;
	struct btrfs_backref_node *node = NULL;
	struct btrfs_backref_edge *edge;
	int ret;

	iter = btrfs_backref_iter_alloc(rc->extent_root->fs_info);
	if (!iter)
		return ERR_PTR(-ENOMEM);
	path = btrfs_alloc_path();
	if (!path) {
		ret = -ENOMEM;
		goto out;
	}

	node = btrfs_backref_alloc_node(cache, bytenr, level);
	if (!node) {
		ret = -ENOMEM;
		goto out;
	}

	cur = node;

	/* Breadth-first search to build backref cache */
	do {
		ret = btrfs_backref_add_tree_node(trans, cache, path, iter,
						  node_key, cur);
		if (ret < 0)
			goto out;

		edge = list_first_entry_or_null(&cache->pending_edge,
				struct btrfs_backref_edge, list[UPPER]);
		/*
		 * The pending list isn't empty, take the first block to
		 * process
		 */
		if (edge) {
			list_del_init(&edge->list[UPPER]);
			cur = edge->node[UPPER];
		}
	} while (edge);

	/* Finish the upper linkage of newly added edges/nodes */
	ret = btrfs_backref_finish_upper_links(cache, node);
	if (ret < 0)
		goto out;

	if (handle_useless_nodes(rc, node))
		node = NULL;
out:
	btrfs_free_path(iter->path);
	kfree(iter);
	btrfs_free_path(path);
	if (ret) {
		btrfs_backref_error_cleanup(cache, node);
		return ERR_PTR(ret);
	}
	ASSERT(!node || !node->detached);
	ASSERT(list_empty(&cache->useless_node) &&
	       list_empty(&cache->pending_edge));
	return node;
}

/*
 * helper to add 'address of tree root -> reloc tree' mapping
 */
static int __add_reloc_root(struct btrfs_root *root)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct rb_node *rb_node;
	struct mapping_node *node;
	struct reloc_control *rc = fs_info->reloc_ctl;

	node = kmalloc_obj(*node, GFP_NOFS);
	if (!node)
		return -ENOMEM;

	node->bytenr = root->commit_root->start;
	node->data = root;

	spin_lock(&rc->reloc_root_tree.lock);
	rb_node = rb_simple_insert(&rc->reloc_root_tree.rb_root, &node->simple_node);
	spin_unlock(&rc->reloc_root_tree.lock);
	if (rb_node) {
		btrfs_err(fs_info,
			    "Duplicate root found for start=%llu while inserting into relocation tree",
			    node->bytenr);
		return -EEXIST;
	}

	list_add_tail(&root->root_list, &rc->reloc_roots);
	return 0;
}

/*
 * helper to delete the 'address of tree root -> reloc tree'
 * mapping
 */
static void __del_reloc_root(struct btrfs_root *root)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct rb_node *rb_node;
	struct mapping_node AUTO_KFREE(node);
	struct reloc_control *rc = fs_info->reloc_ctl;
	bool put_ref = false;

	if (rc && root->node) {
		spin_lock(&rc->reloc_root_tree.lock);
		rb_node = rb_simple_search(&rc->reloc_root_tree.rb_root,
					   root->commit_root->start);
		if (rb_node) {
			node = rb_entry(rb_node, struct mapping_node, rb_node);
			rb_erase(&node->rb_node, &rc->reloc_root_tree.rb_root);
			RB_CLEAR_NODE(&node->rb_node);
		}
		spin_unlock(&rc->reloc_root_tree.lock);
		ASSERT(!node || (struct btrfs_root *)node->data == root);
	}

	/*
	 * We only put the reloc root here if it's on the list.  There's a lot
	 * of places where the pattern is to splice the rc->reloc_roots, process
	 * the reloc roots, and then add the reloc root back onto
	 * rc->reloc_roots.  If we call __del_reloc_root while it's off of the
	 * list we don't want the reference being dropped, because the guy
	 * messing with the list is in charge of the reference.
	 */
	spin_lock(&fs_info->trans_lock);
	if (!list_empty(&root->root_list)) {
		put_ref = true;
		list_del_init(&root->root_list);
	}
	spin_unlock(&fs_info->trans_lock);
	if (put_ref)
		btrfs_put_root(root);
}

/*
 * helper to update the 'address of tree root -> reloc tree'
 * mapping
 */
static int __update_reloc_root(struct btrfs_root *root)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct rb_node *rb_node;
	struct mapping_node *node = NULL;
	struct reloc_control *rc = fs_info->reloc_ctl;

	spin_lock(&rc->reloc_root_tree.lock);
	rb_node = rb_simple_search(&rc->reloc_root_tree.rb_root,
				   root->commit_root->start);
	if (rb_node) {
		node = rb_entry(rb_node, struct mapping_node, rb_node);
		rb_erase(&node->rb_node, &rc->reloc_root_tree.rb_root);
	}
	spin_unlock(&rc->reloc_root_tree.lock);

	if (!node)
		return 0;
	BUG_ON((struct btrfs_root *)node->data != root);

	spin_lock(&rc->reloc_root_tree.lock);
	node->bytenr = root->node->start;
	rb_node = rb_simple_insert(&rc->reloc_root_tree.rb_root, &node->simple_node);
	spin_unlock(&rc->reloc_root_tree.lock);
	if (rb_node)
		btrfs_backref_panic(fs_info, node->bytenr, -EEXIST);
	return 0;
}

static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
					struct btrfs_root *root, u64 objectid)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_root *reloc_root;
	struct extent_buffer *eb;
	struct btrfs_root_item AUTO_KFREE(root_item);
	struct btrfs_key root_key;
	int ret = 0;

	root_item = kmalloc(sizeof(*root_item), GFP_NOFS);
	if (!root_item)
		return ERR_PTR(-ENOMEM);

	root_key.objectid = BTRFS_TREE_RELOC_OBJECTID;
	root_key.type = BTRFS_ROOT_ITEM_KEY;
	root_key.offset = objectid;

	if (btrfs_root_id(root) == objectid) {
		u64 commit_root_gen;

		/*
		 * Relocation will wait for cleaner thread, and any half-dropped
		 * subvolume will be fully cleaned up at mount time.
		 * So here we shouldn't hit a subvolume with non-zero drop_progress.
		 *
		 * If this isn't the case, error out since it can make us attempt to
		 * drop references for extents that were already dropped before.
		 */
		if (unlikely(btrfs_disk_key_objectid(&root->root_item.drop_progress))) {
			struct btrfs_key cpu_key;

			btrfs_disk_key_to_cpu(&cpu_key, &root->root_item.drop_progress);
			btrfs_err(fs_info,
	"cannot relocate partially dropped subvolume %llu, drop progress key " BTRFS_KEY_FMT,
				  objectid, BTRFS_KEY_FMT_VALUE(&cpu_key));
			return ERR_PTR(-EUCLEAN);
		}

		/* called by btrfs_init_reloc_root */
		ret = btrfs_copy_root(trans, root, root->commit_root, &eb,
				      BTRFS_TREE_RELOC_OBJECTID);
		if (ret)
			return ERR_PTR(ret);

		/*
		 * Set the last_snapshot field to the generation of the commit
		 * root - like this ctree.c:btrfs_block_can_be_shared() behaves
		 * correctly (returns true) when the relocation root is created
		 * either inside the critical section of a transaction commit
		 * (through transaction.c:qgroup_account_snapshot()) and when
		 * it's created before the transaction commit is started.
		 */
		commit_root_gen = btrfs_header_generation(root->commit_root);
		btrfs_set_root_last_snapshot(&root->root_item, commit_root_gen);
	} else {
		/*
		 * called by btrfs_reloc_post_snapshot_hook.
		 * the source tree is a reloc tree, all tree blocks
		 * modified after it was created have RELOC flag
		 * set in their headers. so it's OK to not update
		 * the 'last_snapshot'.
		 */
		ret = btrfs_copy_root(trans, root, root->node, &eb,
				      BTRFS_TREE_RELOC_OBJECTID);
		if (ret)
			return ERR_PTR(ret);
	}

	/*
	 * We have changed references at this point, we must abort the
	 * transaction if anything fails (i.e. 'goto abort').
	 */

	memcpy(root_item, &root->root_item, sizeof(*root_item));
	btrfs_set_root_bytenr(root_item, eb->start);
	btrfs_set_root_level(root_item, btrfs_header_level(eb));
	btrfs_set_root_generation(root_item, trans->transid);

	if (btrfs_root_id(root) == objectid) {
		btrfs_set_root_refs(root_item, 0);
		memset(&root_item->drop_progress, 0,
		       sizeof(struct btrfs_disk_key));
		btrfs_set_root_drop_level(root_item, 0);
	}

	btrfs_tree_unlock(eb);
	free_extent_buffer(eb);

	ret = btrfs_insert_root(trans, fs_info->tree_root,
				&root_key, root_item);
	if (ret)
		goto abort;

	reloc_root = btrfs_read_tree_root(fs_info->tree_root, &root_key);
	if (IS_ERR(reloc_root)) {
		ret = PTR_ERR(reloc_root);
		goto abort;
	}
	set_bit(BTRFS_ROOT_SHAREABLE, &reloc_root->state);
	btrfs_set_root_last_trans(reloc_root, trans->transid);
	return reloc_root;

abort:
	btrfs_abort_transaction(trans, ret);
	return ERR_PTR(ret);
}

/*
 * create reloc tree for a given fs tree. reloc tree is just a
 * snapshot of the fs tree with special root objectid.
 *
 * The reloc_root comes out of here with two references, one for
 * root->reloc_root, and another for being on the rc->reloc_roots list.
 */
int btrfs_init_reloc_root(struct btrfs_trans_handle *trans,
			  struct btrfs_root *root)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_root *reloc_root;
	struct reloc_control *rc = fs_info->reloc_ctl;
	struct btrfs_block_rsv *rsv;
	int clear_rsv = 0;
	int ret;

	if (!rc)
		return 0;

	/*
	 * The subvolume has reloc tree but the swap is finished, no need to
	 * create/update the dead reloc tree
	 */
	if (reloc_root_is_dead(root))
		return 0;

	/*
	 * This is subtle but important.  We do not do
	 * record_root_in_transaction for reloc roots, instead we record their
	 * corresponding fs root, and then here we update the last trans for the
	 * reloc root.  This means that we have to do this for the entire life
	 * of the reloc root, regardless of which stage of the relocation we are
	 * in.
	 */
	if (root->reloc_root) {
		reloc_root = root->reloc_root;
		btrfs_set_root_last_trans(reloc_root, trans->transid);
		return 0;
	}

	/*
	 * We are merging reloc roots, we do not need new reloc trees.  Also
	 * reloc trees never need their own reloc tree.
	 */
	if (!rc->create_reloc_tree || btrfs_root_id(root) == BTRFS_TREE_RELOC_OBJECTID)
		return 0;

	if (!trans->reloc_reserved) {
		rsv = trans->block_rsv;
		trans->block_rsv = rc->block_rsv;
		clear_rsv = 1;
	}
	reloc_root = create_reloc_root(trans, root, btrfs_root_id(root));
	if (clear_rsv)
		trans->block_rsv = rsv;
	if (IS_ERR(reloc_root))
		return PTR_ERR(reloc_root);

	ret = __add_reloc_root(reloc_root);
	ASSERT(ret != -EEXIST);
	if (ret) {
		/* Pairs with create_reloc_root */
		btrfs_put_root(reloc_root);
		return ret;
	}
	root->reloc_root = btrfs_grab_root(reloc_root);
	return 0;
}

/*
 * update root item of reloc tree
 */
int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
			    struct btrfs_root *root)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_root *reloc_root;
	struct btrfs_root_item *root_item;
	int ret;

	if (!have_reloc_root(root))
		return 0;

	reloc_root = root->reloc_root;
	root_item = &reloc_root->root_item;

	/*
	 * We are probably ok here, but __del_reloc_root() will drop its ref of
	 * the root.  We have the ref for root->reloc_root, but just in case
	 * hold it while we update the reloc root.
	 */
	btrfs_grab_root(reloc_root);

	/* root->reloc_root will stay until current relocation finished */
	if (fs_info->reloc_ctl && fs_info->reloc_ctl->merge_reloc_tree &&
	    btrfs_root_refs(root_item) == 0) {
		set_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
		/*
		 * Mark the tree as dead before we change reloc_root so
		 * have_reloc_root will not touch it from now on.
		 */
		smp_wmb();
		__del_reloc_root(reloc_root);
	}

	if (reloc_root->commit_root != reloc_root->node) {
		__update_reloc_root(reloc_root);
		btrfs_set_root_node(root_item, reloc_root->node);
		free_extent_buffer(reloc_root->commit_root);
		reloc_root->commit_root = btrfs_root_node(reloc_root);
	}

	ret = btrfs_update_root(trans, fs_info->tree_root,
				&reloc_root->root_key, root_item);
	btrfs_put_root(reloc_root);
	return ret;
}

/*
 * get new location of data
 */
static int get_new_location(struct inode *reloc_inode, u64 *new_bytenr,
			    u64 bytenr, u64 num_bytes)
{
	struct btrfs_root *root = BTRFS_I(reloc_inode)->root;
	BTRFS_PATH_AUTO_FREE(path);
	struct btrfs_file_extent_item *fi;
	struct extent_buffer *leaf;
	int ret;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;

	bytenr -= BTRFS_I(reloc_inode)->reloc_block_group_start;
	ret = btrfs_lookup_file_extent(NULL, root, path,
			btrfs_ino(BTRFS_I(reloc_inode)), bytenr, 0);
	if (ret < 0)
		return ret;
	if (ret > 0)
		return -ENOENT;

	leaf = path->nodes[0];
	fi = btrfs_item_ptr(leaf, path->slots[0],
			    struct btrfs_file_extent_item);

	BUG_ON(btrfs_file_extent_offset(leaf, fi) ||
	       btrfs_file_extent_compression(leaf, fi) ||
	       btrfs_file_extent_encryption(leaf, fi) ||
	       btrfs_file_extent_other_encoding(leaf, fi));

	if (num_bytes != btrfs_file_extent_disk_num_bytes(leaf, fi))
		return -EINVAL;

	*new_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
	return 0;
}

/*
 * update file extent items in the tree leaf to point to
 * the new locations.
 */
static noinline_for_stack
int replace_file_extents(struct btrfs_trans_handle *trans,
			 struct reloc_control *rc,
			 struct btrfs_root *root,
			 struct extent_buffer *leaf)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_key key;
	struct btrfs_file_extent_item *fi;
	struct btrfs_inode *inode = NULL;
	u64 parent;
	u64 bytenr;
	u64 new_bytenr = 0;
	u64 num_bytes;
	u64 end;
	u32 nritems;
	u32 i;
	int ret = 0;
	int first = 1;

	if (rc->stage != UPDATE_DATA_PTRS)
		return 0;

	/* reloc trees always use full backref */
	if (btrfs_root_id(root) == BTRFS_TREE_RELOC_OBJECTID)
		parent = leaf->start;
	else
		parent = 0;

	nritems = btrfs_header_nritems(leaf);
	for (i = 0; i < nritems; i++) {
		struct btrfs_ref ref = { 0 };

		cond_resched();
		btrfs_item_key_to_cpu(leaf, &key, i);
		if (key.type != BTRFS_EXTENT_DATA_KEY)
			continue;
		fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item);
		if (btrfs_file_extent_type(leaf, fi) ==
		    BTRFS_FILE_EXTENT_INLINE)
			continue;
		bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
		num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
		if (bytenr == 0)
			continue;
		if (!in_range(bytenr, rc->block_group->start,
			      rc->block_group->length))
			continue;

		/*
		 * if we are modifying block in fs tree, wait for read_folio
		 * to complete and drop the extent cache
		 */
		if (btrfs_root_id(root) != BTRFS_TREE_RELOC_OBJECTID) {
			if (first) {
				inode = btrfs_find_first_inode(root, key.objectid);
				first = 0;
			} else if (inode && btrfs_ino(inode) < key.objectid) {
				btrfs_add_delayed_iput(inode);
				inode = btrfs_find_first_inode(root, key.objectid);
			}
			if (inode && btrfs_ino(inode) == key.objectid) {
				struct extent_state *cached_state = NULL;

				end = key.offset +
				      btrfs_file_extent_num_bytes(leaf, fi);
				WARN_ON(!IS_ALIGNED(key.offset,
						    fs_info->sectorsize));
				WARN_ON(!IS_ALIGNED(end, fs_info->sectorsize));
				end--;
				/* Take mmap lock to serialize with reflinks. */
				if (!down_read_trylock(&inode->i_mmap_lock))
					continue;
				ret = btrfs_try_lock_extent(&inode->io_tree, key.offset,
							    end, &cached_state);
				if (!ret) {
					up_read(&inode->i_mmap_lock);
					continue;
				}

				btrfs_drop_extent_map_range(inode, key.offset, end, true);
				btrfs_unlock_extent(&inode->io_tree, key.offset, end,
						    &cached_state);
				up_read(&inode->i_mmap_lock);
			}
		}

		ret = get_new_location(rc->data_inode, &new_bytenr,
				       bytenr, num_bytes);
		if (ret) {
			/*
			 * Don't have to abort since we've not changed anything
			 * in the file extent yet.
			 */
			break;
		}

		btrfs_set_file_extent_disk_bytenr(leaf, fi, new_bytenr);

		key.offset -= btrfs_file_extent_offset(leaf, fi);
		ref.action = BTRFS_ADD_DELAYED_REF;
		ref.bytenr = new_bytenr;
		ref.num_bytes = num_bytes;
		ref.parent = parent;
		ref.owning_root = btrfs_root_id(root);
		ref.ref_root = btrfs_header_owner(leaf);
		btrfs_init_data_ref(&ref, key.objectid, key.offset,
				    btrfs_root_id(root), false);
		ret = btrfs_inc_extent_ref(trans, &ref);
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			break;
		}

		ref.action = BTRFS_DROP_DELAYED_REF;
		ref.bytenr = bytenr;
		ref.num_bytes = num_bytes;
		ref.parent = parent;
		ref.owning_root = btrfs_root_id(root);
		ref.ref_root = btrfs_header_owner(leaf);
		btrfs_init_data_ref(&ref, key.objectid, key.offset,
				    btrfs_root_id(root), false);
		ret = btrfs_free_extent(trans, &ref);
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			break;
		}
	}
	if (inode)
		btrfs_add_delayed_iput(inode);
	return ret;
}

static noinline_for_stack int memcmp_node_keys(const struct extent_buffer *eb,
					       int slot, const struct btrfs_path *path,
					       int level)
{
	struct btrfs_disk_key key1;
	struct btrfs_disk_key key2;
	btrfs_node_key(eb, &key1, slot);
	btrfs_node_key(path->nodes[level], &key2, path->slots[level]);
	return memcmp(&key1, &key2, sizeof(key1));
}

/*
 * try to replace tree blocks in fs tree with the new blocks
 * in reloc tree. tree blocks haven't been modified since the
 * reloc tree was create can be replaced.
 *
 * if a block was replaced, level of the block + 1 is returned.
 * if no block got replaced, 0 is returned. if there are other
 * errors, a negative error number is returned.
 */
static noinline_for_stack
int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
		 struct btrfs_root *dest, struct btrfs_root *src,
		 struct btrfs_path *path, struct btrfs_key *next_key,
		 int lowest_level, int max_level)
{
	struct btrfs_fs_info *fs_info = dest->fs_info;
	struct extent_buffer *eb;
	struct extent_buffer *parent;
	struct btrfs_ref ref = { 0 };
	struct btrfs_key key;
	u64 old_bytenr;
	u64 new_bytenr;
	u64 old_ptr_gen;
	u64 new_ptr_gen;
	u64 last_snapshot;
	u32 blocksize;
	int cow = 0;
	int level;
	int ret;
	int slot;

	ASSERT(btrfs_root_id(src) == BTRFS_TREE_RELOC_OBJECTID);
	ASSERT(btrfs_root_id(dest) != BTRFS_TREE_RELOC_OBJECTID);

	last_snapshot = btrfs_root_last_snapshot(&src->root_item);
again:
	slot = path->slots[lowest_level];
	btrfs_node_key_to_cpu(path->nodes[lowest_level], &key, slot);

	eb = btrfs_lock_root_node(dest);
	level = btrfs_header_level(eb);

	if (level < lowest_level) {
		btrfs_tree_unlock(eb);
		free_extent_buffer(eb);
		return 0;
	}

	if (cow) {
		ret = btrfs_cow_block(trans, dest, eb, NULL, 0, &eb,
				      BTRFS_NESTING_COW);
		if (ret) {
			btrfs_tree_unlock(eb);
			free_extent_buffer(eb);
			return ret;
		}
	}

	if (next_key) {
		next_key->objectid = (u64)-1;
		next_key->type = (u8)-1;
		next_key->offset = (u64)-1;
	}

	parent = eb;
	while (1) {
		level = btrfs_header_level(parent);
		ASSERT(level >= lowest_level);

		ret = btrfs_bin_search(parent, 0, &key, &slot);
		if (ret < 0)
			break;
		if (ret && slot > 0)
			slot--;

		if (next_key && slot + 1 < btrfs_header_nritems(parent))
			btrfs_node_key_to_cpu(parent, next_key, slot + 1);

		old_bytenr = btrfs_node_blockptr(parent, slot);
		blocksize = fs_info->nodesize;
		old_ptr_gen = btrfs_node_ptr_generation(parent, slot);

		if (level <= max_level) {
			eb = path->nodes[level];
			new_bytenr = btrfs_node_blockptr(eb,
							path->slots[level]);
			new_ptr_gen = btrfs_node_ptr_generation(eb,
							path->slots[level]);
		} else {
			new_bytenr = 0;
			new_ptr_gen = 0;
		}

		if (WARN_ON(new_bytenr > 0 && new_bytenr == old_bytenr)) {
			ret = level;
			break;
		}

		if (new_bytenr == 0 || old_ptr_gen > last_snapshot ||
		    memcmp_node_keys(parent, slot, path, level)) {
			if (level <= lowest_level) {
				ret = 0;
				break;
			}

			eb = btrfs_read_node_slot(parent, slot);
			if (IS_ERR(eb)) {
				ret = PTR_ERR(eb);
				break;
			}
			btrfs_tree_lock(eb);
			if (cow) {
				ret = btrfs_cow_block(trans, dest, eb, parent,
						      slot, &eb,
						      BTRFS_NESTING_COW);
				if (ret) {
					btrfs_tree_unlock(eb);
					free_extent_buffer(eb);
					break;
				}
			}

			btrfs_tree_unlock(parent);
			free_extent_buffer(parent);

			parent = eb;
			continue;
		}

		if (!cow) {
			btrfs_tree_unlock(parent);
			free_extent_buffer(parent);
			cow = 1;
			goto again;
		}

		btrfs_node_key_to_cpu(path->nodes[level], &key,
				      path->slots[level]);
		btrfs_release_path(path);

		path->lowest_level = level;
		set_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &src->state);
		ret = btrfs_search_slot(trans, src, &key, path, 0, 1);
		clear_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &src->state);
		path->lowest_level = 0;
		if (ret) {
			if (ret > 0)
				ret = -ENOENT;
			break;
		}

		/*
		 * Info qgroup to trace both subtrees.
		 *
		 * We must trace both trees.
		 * 1) Tree reloc subtree
		 *    If not traced, we will leak data numbers
		 * 2) Fs subtree
		 *    If not traced, we will double count old data
		 *
		 * We don't scan the subtree right now, but only record
		 * the swapped tree blocks.
		 * The real subtree rescan is delayed until we have new
		 * CoW on the subtree root node before transaction commit.
		 */
		ret = btrfs_qgroup_add_swapped_blocks(dest,
				rc->block_group, parent, slot,
				path->nodes[level], path->slots[level],
				last_snapshot);
		if (ret < 0)
			break;
		/*
		 * swap blocks in fs tree and reloc tree.
		 */
		btrfs_set_node_blockptr(parent, slot, new_bytenr);
		btrfs_set_node_ptr_generation(parent, slot, new_ptr_gen);

		btrfs_set_node_blockptr(path->nodes[level],
					path->slots[level], old_bytenr);
		btrfs_set_node_ptr_generation(path->nodes[level],
					      path->slots[level], old_ptr_gen);

		ref.action = BTRFS_ADD_DELAYED_REF;
		ref.bytenr = old_bytenr;
		ref.num_bytes = blocksize;
		ref.parent = path->nodes[level]->start;
		ref.owning_root = btrfs_root_id(src);
		ref.ref_root = btrfs_root_id(src);
		btrfs_init_tree_ref(&ref, level - 1, 0, true);
		ret = btrfs_inc_extent_ref(trans, &ref);
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			break;
		}

		ref.action = BTRFS_ADD_DELAYED_REF;
		ref.bytenr = new_bytenr;
		ref.num_bytes = blocksize;
		ref.parent = 0;
		ref.owning_root = btrfs_root_id(dest);
		ref.ref_root = btrfs_root_id(dest);
		btrfs_init_tree_ref(&ref, level - 1, 0, true);
		ret = btrfs_inc_extent_ref(trans, &ref);
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			break;
		}

		/* We don't know the real owning_root, use 0. */
		ref.action = BTRFS_DROP_DELAYED_REF;
		ref.bytenr = new_bytenr;
		ref.num_bytes = blocksize;
		ref.parent = path->nodes[level]->start;
		ref.owning_root = 0;
		ref.ref_root = btrfs_root_id(src);
		btrfs_init_tree_ref(&ref, level - 1, 0, true);
		ret = btrfs_free_extent(trans, &ref);
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			break;
		}

		/* We don't know the real owning_root, use 0. */
		ref.action = BTRFS_DROP_DELAYED_REF;
		ref.bytenr = old_bytenr;
		ref.num_bytes = blocksize;
		ref.parent = 0;
		ref.owning_root = 0;
		ref.ref_root = btrfs_root_id(dest);
		btrfs_init_tree_ref(&ref, level - 1, 0, true);
		ret = btrfs_free_extent(trans, &ref);
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			break;
		}

		btrfs_unlock_up_safe(path, 0);

		ret = level;
		break;
	}
	btrfs_tree_unlock(parent);
	free_extent_buffer(parent);
	return ret;
}

/*
 * helper to find next relocated block in reloc tree
 */
static noinline_for_stack
int walk_up_reloc_tree(struct btrfs_root *root, struct btrfs_path *path,
		       int *level)
{
	struct extent_buffer *eb;
	int i;
	u64 last_snapshot;
	u32 nritems;

	last_snapshot = btrfs_root_last_snapshot(&root->root_item);

	for (i = 0; i < *level; i++) {
		free_extent_buffer(path->nodes[i]);
		path->nodes[i] = NULL;
	}

	for (i = *level; i < BTRFS_MAX_LEVEL && path->nodes[i]; i++) {
		eb = path->nodes[i];
		nritems = btrfs_header_nritems(eb);
		while (path->slots[i] + 1 < nritems) {
			path->slots[i]++;
			if (btrfs_node_ptr_generation(eb, path->slots[i]) <=
			    last_snapshot)
				continue;

			*level = i;
			return 0;
		}
		free_extent_buffer(path->nodes[i]);
		path->nodes[i] = NULL;
	}
	return 1;
}

/*
 * walk down reloc tree to find relocated block of lowest level
 */
static noinline_for_stack
int walk_down_reloc_tree(struct btrfs_root *root, struct btrfs_path *path,
			 int *level)
{
	struct extent_buffer *eb = NULL;
	int i;
	u64 ptr_gen = 0;
	u64 last_snapshot;
	u32 nritems;

	last_snapshot = btrfs_root_last_snapshot(&root->root_item);

	for (i = *level; i > 0; i--) {
		eb = path->nodes[i];
		nritems = btrfs_header_nritems(eb);
		while (path->slots[i] < nritems) {
			ptr_gen = btrfs_node_ptr_generation(eb, path->slots[i]);
			if (ptr_gen > last_snapshot)
				break;
			path->slots[i]++;
		}
		if (path->slots[i] >= nritems) {
			if (i == *level)
				break;
			*level = i + 1;
			return 0;
		}
		if (i == 1) {
			*level = i;
			return 0;
		}

		eb = btrfs_read_node_slot(eb, path->slots[i]);
		if (IS_ERR(eb))
			return PTR_ERR(eb);
		BUG_ON(btrfs_header_level(eb) != i - 1);
		path->nodes[i - 1] = eb;
		path->slots[i - 1] = 0;
	}
	return 1;
}

/*
 * invalidate extent cache for file extents whose key in range of
 * [min_key, max_key)
 */
static int invalidate_extent_cache(struct btrfs_root *root,
				   const struct btrfs_key *min_key,
				   const struct btrfs_key *max_key)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_inode *inode = NULL;
	u64 objectid;
	u64 start, end;
	u64 ino;

	objectid = min_key->objectid;
	while (1) {
		struct extent_state *cached_state = NULL;

		cond_resched();
		if (inode)
			iput(&inode->vfs_inode);

		if (objectid > max_key->objectid)
			break;

		inode = btrfs_find_first_inode(root, objectid);
		if (!inode)
			break;
		ino = btrfs_ino(inode);

		if (ino > max_key->objectid) {
			iput(&inode->vfs_inode);
			break;
		}

		objectid = ino + 1;
		if (!S_ISREG(inode->vfs_inode.i_mode))
			continue;

		if (unlikely(min_key->objectid == ino)) {
			if (min_key->type > BTRFS_EXTENT_DATA_KEY)
				continue;
			if (min_key->type < BTRFS_EXTENT_DATA_KEY)
				start = 0;
			else {
				start = min_key->offset;
				WARN_ON(!IS_ALIGNED(start, fs_info->sectorsize));
			}
		} else {
			start = 0;
		}

		if (unlikely(max_key->objectid == ino)) {
			if (max_key->type < BTRFS_EXTENT_DATA_KEY)
				continue;
			if (max_key->type > BTRFS_EXTENT_DATA_KEY) {
				end = (u64)-1;
			} else {
				if (max_key->offset == 0)
					continue;
				end = max_key->offset;
				WARN_ON(!IS_ALIGNED(end, fs_info->sectorsize));
				end--;
			}
		} else {
			end = (u64)-1;
		}

		/* the lock_extent waits for read_folio to complete */
		btrfs_lock_extent(&inode->io_tree, start, end, &cached_state);
		btrfs_drop_extent_map_range(inode, start, end, true);
		btrfs_unlock_extent(&inode->io_tree, start, end, &cached_state);
	}
	return 0;
}

static int find_next_key(struct btrfs_path *path, int level,
			 struct btrfs_key *key)

{
	while (level < BTRFS_MAX_LEVEL) {
		if (!path->nodes[level])
			break;
		if (path->slots[level] + 1 <
		    btrfs_header_nritems(path->nodes[level])) {
			btrfs_node_key_to_cpu(path->nodes[level], key,
					      path->slots[level] + 1);
			return 0;
		}
		level++;
	}
	return 1;
}

/*
 * Insert current subvolume into reloc_control::dirty_subvol_roots
 */
static int insert_dirty_subvol(struct btrfs_trans_handle *trans,
			       struct reloc_control *rc,
			       struct btrfs_root *root)
{
	struct btrfs_root *reloc_root = root->reloc_root;
	struct btrfs_root_item *reloc_root_item;
	int ret;

	/* @root must be a subvolume tree root with a valid reloc tree */
	ASSERT(btrfs_root_id(root) != BTRFS_TREE_RELOC_OBJECTID);
	ASSERT(reloc_root);

	reloc_root_item = &reloc_root->root_item;
	memset(&reloc_root_item->drop_progress, 0,
		sizeof(reloc_root_item->drop_progress));
	btrfs_set_root_drop_level(reloc_root_item, 0);
	btrfs_set_root_refs(reloc_root_item, 0);
	ret = btrfs_update_reloc_root(trans, root);
	if (ret)
		return ret;

	if (list_empty(&root->reloc_dirty_list)) {
		btrfs_grab_root(root);
		list_add_tail(&root->reloc_dirty_list, &rc->dirty_subvol_roots);
	}

	return 0;
}

static int clean_dirty_subvols(struct reloc_control *rc)
{
	struct btrfs_root *root;
	struct btrfs_root *next;
	int ret = 0;
	int ret2;

	list_for_each_entry_safe(root, next, &rc->dirty_subvol_roots,
				 reloc_dirty_list) {
		if (btrfs_root_id(root) != BTRFS_TREE_RELOC_OBJECTID) {
			/* Merged subvolume, cleanup its reloc root */
			struct btrfs_root *reloc_root = root->reloc_root;

			list_del_init(&root->reloc_dirty_list);
			root->reloc_root = NULL;
			/*
			 * Need barrier to ensure clear_bit() only happens after
			 * root->reloc_root = NULL. Pairs with have_reloc_root.
			 */
			smp_wmb();
			clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
			if (reloc_root) {
				/*
				 * btrfs_drop_snapshot drops our ref we hold for
				 * ->reloc_root.  If it fails however we must
				 * drop the ref ourselves.
				 */
				ret2 = btrfs_drop_snapshot(reloc_root, false, true);
				if (ret2 < 0) {
					btrfs_put_root(reloc_root);
					if (!ret)
						ret = ret2;
				}
			}
			btrfs_put_root(root);
		} else {
			/* Orphan reloc tree, just clean it up */
			ret2 = btrfs_drop_snapshot(root, false, true);
			if (ret2 < 0) {
				btrfs_put_root(root);
				if (!ret)
					ret = ret2;
			}
		}
	}
	return ret;
}

/*
 * merge the relocated tree blocks in reloc tree with corresponding
 * fs tree.
 */
static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
					       struct btrfs_root *root)
{
	struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
	struct btrfs_key key;
	struct btrfs_key next_key;
	struct btrfs_trans_handle *trans = NULL;
	struct btrfs_root *reloc_root;
	struct btrfs_root_item *root_item;
	struct btrfs_path *path;
	struct extent_buffer *leaf;
	int reserve_level;
	int level;
	int max_level;
	int replaced = 0;
	int ret = 0;
	u32 min_reserved;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
	path->reada = READA_FORWARD;

	reloc_root = root->reloc_root;
	root_item = &reloc_root->root_item;

	if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) {
		level = btrfs_root_level(root_item);
		refcount_inc(&reloc_root->node->refs);
		path->nodes[level] = reloc_root->node;
		path->slots[level] = 0;
	} else {
		btrfs_disk_key_to_cpu(&key, &root_item->drop_progress);

		level = btrfs_root_drop_level(root_item);
		BUG_ON(level == 0);
		path->lowest_level = level;
		ret = btrfs_search_slot(NULL, reloc_root, &key, path, 0, 0);
		path->lowest_level = 0;
		if (ret < 0) {
			btrfs_free_path(path);
			return ret;
		}

		btrfs_node_key_to_cpu(path->nodes[level], &next_key,
				      path->slots[level]);
		WARN_ON(memcmp(&key, &next_key, sizeof(key)));

		btrfs_unlock_up_safe(path, 0);
	}

	/*
	 * In merge_reloc_root(), we modify the upper level pointer to swap the
	 * tree blocks between reloc tree and subvolume tree.  Thus for tree
	 * block COW, we COW at most from level 1 to root level for each tree.
	 *
	 * Thus the needed metadata size is at most root_level * nodesize,
	 * and * 2 since we have two trees to COW.
	 */
	reserve_level = max_t(int, 1, btrfs_root_level(root_item));
	min_reserved = fs_info->nodesize * reserve_level * 2;
	memset(&next_key, 0, sizeof(next_key));

	while (1) {
		ret = btrfs_block_rsv_refill(fs_info, rc->block_rsv,
					     min_reserved,
					     BTRFS_RESERVE_FLUSH_LIMIT);
		if (ret)
			goto out;
		trans = btrfs_start_transaction(root, 0);
		if (IS_ERR(trans)) {
			ret = PTR_ERR(trans);
			trans = NULL;
			goto out;
		}

		/*
		 * At this point we no longer have a reloc_control, so we can't
		 * depend on btrfs_init_reloc_root to update our last_trans.
		 *
		 * But that's ok, we started the trans handle on our
		 * corresponding fs_root, which means it's been added to the
		 * dirty list.  At commit time we'll still call
		 * btrfs_update_reloc_root() and update our root item
		 * appropriately.
		 */
		btrfs_set_root_last_trans(reloc_root, trans->transid);
		trans->block_rsv = rc->block_rsv;

		replaced = 0;
		max_level = level;

		ret = walk_down_reloc_tree(reloc_root, path, &level);
		if (ret < 0)
			goto out;
		if (ret > 0)
			break;

		if (!find_next_key(path, level, &key) &&
		    btrfs_comp_cpu_keys(&next_key, &key) >= 0) {
			ret = 0;
		} else {
			ret = replace_path(trans, rc, root, reloc_root, path,
					   &next_key, level, max_level);
		}
		if (ret < 0)
			goto out;
		if (ret > 0) {
			level = ret;
			btrfs_node_key_to_cpu(path->nodes[level], &key,
					      path->slots[level]);
			replaced = 1;
		}

		ret = walk_up_reloc_tree(reloc_root, path, &level);
		if (ret > 0)
			break;

		BUG_ON(level == 0);
		/*
		 * save the merging progress in the drop_progress.
		 * this is OK since root refs == 1 in this case.
		 */
		btrfs_node_key(path->nodes[level], &root_item->drop_progress,
			       path->slots[level]);
		btrfs_set_root_drop_level(root_item, level);

		btrfs_end_transaction_throttle(trans);
		trans = NULL;

		btrfs_btree_balance_dirty(fs_info);

		if (replaced && rc->stage == UPDATE_DATA_PTRS)
			invalidate_extent_cache(root, &key, &next_key);
	}

	/*
	 * handle the case only one block in the fs tree need to be
	 * relocated and the block is tree root.
	 */
	leaf = btrfs_lock_root_node(root);
	ret = btrfs_cow_block(trans, root, leaf, NULL, 0, &leaf,
			      BTRFS_NESTING_COW);
	btrfs_tree_unlock(leaf);
	free_extent_buffer(leaf);
out:
	btrfs_free_path(path);

	if (ret == 0) {
		ret = insert_dirty_subvol(trans, rc, root);
		if (ret)
			btrfs_abort_transaction(trans, ret);
	}

	if (trans)
		btrfs_end_transaction_throttle(trans);

	btrfs_btree_balance_dirty(fs_info);

	if (replaced && rc->stage == UPDATE_DATA_PTRS)
		invalidate_extent_cache(root, &key, &next_key);

	return ret;
}

static noinline_for_stack
int prepare_to_merge(struct reloc_control *rc, int err)
{
	struct btrfs_root *root = rc->extent_root;
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_root *reloc_root;
	struct btrfs_trans_handle *trans;
	LIST_HEAD(reloc_roots);
	u64 num_bytes = 0;
	int ret;

	mutex_lock(&fs_info->reloc_mutex);
	rc->merging_rsv_size += fs_info->nodesize * (BTRFS_MAX_LEVEL - 1) * 2;
	rc->merging_rsv_size += rc->nodes_relocated * 2;
	mutex_unlock(&fs_info->reloc_mutex);

again:
	if (!err) {
		num_bytes = rc->merging_rsv_size;
		ret = btrfs_block_rsv_add(fs_info, rc->block_rsv, num_bytes,
					  BTRFS_RESERVE_FLUSH_ALL);
		if (ret)
			err = ret;
	}

	trans = btrfs_join_transaction(rc->extent_root);
	if (IS_ERR(trans)) {
		if (!err)
			btrfs_block_rsv_release(fs_info, rc->block_rsv,
						num_bytes, NULL);
		return PTR_ERR(trans);
	}

	if (!err) {
		if (num_bytes != rc->merging_rsv_size) {
			btrfs_end_transaction(trans);
			btrfs_block_rsv_release(fs_info, rc->block_rsv,
						num_bytes, NULL);
			goto again;
		}
	}

	rc->merge_reloc_tree = true;

	while (!list_empty(&rc->reloc_roots)) {
		reloc_root = list_first_entry(&rc->reloc_roots,
					      struct btrfs_root, root_list);
		list_del_init(&reloc_root->root_list);

		root = btrfs_get_fs_root(fs_info, reloc_root->root_key.offset,
				false);
		if (IS_ERR(root)) {
			/*
			 * Even if we have an error we need this reloc root
			 * back on our list so we can clean up properly.
			 */
			list_add(&reloc_root->root_list, &reloc_roots);
			btrfs_abort_transaction(trans, (int)PTR_ERR(root));
			if (!err)
				err = PTR_ERR(root);
			break;
		}

		if (unlikely(root->reloc_root != reloc_root)) {
			if (root->reloc_root) {
				btrfs_err(fs_info,
"reloc tree mismatch, root %lld has reloc root key (%lld %u %llu) gen %llu, expect reloc root key (%lld %u %llu) gen %llu",
					  btrfs_root_id(root),
					  btrfs_root_id(root->reloc_root),
					  root->reloc_root->root_key.type,
					  root->reloc_root->root_key.offset,
					  btrfs_root_generation(
						  &root->reloc_root->root_item),
					  btrfs_root_id(reloc_root),
					  reloc_root->root_key.type,
					  reloc_root->root_key.offset,
					  btrfs_root_generation(
						  &reloc_root->root_item));
			} else {
				btrfs_err(fs_info,
"reloc tree mismatch, root %lld has no reloc root, expect reloc root key (%lld %u %llu) gen %llu",
					  btrfs_root_id(root),
					  btrfs_root_id(reloc_root),
					  reloc_root->root_key.type,
					  reloc_root->root_key.offset,
					  btrfs_root_generation(
						  &reloc_root->root_item));
			}
			list_add(&reloc_root->root_list, &reloc_roots);
			btrfs_put_root(root);
			btrfs_abort_transaction(trans, -EUCLEAN);
			if (!err)
				err = -EUCLEAN;
			break;
		}

		/*
		 * set reference count to 1, so btrfs_recover_relocation
		 * knows it should resumes merging
		 */
		if (!err)
			btrfs_set_root_refs(&reloc_root->root_item, 1);
		ret = btrfs_update_reloc_root(trans, root);

		/*
		 * Even if we have an error we need this reloc root back on our
		 * list so we can clean up properly.
		 */
		list_add(&reloc_root->root_list, &reloc_roots);
		btrfs_put_root(root);

		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			if (!err)
				err = ret;
			break;
		}
	}

	list_splice(&reloc_roots, &rc->reloc_roots);

	if (!err)
		err = btrfs_commit_transaction(trans);
	else
		btrfs_end_transaction(trans);
	return err;
}

static noinline_for_stack
void free_reloc_roots(struct list_head *list)
{
	struct btrfs_root *reloc_root, *tmp;

	list_for_each_entry_safe(reloc_root, tmp, list, root_list)
		__del_reloc_root(reloc_root);
}

static noinline_for_stack
void merge_reloc_roots(struct reloc_control *rc)
{
	struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
	struct btrfs_root *root;
	struct btrfs_root *reloc_root;
	LIST_HEAD(reloc_roots);
	int found = 0;
	int ret = 0;
again:
	root = rc->extent_root;

	/*
	 * this serializes us with btrfs_record_root_in_transaction,
	 * we have to make sure nobody is in the middle of
	 * adding their roots to the list while we are
	 * doing this splice
	 */
	mutex_lock(&fs_info->reloc_mutex);
	list_splice_init(&rc->reloc_roots, &reloc_roots);
	mutex_unlock(&fs_info->reloc_mutex);

	while (!list_empty(&reloc_roots)) {
		found = 1;
		reloc_root = list_first_entry(&reloc_roots, struct btrfs_root, root_list);

		root = btrfs_get_fs_root(fs_info, reloc_root->root_key.offset,
					 false);
		if (btrfs_root_refs(&reloc_root->root_item) > 0) {
			if (WARN_ON(IS_ERR(root))) {
				/*
				 * For recovery we read the fs roots on mount,
				 * and if we didn't find the root then we marked
				 * the reloc root as a garbage root.  For normal
				 * relocation obviously the root should exist in
				 * memory.  However there's no reason we can't
				 * handle the error properly here just in case.
				 */
				ret = PTR_ERR(root);
				goto out;
			}
			if (WARN_ON(root->reloc_root != reloc_root)) {
				/*
				 * This can happen if on-disk metadata has some
				 * corruption, e.g. bad reloc tree key offset.
				 */
				ret = -EINVAL;
				goto out;
			}
			ret = merge_reloc_root(rc, root);
			btrfs_put_root(root);
			if (ret) {
				if (list_empty(&reloc_root->root_list))
					list_add_tail(&reloc_root->root_list,
						      &reloc_roots);
				goto out;
			}
		} else {
			if (!IS_ERR(root)) {
				if (root->reloc_root == reloc_root) {
					root->reloc_root = NULL;
					btrfs_put_root(reloc_root);
				}
				clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE,
					  &root->state);
				btrfs_put_root(root);
			}

			list_del_init(&reloc_root->root_list);
			/* Don't forget to queue this reloc root for cleanup */
			list_add_tail(&reloc_root->reloc_dirty_list,
				      &rc->dirty_subvol_roots);
		}
	}

	if (found) {
		found = 0;
		goto again;
	}
out:
	if (ret) {
		btrfs_handle_fs_error(fs_info, ret, NULL);
		free_reloc_roots(&reloc_roots);

		/* new reloc root may be added */
		mutex_lock(&fs_info->reloc_mutex);
		list_splice_init(&rc->reloc_roots, &reloc_roots);
		mutex_unlock(&fs_info->reloc_mutex);
		free_reloc_roots(&reloc_roots);
	}

	/*
	 * We used to have
	 *
	 * BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root));
	 *
	 * here, but it's wrong.  If we fail to start the transaction in
	 * prepare_to_merge() we will have only 0 ref reloc roots, none of which
	 * have actually been removed from the reloc_root_tree rb tree.  This is
	 * fine because we're bailing here, and we hold a reference on the root
	 * for the list that holds it, so these roots will be cleaned up when we
	 * do the reloc_dirty_list afterwards.  Meanwhile the root->reloc_root
	 * will be cleaned up on unmount.
	 *
	 * The remaining nodes will be cleaned up by free_reloc_control.
	 */
}

static void free_block_list(struct rb_root *blocks)
{
	struct tree_block *block;
	struct rb_node *rb_node;
	while ((rb_node = rb_first(blocks))) {
		block = rb_entry(rb_node, struct tree_block, rb_node);
		rb_erase(rb_node, blocks);
		kfree(block);
	}
}

static int record_reloc_root_in_trans(struct btrfs_trans_handle *trans,
				      struct btrfs_root *reloc_root)
{
	struct btrfs_fs_info *fs_info = reloc_root->fs_info;
	struct btrfs_root *root;
	int ret;

	if (btrfs_get_root_last_trans(reloc_root) == trans->transid)
		return 0;

	root = btrfs_get_fs_root(fs_info, reloc_root->root_key.offset, false);

	/*
	 * This should succeed, since we can't have a reloc root without having
	 * already looked up the actual root and created the reloc root for this
	 * root.
	 *
	 * However if there's some sort of corruption where we have a ref to a
	 * reloc root without a corresponding root this could return ENOENT.
	 */
	if (IS_ERR(root)) {
		DEBUG_WARN("error %ld reading root for reloc root", PTR_ERR(root));
		return PTR_ERR(root);
	}
	if (unlikely(root->reloc_root != reloc_root)) {
		DEBUG_WARN("unexpected reloc root found");
		btrfs_err(fs_info,
			  "root %llu has two reloc roots associated with it",
			  reloc_root->root_key.offset);
		btrfs_put_root(root);
		return -EUCLEAN;
	}
	ret = btrfs_record_root_in_trans(trans, root);
	btrfs_put_root(root);

	return ret;
}

static noinline_for_stack
struct btrfs_root *select_reloc_root(struct btrfs_trans_handle *trans,
				     struct reloc_control *rc,
				     struct btrfs_backref_node *node,
				     struct btrfs_backref_edge *edges[])
{
	struct btrfs_backref_node *next;
	struct btrfs_root *root;
	int index = 0;
	int ret;

	next = walk_up_backref(node, edges, &index);
	root = next->root;

	/*
	 * If there is no root, then our references for this block are
	 * incomplete, as we should be able to walk all the way up to a block
	 * that is owned by a root.
	 *
	 * This path is only for SHAREABLE roots, so if we come upon a
	 * non-SHAREABLE root then we have backrefs that resolve improperly.
	 *
	 * Both of these cases indicate file system corruption, or a bug in the
	 * backref walking code.
	 */
	if (unlikely(!root)) {
		btrfs_err(trans->fs_info,
			  "bytenr %llu doesn't have a backref path ending in a root",
			  node->bytenr);
		return ERR_PTR(-EUCLEAN);
	}
	if (unlikely(!test_bit(BTRFS_ROOT_SHAREABLE, &root->state))) {
		btrfs_err(trans->fs_info,
			  "bytenr %llu has multiple refs with one ending in a non-shareable root",
			  node->bytenr);
		return ERR_PTR(-EUCLEAN);
	}

	if (btrfs_root_id(root) == BTRFS_TREE_RELOC_OBJECTID) {
		ret = record_reloc_root_in_trans(trans, root);
		if (ret)
			return ERR_PTR(ret);
		goto found;
	}

	ret = btrfs_record_root_in_trans(trans, root);
	if (ret)
		return ERR_PTR(ret);
	root = root->reloc_root;

	/*
	 * We could have raced with another thread which failed, so
	 * root->reloc_root may not be set, return ENOENT in this case.
	 */
	if (!root)
		return ERR_PTR(-ENOENT);

	if (unlikely(next->new_bytenr)) {
		/*
		 * We just created the reloc root, so we shouldn't have
		 * ->new_bytenr set yet. If it is then we have multiple roots
		 *  pointing at the same bytenr which indicates corruption, or
		 *  we've made a mistake in the backref walking code.
		 */
		ASSERT(next->new_bytenr == 0);
		btrfs_err(trans->fs_info,
			  "bytenr %llu possibly has multiple roots pointing at the same bytenr %llu",
			  node->bytenr, next->bytenr);
		return ERR_PTR(-EUCLEAN);
	}

	next->new_bytenr = root->node->start;
	btrfs_put_root(next->root);
	next->root = btrfs_grab_root(root);
	ASSERT(next->root);
	mark_block_processed(rc, next);
found:
	next = node;
	/* setup backref node path for btrfs_reloc_cow_block */
	while (1) {
		rc->backref_cache.path[next->level] = next;
		if (--index < 0)
			break;
		next = edges[index]->node[UPPER];
	}
	return root;
}

/*
 * Select a tree root for relocation.
 *
 * Return NULL if the block is not shareable. We should use do_relocation() in
 * this case.
 *
 * Return a tree root pointer if the block is shareable.
 * Return -ENOENT if the block is root of reloc tree.
 */
static noinline_for_stack
struct btrfs_root *select_one_root(struct btrfs_backref_node *node)
{
	struct btrfs_backref_node *next;
	struct btrfs_root *root;
	struct btrfs_root *fs_root = NULL;
	struct btrfs_backref_edge *edges[BTRFS_MAX_LEVEL - 1];
	int index = 0;

	next = node;
	while (1) {
		cond_resched();
		next = walk_up_backref(next, edges, &index);
		root = next->root;

		/*
		 * This can occur if we have incomplete extent refs leading all
		 * the way up a particular path, in this case return -EUCLEAN.
		 */
		if (unlikely(!root))
			return ERR_PTR(-EUCLEAN);

		/* No other choice for non-shareable tree */
		if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
			return root;

		if (btrfs_root_id(root) != BTRFS_TREE_RELOC_OBJECTID)
			fs_root = root;

		if (next != node)
			return NULL;

		next = walk_down_backref(edges, &index);
		if (!next || next->level <= node->level)
			break;
	}

	if (!fs_root)
		return ERR_PTR(-ENOENT);
	return fs_root;
}

static noinline_for_stack u64 calcu_metadata_size(struct reloc_control *rc,
						  struct btrfs_backref_node *node)
{
	struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
	struct btrfs_backref_node *next = node;
	struct btrfs_backref_edge *edge;
	struct btrfs_backref_edge *edges[BTRFS_MAX_LEVEL - 1];
	u64 num_bytes = 0;
	int index = 0;

	BUG_ON(node->processed);

	while (next) {
		cond_resched();
		while (1) {
			if (next->processed)
				break;

			num_bytes += fs_info->nodesize;

			if (list_empty(&next->upper))
				break;

			edge = list_first_entry(&next->upper, struct btrfs_backref_edge,
						list[LOWER]);
			edges[index++] = edge;
			next = edge->node[UPPER];
		}
		next = walk_down_backref(edges, &index);
	}
	return num_bytes;
}

static int refill_metadata_space(struct btrfs_trans_handle *trans,
				 struct reloc_control *rc, u64 num_bytes)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	int ret;

	trans->block_rsv = rc->block_rsv;
	rc->reserved_bytes += num_bytes;

	/*
	 * We are under a transaction here so we can only do limited flushing.
	 * If we get an enospc just kick back -EAGAIN so we know to drop the
	 * transaction and try to refill when we can flush all the things.
	 */
	ret = btrfs_block_rsv_refill(fs_info, rc->block_rsv, num_bytes,
				     BTRFS_RESERVE_FLUSH_LIMIT);
	if (ret) {
		u64 tmp = fs_info->nodesize * RELOCATION_RESERVED_NODES;

		while (tmp <= rc->reserved_bytes)
			tmp <<= 1;
		/*
		 * only one thread can access block_rsv at this point,
		 * so we don't need hold lock to protect block_rsv.
		 * we expand more reservation size here to allow enough
		 * space for relocation and we will return earlier in
		 * enospc case.
		 */
		rc->block_rsv->size = tmp + fs_info->nodesize *
				      RELOCATION_RESERVED_NODES;
		return -EAGAIN;
	}

	return 0;
}

static int reserve_metadata_space(struct btrfs_trans_handle *trans,
				  struct reloc_control *rc,
				  struct btrfs_backref_node *node)
{
	u64 num_bytes;

	num_bytes = calcu_metadata_size(rc, node) * 2;
	return refill_metadata_space(trans, rc, num_bytes);
}

/*
 * relocate a block tree, and then update pointers in upper level
 * blocks that reference the block to point to the new location.
 *
 * if called by link_to_upper, the block has already been relocated.
 * in that case this function just updates pointers.
 */
static int do_relocation(struct btrfs_trans_handle *trans,
			 struct reloc_control *rc,
			 struct btrfs_backref_node *node,
			 struct btrfs_key *key,
			 struct btrfs_path *path, int lowest)
{
	struct btrfs_backref_node *upper;
	struct btrfs_backref_edge *edge;
	struct btrfs_backref_edge *edges[BTRFS_MAX_LEVEL - 1];
	struct btrfs_root *root;
	struct extent_buffer *eb;
	u32 blocksize;
	u64 bytenr;
	int slot;
	int ret = 0;

	/*
	 * If we are lowest then this is the first time we're processing this
	 * block, and thus shouldn't have an eb associated with it yet.
	 */
	ASSERT(!lowest || !node->eb);

	path->lowest_level = node->level + 1;
	rc->backref_cache.path[node->level] = node;
	list_for_each_entry(edge, &node->upper, list[LOWER]) {
		cond_resched();

		upper = edge->node[UPPER];
		root = select_reloc_root(trans, rc, upper, edges);
		if (IS_ERR(root)) {
			ret = PTR_ERR(root);
			goto next;
		}

		if (upper->eb && !upper->locked) {
			if (!lowest) {
				ret = btrfs_bin_search(upper->eb, 0, key, &slot);
				if (ret < 0)
					goto next;
				BUG_ON(ret);
				bytenr = btrfs_node_blockptr(upper->eb, slot);
				if (node->eb->start == bytenr)
					goto next;
			}
			btrfs_backref_drop_node_buffer(upper);
		}

		if (!upper->eb) {
			ret = btrfs_search_slot(trans, root, key, path, 0, 1);
			if (ret) {
				if (ret > 0)
					ret = -ENOENT;

				btrfs_release_path(path);
				break;
			}

			if (!upper->eb) {
				upper->eb = path->nodes[upper->level];
				path->nodes[upper->level] = NULL;
			} else {
				BUG_ON(upper->eb != path->nodes[upper->level]);
			}

			upper->locked = 1;
			path->locks[upper->level] = 0;

			slot = path->slots[upper->level];
			btrfs_release_path(path);
		} else {
			ret = btrfs_bin_search(upper->eb, 0, key, &slot);
			if (ret < 0)
				goto next;
			BUG_ON(ret);
		}

		bytenr = btrfs_node_blockptr(upper->eb, slot);
		if (lowest) {
			if (unlikely(bytenr != node->bytenr)) {
				btrfs_err(root->fs_info,
		"lowest leaf/node mismatch: bytenr %llu node->bytenr %llu slot %d upper %llu",
					  bytenr, node->bytenr, slot,
					  upper->eb->start);
				ret = -EIO;
				goto next;
			}
		} else {
			if (node->eb->start == bytenr)
				goto next;
		}

		blocksize = root->fs_info->nodesize;
		eb = btrfs_read_node_slot(upper->eb, slot);
		if (IS_ERR(eb)) {
			ret = PTR_ERR(eb);
			goto next;
		}
		btrfs_tree_lock(eb);

		if (!node->eb) {
			ret = btrfs_cow_block(trans, root, eb, upper->eb,
					      slot, &eb, BTRFS_NESTING_COW);
			btrfs_tree_unlock(eb);
			free_extent_buffer(eb);
			if (ret < 0)
				goto next;
			/*
			 * We've just COWed this block, it should have updated
			 * the correct backref node entry.
			 */
			ASSERT(node->eb == eb);
		} else {
			struct btrfs_ref ref = {
				.action = BTRFS_ADD_DELAYED_REF,
				.bytenr = node->eb->start,
				.num_bytes = blocksize,
				.parent = upper->eb->start,
				.owning_root = btrfs_header_owner(upper->eb),
				.ref_root = btrfs_header_owner(upper->eb),
			};

			btrfs_set_node_blockptr(upper->eb, slot,
						node->eb->start);
			btrfs_set_node_ptr_generation(upper->eb, slot,
						      trans->transid);
			btrfs_mark_buffer_dirty(trans, upper->eb);

			btrfs_init_tree_ref(&ref, node->level,
					    btrfs_root_id(root), false);
			ret = btrfs_inc_extent_ref(trans, &ref);
			if (!ret)
				ret = btrfs_drop_subtree(trans, root, eb,
							 upper->eb);
			if (unlikely(ret))
				btrfs_abort_transaction(trans, ret);
		}
next:
		if (!upper->pending)
			btrfs_backref_drop_node_buffer(upper);
		else
			btrfs_backref_unlock_node_buffer(upper);
		if (ret)
			break;
	}

	if (!ret && node->pending) {
		btrfs_backref_drop_node_buffer(node);
		list_del_init(&node->list);
		node->pending = 0;
	}

	path->lowest_level = 0;

	/*
	 * We should have allocated all of our space in the block rsv and thus
	 * shouldn't ENOSPC.
	 */
	ASSERT(ret != -ENOSPC);
	return ret;
}

static int link_to_upper(struct btrfs_trans_handle *trans,
			 struct reloc_control *rc,
			 struct btrfs_backref_node *node,
			 struct btrfs_path *path)
{
	struct btrfs_key key;

	btrfs_node_key_to_cpu(node->eb, &key, 0);
	return do_relocation(trans, rc, node, &key, path, 0);
}

static int finish_pending_nodes(struct btrfs_trans_handle *trans,
				struct reloc_control *rc,
				struct btrfs_path *path, int err)
{
	LIST_HEAD(list);
	struct btrfs_backref_cache *cache = &rc->backref_cache;
	struct btrfs_backref_node *node;
	int level;
	int ret;

	for (level = 0; level < BTRFS_MAX_LEVEL; level++) {
		while (!list_empty(&cache->pending[level])) {
			node = list_first_entry(&cache->pending[level],
						struct btrfs_backref_node, list);
			list_move_tail(&node->list, &list);
			BUG_ON(!node->pending);

			if (!err) {
				ret = link_to_upper(trans, rc, node, path);
				if (ret < 0)
					err = ret;
			}
		}
		list_splice_init(&list, &cache->pending[level]);
	}
	return err;
}

/*
 * mark a block and all blocks directly/indirectly reference the block
 * as processed.
 */
static void update_processed_blocks(struct reloc_control *rc,
				    struct btrfs_backref_node *node)
{
	struct btrfs_backref_node *next = node;
	struct btrfs_backref_edge *edge;
	struct btrfs_backref_edge *edges[BTRFS_MAX_LEVEL - 1];
	int index = 0;

	while (next) {
		cond_resched();
		while (1) {
			if (next->processed)
				break;

			mark_block_processed(rc, next);

			if (list_empty(&next->upper))
				break;

			edge = list_first_entry(&next->upper, struct btrfs_backref_edge,
						list[LOWER]);
			edges[index++] = edge;
			next = edge->node[UPPER];
		}
		next = walk_down_backref(edges, &index);
	}
}

static int tree_block_processed(u64 bytenr, struct reloc_control *rc)
{
	u32 blocksize = rc->extent_root->fs_info->nodesize;

	if (btrfs_test_range_bit(&rc->processed_blocks, bytenr,
				 bytenr + blocksize - 1, EXTENT_DIRTY, NULL))
		return 1;
	return 0;
}

static int get_tree_block_key(struct btrfs_fs_info *fs_info,
			      struct tree_block *block)
{
	struct btrfs_tree_parent_check check = {
		.level = block->level,
		.owner_root = block->owner,
		.transid = block->key.offset
	};
	struct extent_buffer *eb;

	eb = read_tree_block(fs_info, block->bytenr, &check);
	if (IS_ERR(eb))
		return PTR_ERR(eb);

	if (block->level == 0)
		btrfs_item_key_to_cpu(eb, &block->key, 0);
	else
		btrfs_node_key_to_cpu(eb, &block->key, 0);
	free_extent_buffer(eb);
	block->key_ready = true;
	return 0;
}

/*
 * helper function to relocate a tree block
 */
static int relocate_tree_block(struct btrfs_trans_handle *trans,
				struct reloc_control *rc,
				struct btrfs_backref_node *node,
				struct btrfs_key *key,
				struct btrfs_path *path)
{
	struct btrfs_root *root;
	int ret = 0;

	if (!node)
		return 0;

	/*
	 * If we fail here we want to drop our backref_node because we are going
	 * to start over and regenerate the tree for it.
	 */
	ret = reserve_metadata_space(trans, rc, node);
	if (ret)
		goto out;

	BUG_ON(node->processed);
	root = select_one_root(node);
	if (IS_ERR(root)) {
		ret = PTR_ERR(root);

		/* See explanation in select_one_root for the -EUCLEAN case. */
		ASSERT(ret == -ENOENT);
		if (ret == -ENOENT) {
			ret = 0;
			update_processed_blocks(rc, node);
		}
		goto out;
	}

	if (root) {
		if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) {
			/*
			 * This block was the root block of a root, and this is
			 * the first time we're processing the block and thus it
			 * should not have had the ->new_bytenr modified.
			 *
			 * However in the case of corruption we could have
			 * multiple refs pointing to the same block improperly,
			 * and thus we would trip over these checks.  ASSERT()
			 * for the developer case, because it could indicate a
			 * bug in the backref code, however error out for a
			 * normal user in the case of corruption.
			 */
			ASSERT(node->new_bytenr == 0);
			if (unlikely(node->new_bytenr)) {
				btrfs_err(root->fs_info,
				  "bytenr %llu has improper references to it",
					  node->bytenr);
				ret = -EUCLEAN;
				goto out;
			}
			ret = btrfs_record_root_in_trans(trans, root);
			if (ret)
				goto out;
			/*
			 * Another thread could have failed, need to check if we
			 * have reloc_root actually set.
			 */
			if (!root->reloc_root) {
				ret = -ENOENT;
				goto out;
			}
			root = root->reloc_root;
			node->new_bytenr = root->node->start;
			btrfs_put_root(node->root);
			node->root = btrfs_grab_root(root);
			ASSERT(node->root);
		} else {
			btrfs_err(root->fs_info,
				  "bytenr %llu resolved to a non-shareable root",
				  node->bytenr);
			ret = -EUCLEAN;
			goto out;
		}
		if (!ret)
			update_processed_blocks(rc, node);
	} else {
		ret = do_relocation(trans, rc, node, key, path, 1);
	}
out:
	if (ret || node->level == 0)
		btrfs_backref_cleanup_node(&rc->backref_cache, node);
	return ret;
}

static int relocate_cowonly_block(struct btrfs_trans_handle *trans,
				  struct reloc_control *rc, struct tree_block *block,
				  struct btrfs_path *path)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_root *root;
	u64 num_bytes;
	int nr_levels;
	int ret;

	root = btrfs_get_fs_root(fs_info, block->owner, true);
	if (IS_ERR(root))
		return PTR_ERR(root);

	nr_levels = max(btrfs_header_level(root->node) - block->level, 0) + 1;

	num_bytes = fs_info->nodesize * nr_levels;
	ret = refill_metadata_space(trans, rc, num_bytes);
	if (ret) {
		btrfs_put_root(root);
		return ret;
	}
	path->lowest_level = block->level;
	if (root == root->fs_info->chunk_root)
		btrfs_reserve_chunk_metadata(trans, false);

	ret = btrfs_search_slot(trans, root, &block->key, path, 0, 1);
	path->lowest_level = 0;
	btrfs_release_path(path);

	if (root == root->fs_info->chunk_root)
		btrfs_trans_release_chunk_metadata(trans);
	if (ret > 0)
		ret = 0;
	btrfs_put_root(root);

	return ret;
}

/*
 * relocate a list of blocks
 */
static noinline_for_stack
int relocate_tree_blocks(struct btrfs_trans_handle *trans,
			 struct reloc_control *rc, struct rb_root *blocks)
{
	struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
	struct btrfs_backref_node *node;
	struct btrfs_path *path;
	struct tree_block *block;
	struct tree_block *next;
	int ret = 0;

	path = btrfs_alloc_path();
	if (!path) {
		ret = -ENOMEM;
		goto out_free_blocks;
	}

	/* Kick in readahead for tree blocks with missing keys */
	rbtree_postorder_for_each_entry_safe(block, next, blocks, rb_node) {
		if (!block->key_ready)
			btrfs_readahead_tree_block(fs_info, block->bytenr,
						   block->owner, 0,
						   block->level, NULL);
	}

	/* Get first keys */
	rbtree_postorder_for_each_entry_safe(block, next, blocks, rb_node) {
		if (!block->key_ready) {
			ret = get_tree_block_key(fs_info, block);
			if (ret)
				goto out_free_path;
		}
	}

	/* Do tree relocation */
	rbtree_postorder_for_each_entry_safe(block, next, blocks, rb_node) {
		/*
		 * For COWonly blocks, or the data reloc tree, we only need to
		 * COW down to the block, there's no need to generate a backref
		 * tree.
		 */
		if (block->owner &&
		    (!btrfs_is_fstree(block->owner) ||
		     block->owner == BTRFS_DATA_RELOC_TREE_OBJECTID)) {
			ret = relocate_cowonly_block(trans, rc, block, path);
			if (ret)
				break;
			continue;
		}

		node = build_backref_tree(trans, rc, &block->key,
					  block->level, block->bytenr);
		if (IS_ERR(node)) {
			ret = PTR_ERR(node);
			goto out;
		}

		ret = relocate_tree_block(trans, rc, node, &block->key,
					  path);
		if (ret < 0)
			break;
	}
out:
	ret = finish_pending_nodes(trans, rc, path, ret);

out_free_path:
	btrfs_free_path(path);
out_free_blocks:
	free_block_list(blocks);
	return ret;
}

static noinline_for_stack int prealloc_file_extent_cluster(struct reloc_control *rc)
{
	const struct file_extent_cluster *cluster = &rc->cluster;
	struct btrfs_inode *inode = BTRFS_I(rc->data_inode);
	u64 alloc_hint = 0;
	u64 start;
	u64 end;
	u64 offset = inode->reloc_block_group_start;
	u64 num_bytes;
	int nr;
	int ret = 0;
	u64 prealloc_start = cluster->start - offset;
	u64 prealloc_end = cluster->end - offset;
	u64 cur_offset = prealloc_start;

	/*
	 * For blocksize < folio size case (either bs < page size or large folios),
	 * beyond i_size, all blocks are filled with zero.
	 *
	 * If the current cluster covers the above range, btrfs_do_readpage()
	 * will skip the read, and relocate_one_folio() will later writeback
	 * the padding zeros as new data, causing data corruption.
	 *
	 * Here we have to invalidate the cache covering our cluster.
	 */
	ret = filemap_invalidate_inode(&inode->vfs_inode, true, prealloc_start,
				       prealloc_end);
	if (ret < 0)
		return ret;

	BUG_ON(cluster->start != cluster->boundary[0]);
	ret = btrfs_alloc_data_chunk_ondemand(inode,
					      prealloc_end + 1 - prealloc_start);
	if (ret)
		return ret;

	btrfs_inode_lock(inode, 0);
	for (nr = 0; nr < cluster->nr; nr++) {
		struct extent_state *cached_state = NULL;

		start = cluster->boundary[nr] - offset;
		if (nr + 1 < cluster->nr)
			end = cluster->boundary[nr + 1] - 1 - offset;
		else
			end = cluster->end - offset;

		btrfs_lock_extent(&inode->io_tree, start, end, &cached_state);
		num_bytes = end + 1 - start;
		ret = btrfs_prealloc_file_range(&inode->vfs_inode, 0, start,
						num_bytes, num_bytes,
						end + 1, &alloc_hint);
		cur_offset = end + 1;
		btrfs_unlock_extent(&inode->io_tree, start, end, &cached_state);
		if (ret)
			break;
	}
	btrfs_inode_unlock(inode, 0);

	if (cur_offset < prealloc_end)
		btrfs_free_reserved_data_space_noquota(inode,
						       prealloc_end + 1 - cur_offset);
	return ret;
}

static noinline_for_stack int setup_relocation_extent_mapping(struct reloc_control *rc)
{
	struct btrfs_inode *inode = BTRFS_I(rc->data_inode);
	struct extent_map *em;
	struct extent_state *cached_state = NULL;
	u64 offset = inode->reloc_block_group_start;
	u64 start = rc->cluster.start - offset;
	u64 end = rc->cluster.end - offset;
	int ret = 0;

	em = btrfs_alloc_extent_map();
	if (!em)
		return -ENOMEM;

	em->start = start;
	em->len = end + 1 - start;
	em->disk_bytenr = rc->cluster.start;
	em->disk_num_bytes = em->len;
	em->ram_bytes = em->len;
	em->flags |= EXTENT_FLAG_PINNED;

	btrfs_lock_extent(&inode->io_tree, start, end, &cached_state);
	ret = btrfs_replace_extent_map_range(inode, em, false);
	btrfs_unlock_extent(&inode->io_tree, start, end, &cached_state);
	btrfs_free_extent_map(em);

	return ret;
}

/*
 * Allow error injection to test balance/relocation cancellation
 */
noinline int btrfs_should_cancel_balance(const struct btrfs_fs_info *fs_info)
{
	return atomic_read(&fs_info->balance_cancel_req) ||
		atomic_read(&fs_info->reloc_cancel_req) ||
		fatal_signal_pending(current);
}
ALLOW_ERROR_INJECTION(btrfs_should_cancel_balance, TRUE);

static u64 get_cluster_boundary_end(const struct file_extent_cluster *cluster,
				    int cluster_nr)
{
	/* Last extent, use cluster end directly */
	if (cluster_nr >= cluster->nr - 1)
		return cluster->end;

	/* Use next boundary start*/
	return cluster->boundary[cluster_nr + 1] - 1;
}

static int relocate_one_folio(struct reloc_control *rc,
			      struct file_ra_state *ra,
			      int *cluster_nr, u64 *file_offset_ret)
{
	const struct file_extent_cluster *cluster = &rc->cluster;
	struct inode *inode = rc->data_inode;
	struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
	const u64 orig_file_offset = *file_offset_ret;
	u64 offset = BTRFS_I(inode)->reloc_block_group_start;
	const pgoff_t last_index = (cluster->end - offset) >> PAGE_SHIFT;
	const pgoff_t index = orig_file_offset >> PAGE_SHIFT;
	gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
	struct folio *folio;
	u64 folio_start;
	u64 folio_end;
	u64 cur;
	int ret;
	const bool use_rst = btrfs_need_stripe_tree_update(fs_info, rc->block_group->flags);

	ASSERT(index <= last_index);
again:
	folio = filemap_lock_folio(inode->i_mapping, index);
	if (IS_ERR(folio)) {

		/*
		 * On relocation we're doing readahead on the relocation inode,
		 * but if the filesystem is backed by a RAID stripe tree we can
		 * get ENOENT (e.g. due to preallocated extents not being
		 * mapped in the RST) from the lookup.
		 *
		 * But readahead doesn't handle the error and submits invalid
		 * reads to the device, causing a assertion failures.
		 */
		if (!use_rst)
			page_cache_sync_readahead(inode->i_mapping, ra, NULL,
						  index, last_index + 1 - index);
		folio = __filemap_get_folio(inode->i_mapping, index,
					    FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
					    mask);
		if (IS_ERR(folio))
			return PTR_ERR(folio);
	}

	if (folio_test_readahead(folio) && !use_rst)
		page_cache_async_readahead(inode->i_mapping, ra, NULL,
					   folio, last_index + 1 - index);

	if (!folio_test_uptodate(folio)) {
		btrfs_read_folio(NULL, folio);
		folio_lock(folio);
		if (unlikely(!folio_test_uptodate(folio))) {
			ret = -EIO;
			goto release_folio;
		}
		if (folio->mapping != inode->i_mapping) {
			folio_unlock(folio);
			folio_put(folio);
			goto again;
		}
	}

	/*
	 * We could have lost folio private when we dropped the lock to read the
	 * folio above, make sure we set_folio_extent_mapped() here so we have any
	 * of the subpage blocksize stuff we need in place.
	 */
	ret = set_folio_extent_mapped(folio);
	if (ret < 0)
		goto release_folio;

	folio_start = folio_pos(folio);
	folio_end = folio_start + folio_size(folio) - 1;

	/*
	 * Start from the cluster, as for subpage case, the cluster can start
	 * inside the folio.
	 */
	cur = max(folio_start, cluster->boundary[*cluster_nr] - offset);
	while (cur <= folio_end) {
		struct extent_state *cached_state = NULL;
		u64 extent_start = cluster->boundary[*cluster_nr] - offset;
		u64 extent_end = get_cluster_boundary_end(cluster,
						*cluster_nr) - offset;
		u64 clamped_start = max(folio_start, extent_start);
		u64 clamped_end = min(folio_end, extent_end);
		u32 clamped_len = clamped_end + 1 - clamped_start;

		/* Reserve metadata for this range */
		ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode),
						      clamped_len, clamped_len,
						      false);
		if (ret)
			goto release_folio;

		/* Mark the range delalloc and dirty for later writeback */
		btrfs_lock_extent(&BTRFS_I(inode)->io_tree, clamped_start,
				  clamped_end, &cached_state);
		ret = btrfs_set_extent_delalloc(BTRFS_I(inode), clamped_start,
						clamped_end, 0, &cached_state);
		if (ret) {
			btrfs_clear_extent_bit(&BTRFS_I(inode)->io_tree,
					       clamped_start, clamped_end,
					       EXTENT_LOCKED | EXTENT_BOUNDARY,
					       &cached_state);
			btrfs_delalloc_release_metadata(BTRFS_I(inode),
							clamped_len, true);
			btrfs_delalloc_release_extents(BTRFS_I(inode),
						       clamped_len);
			goto release_folio;
		}
		btrfs_folio_set_dirty(fs_info, folio, clamped_start, clamped_len);

		/*
		 * Set the boundary if it's inside the folio.
		 * Data relocation requires the destination extents to have the
		 * same size as the source.
		 * EXTENT_BOUNDARY bit prevents current extent from being merged
		 * with previous extent.
		 */
		if (in_range(cluster->boundary[*cluster_nr] - offset,
			     folio_start, folio_size(folio))) {
			u64 boundary_start = cluster->boundary[*cluster_nr] -
						offset;
			u64 boundary_end = boundary_start +
					   fs_info->sectorsize - 1;

			btrfs_set_extent_bit(&BTRFS_I(inode)->io_tree,
					     boundary_start, boundary_end,
					     EXTENT_BOUNDARY, NULL);
		}
		btrfs_unlock_extent(&BTRFS_I(inode)->io_tree, clamped_start, clamped_end,
				    &cached_state);
		btrfs_delalloc_release_extents(BTRFS_I(inode), clamped_len);
		cur += clamped_len;

		/* Crossed extent end, go to next extent */
		if (cur >= extent_end) {
			(*cluster_nr)++;
			/* Just finished the last extent of the cluster, exit. */
			if (*cluster_nr >= cluster->nr)
				break;
		}
	}
	folio_unlock(folio);
	folio_put(folio);

	balance_dirty_pages_ratelimited(inode->i_mapping);
	btrfs_throttle(fs_info);
	if (btrfs_should_cancel_balance(fs_info))
		ret = -ECANCELED;
	*file_offset_ret = folio_end + 1;
	return ret;

release_folio:
	folio_unlock(folio);
	folio_put(folio);
	return ret;
}

static int relocate_file_extent_cluster(struct reloc_control *rc)
{
	struct inode *inode = rc->data_inode;
	const struct file_extent_cluster *cluster = &rc->cluster;
	u64 offset = BTRFS_I(inode)->reloc_block_group_start;
	u64 cur_file_offset = cluster->start - offset;
	struct file_ra_state AUTO_KFREE(ra);
	int cluster_nr = 0;
	int ret = 0;

	if (!cluster->nr)
		return 0;

	ra = kzalloc(sizeof(*ra), GFP_NOFS);
	if (!ra)
		return -ENOMEM;

	ret = prealloc_file_extent_cluster(rc);
	if (ret)
		return ret;

	file_ra_state_init(ra, inode->i_mapping);

	ret = setup_relocation_extent_mapping(rc);
	if (ret)
		return ret;

	while (cur_file_offset < cluster->end - offset) {
		ret = relocate_one_folio(rc, ra, &cluster_nr, &cur_file_offset);
		if (ret)
			break;
	}
	if (ret == 0)
		WARN_ON(cluster_nr != cluster->nr);
	return ret;
}

static noinline_for_stack int relocate_data_extent(struct reloc_control *rc,
					   const struct btrfs_key *extent_key)
{
	struct inode *inode = rc->data_inode;
	struct file_extent_cluster *cluster = &rc->cluster;
	int ret;
	struct btrfs_root *root = BTRFS_I(inode)->root;

	if (cluster->nr > 0 && extent_key->objectid != cluster->end + 1) {
		ret = relocate_file_extent_cluster(rc);
		if (ret)
			return ret;
		cluster->nr = 0;
	}

	/*
	 * Under simple quotas, we set root->relocation_src_root when we find
	 * the extent. If adjacent extents have different owners, we can't merge
	 * them while relocating. Handle this by storing the owning root that
	 * started a cluster and if we see an extent from a different root break
	 * cluster formation (just like the above case of non-adjacent extents).
	 *
	 * Without simple quotas, relocation_src_root is always 0, so we should
	 * never see a mismatch, and it should have no effect on relocation
	 * clusters.
	 */
	if (cluster->nr > 0 && cluster->owning_root != root->relocation_src_root) {
		u64 tmp = root->relocation_src_root;

		/*
		 * root->relocation_src_root is the state that actually affects
		 * the preallocation we do here, so set it to the root owning
		 * the cluster we need to relocate.
		 */
		root->relocation_src_root = cluster->owning_root;
		ret = relocate_file_extent_cluster(rc);
		if (ret)
			return ret;
		cluster->nr = 0;
		/* And reset it back for the current extent's owning root. */
		root->relocation_src_root = tmp;
	}

	if (!cluster->nr) {
		cluster->start = extent_key->objectid;
		cluster->owning_root = root->relocation_src_root;
	}
	else
		BUG_ON(cluster->nr >= MAX_EXTENTS);
	cluster->end = extent_key->objectid + extent_key->offset - 1;
	cluster->boundary[cluster->nr] = extent_key->objectid;
	cluster->nr++;

	if (cluster->nr >= MAX_EXTENTS) {
		ret = relocate_file_extent_cluster(rc);
		if (ret)
			return ret;
		cluster->nr = 0;
	}
	return 0;
}

/*
 * helper to add a tree block to the list.
 * the major work is getting the generation and level of the block
 */
static int add_tree_block(struct reloc_control *rc,
			  const struct btrfs_key *extent_key,
			  struct btrfs_path *path,
			  struct rb_root *blocks)
{
	struct extent_buffer *eb;
	struct btrfs_extent_item *ei;
	struct btrfs_tree_block_info *bi;
	struct tree_block *block;
	struct rb_node *rb_node;
	u32 item_size;
	int level = -1;
	u64 generation;
	u64 owner = 0;

	eb =  path->nodes[0];
	item_size = btrfs_item_size(eb, path->slots[0]);

	if (extent_key->type == BTRFS_METADATA_ITEM_KEY ||
	    item_size >= sizeof(*ei) + sizeof(*bi)) {
		unsigned long ptr = 0, end;

		ei = btrfs_item_ptr(eb, path->slots[0],
				struct btrfs_extent_item);
		end = (unsigned long)ei + item_size;
		if (extent_key->type == BTRFS_EXTENT_ITEM_KEY) {
			bi = (struct btrfs_tree_block_info *)(ei + 1);
			level = btrfs_tree_block_level(eb, bi);
			ptr = (unsigned long)(bi + 1);
		} else {
			level = (int)extent_key->offset;
			ptr = (unsigned long)(ei + 1);
		}
		generation = btrfs_extent_generation(eb, ei);

		/*
		 * We're reading random blocks without knowing their owner ahead
		 * of time.  This is ok most of the time, as all reloc roots and
		 * fs roots have the same lock type.  However normal trees do
		 * not, and the only way to know ahead of time is to read the
		 * inline ref offset.  We know it's an fs root if
		 *
		 * 1. There's more than one ref.
		 * 2. There's a SHARED_DATA_REF_KEY set.
		 * 3. FULL_BACKREF is set on the flags.
		 *
		 * Otherwise it's safe to assume that the ref offset == the
		 * owner of this block, so we can use that when calling
		 * read_tree_block.
		 */
		if (btrfs_extent_refs(eb, ei) == 1 &&
		    !(btrfs_extent_flags(eb, ei) &
		      BTRFS_BLOCK_FLAG_FULL_BACKREF) &&
		    ptr < end) {
			struct btrfs_extent_inline_ref *iref;
			int type;

			iref = (struct btrfs_extent_inline_ref *)ptr;
			type = btrfs_get_extent_inline_ref_type(eb, iref,
							BTRFS_REF_TYPE_BLOCK);
			if (type == BTRFS_REF_TYPE_INVALID)
				return -EINVAL;
			if (type == BTRFS_TREE_BLOCK_REF_KEY)
				owner = btrfs_extent_inline_ref_offset(eb, iref);
		}
	} else {
		btrfs_print_leaf(eb);
		btrfs_err(rc->block_group->fs_info,
			  "unrecognized tree backref at tree block %llu slot %u",
			  eb->start, path->slots[0]);
		btrfs_release_path(path);
		return -EUCLEAN;
	}

	btrfs_release_path(path);

	BUG_ON(level == -1);

	block = kmalloc_obj(*block, GFP_NOFS);
	if (!block)
		return -ENOMEM;

	block->bytenr = extent_key->objectid;
	block->key.objectid = rc->extent_root->fs_info->nodesize;
	block->key.offset = generation;
	block->level = level;
	block->key_ready = false;
	block->owner = owner;

	rb_node = rb_simple_insert(blocks, &block->simple_node);
	if (rb_node)
		btrfs_backref_panic(rc->extent_root->fs_info, block->bytenr,
				    -EEXIST);

	return 0;
}

/*
 * helper to add tree blocks for backref of type BTRFS_SHARED_DATA_REF_KEY
 */
static int __add_tree_block(struct reloc_control *rc,
			    u64 bytenr, u32 blocksize,
			    struct rb_root *blocks)
{
	struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
	BTRFS_PATH_AUTO_FREE(path);
	struct btrfs_key key;
	int ret;
	bool skinny = btrfs_fs_incompat(fs_info, SKINNY_METADATA);

	if (tree_block_processed(bytenr, rc))
		return 0;

	if (rb_simple_search(blocks, bytenr))
		return 0;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
again:
	key.objectid = bytenr;
	if (skinny) {
		key.type = BTRFS_METADATA_ITEM_KEY;
		key.offset = (u64)-1;
	} else {
		key.type = BTRFS_EXTENT_ITEM_KEY;
		key.offset = blocksize;
	}

	path->search_commit_root = true;
	path->skip_locking = true;
	ret = btrfs_search_slot(NULL, rc->extent_root, &key, path, 0, 0);
	if (ret < 0)
		return ret;

	if (ret > 0 && skinny) {
		if (path->slots[0]) {
			path->slots[0]--;
			btrfs_item_key_to_cpu(path->nodes[0], &key,
					      path->slots[0]);
			if (key.objectid == bytenr &&
			    (key.type == BTRFS_METADATA_ITEM_KEY ||
			     (key.type == BTRFS_EXTENT_ITEM_KEY &&
			      key.offset == blocksize)))
				ret = 0;
		}

		if (ret) {
			skinny = false;
			btrfs_release_path(path);
			goto again;
		}
	}
	if (ret) {
		ASSERT(ret == 1);
		btrfs_print_leaf(path->nodes[0]);
		btrfs_err(fs_info,
	     "tree block extent item (%llu) is not found in extent tree",
		     bytenr);
		WARN_ON(1);
		return -EINVAL;
	}

	return add_tree_block(rc, &key, path, blocks);
}

static int delete_block_group_cache(struct btrfs_block_group *block_group,
				    struct inode *inode,
				    u64 ino)
{
	struct btrfs_fs_info *fs_info = block_group->fs_info;
	struct btrfs_root *root = fs_info->tree_root;
	struct btrfs_trans_handle *trans;
	struct btrfs_inode *btrfs_inode;
	int ret = 0;

	if (inode)
		goto truncate;

	btrfs_inode = btrfs_iget(ino, root);
	if (IS_ERR(btrfs_inode))
		return -ENOENT;
	inode = &btrfs_inode->vfs_inode;

truncate:
	ret = btrfs_check_trunc_cache_free_space(fs_info,
						 &fs_info->global_block_rsv);
	if (ret)
		goto out;

	trans = btrfs_join_transaction(root);
	if (IS_ERR(trans)) {
		ret = PTR_ERR(trans);
		goto out;
	}

	ret = btrfs_truncate_free_space_cache(trans, block_group, inode);

	btrfs_end_transaction(trans);
	btrfs_btree_balance_dirty(fs_info);
out:
	iput(inode);
	return ret;
}

/*
 * Locate the free space cache EXTENT_DATA in root tree leaf and delete the
 * cache inode, to avoid free space cache data extent blocking data relocation.
 */
static int delete_v1_space_cache(struct extent_buffer *leaf,
				 struct btrfs_block_group *block_group,
				 u64 data_bytenr)
{
	u64 space_cache_ino;
	struct btrfs_file_extent_item *ei;
	struct btrfs_key key;
	bool found = false;
	int i;

	if (btrfs_header_owner(leaf) != BTRFS_ROOT_TREE_OBJECTID)
		return 0;

	for (i = 0; i < btrfs_header_nritems(leaf); i++) {
		u8 type;

		btrfs_item_key_to_cpu(leaf, &key, i);
		if (key.type != BTRFS_EXTENT_DATA_KEY)
			continue;
		ei = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item);
		type = btrfs_file_extent_type(leaf, ei);

		if ((type == BTRFS_FILE_EXTENT_REG ||
		     type == BTRFS_FILE_EXTENT_PREALLOC) &&
		    btrfs_file_extent_disk_bytenr(leaf, ei) == data_bytenr) {
			found = true;
			space_cache_ino = key.objectid;
			break;
		}
	}
	if (!found)
		return -ENOENT;

	return delete_block_group_cache(block_group, NULL, space_cache_ino);
}

/*
 * helper to find all tree blocks that reference a given data extent
 */
static noinline_for_stack int add_data_references(struct reloc_control *rc,
						  const struct btrfs_key *extent_key,
						  struct btrfs_path *path,
						  struct rb_root *blocks)
{
	struct btrfs_backref_walk_ctx ctx = { 0 };
	struct ulist_iterator leaf_uiter;
	struct ulist_node *ref_node = NULL;
	const u32 blocksize = rc->extent_root->fs_info->nodesize;
	int ret = 0;

	btrfs_release_path(path);

	ctx.bytenr = extent_key->objectid;
	ctx.skip_inode_ref_list = true;
	ctx.fs_info = rc->extent_root->fs_info;

	ret = btrfs_find_all_leafs(&ctx);
	if (ret < 0)
		return ret;

	ULIST_ITER_INIT(&leaf_uiter);
	while ((ref_node = ulist_next(ctx.refs, &leaf_uiter))) {
		struct btrfs_tree_parent_check check = { 0 };
		struct extent_buffer *eb;

		eb = read_tree_block(ctx.fs_info, ref_node->val, &check);
		if (IS_ERR(eb)) {
			ret = PTR_ERR(eb);
			break;
		}
		ret = delete_v1_space_cache(eb, rc->block_group,
					    extent_key->objectid);
		free_extent_buffer(eb);
		if (ret < 0)
			break;
		ret = __add_tree_block(rc, ref_node->val, blocksize, blocks);
		if (ret < 0)
			break;
	}
	if (ret < 0)
		free_block_list(blocks);
	ulist_free(ctx.refs);
	return ret;
}

/*
 * helper to find next unprocessed extent
 */
static noinline_for_stack
int find_next_extent(struct reloc_control *rc, struct btrfs_path *path,
		     struct btrfs_key *extent_key)
{
	struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
	struct btrfs_key key;
	struct extent_buffer *leaf;
	u64 start, end, last;
	int ret;

	last = rc->block_group->start + rc->block_group->length;
	while (1) {
		bool block_found;

		cond_resched();
		if (rc->search_start >= last) {
			ret = 1;
			break;
		}

		key.objectid = rc->search_start;
		key.type = BTRFS_EXTENT_ITEM_KEY;
		key.offset = 0;

		path->search_commit_root = true;
		path->skip_locking = true;
		ret = btrfs_search_slot(NULL, rc->extent_root, &key, path,
					0, 0);
		if (ret < 0)
			break;
next:
		leaf = path->nodes[0];
		if (path->slots[0] >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(rc->extent_root, path);
			if (ret != 0)
				break;
			leaf = path->nodes[0];
		}

		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
		if (key.objectid >= last) {
			ret = 1;
			break;
		}

		if (key.type != BTRFS_EXTENT_ITEM_KEY &&
		    key.type != BTRFS_METADATA_ITEM_KEY) {
			path->slots[0]++;
			goto next;
		}

		if (key.type == BTRFS_EXTENT_ITEM_KEY &&
		    key.objectid + key.offset <= rc->search_start) {
			path->slots[0]++;
			goto next;
		}

		if (key.type == BTRFS_METADATA_ITEM_KEY &&
		    key.objectid + fs_info->nodesize <=
		    rc->search_start) {
			path->slots[0]++;
			goto next;
		}

		block_found = btrfs_find_first_extent_bit(&rc->processed_blocks,
							  key.objectid, &start, &end,
							  EXTENT_DIRTY, NULL);

		if (block_found && start <= key.objectid) {
			btrfs_release_path(path);
			rc->search_start = end + 1;
		} else {
			if (key.type == BTRFS_EXTENT_ITEM_KEY)
				rc->search_start = key.objectid + key.offset;
			else
				rc->search_start = key.objectid +
					fs_info->nodesize;
			memcpy(extent_key, &key, sizeof(key));
			return 0;
		}
	}
	btrfs_release_path(path);
	return ret;
}

static void set_reloc_control(struct reloc_control *rc)
{
	struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;

	mutex_lock(&fs_info->reloc_mutex);
	fs_info->reloc_ctl = rc;
	mutex_unlock(&fs_info->reloc_mutex);
}

static void unset_reloc_control(struct reloc_control *rc)
{
	struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;

	mutex_lock(&fs_info->reloc_mutex);
	fs_info->reloc_ctl = NULL;
	mutex_unlock(&fs_info->reloc_mutex);
}

static noinline_for_stack
int prepare_to_relocate(struct reloc_control *rc)
{
	struct btrfs_trans_handle *trans;
	int ret;

	rc->block_rsv = btrfs_alloc_block_rsv(rc->extent_root->fs_info,
					      BTRFS_BLOCK_RSV_TEMP);
	if (!rc->block_rsv)
		return -ENOMEM;

	memset(&rc->cluster, 0, sizeof(rc->cluster));
	rc->search_start = rc->block_group->start;
	rc->extents_found = 0;
	rc->nodes_relocated = 0;
	rc->merging_rsv_size = 0;
	rc->reserved_bytes = 0;
	rc->block_rsv->size = rc->extent_root->fs_info->nodesize *
			      RELOCATION_RESERVED_NODES;
	ret = btrfs_block_rsv_refill(rc->extent_root->fs_info,
				     rc->block_rsv, rc->block_rsv->size,
				     BTRFS_RESERVE_FLUSH_ALL);
	if (ret)
		return ret;

	rc->create_reloc_tree = true;
	set_reloc_control(rc);

	trans = btrfs_join_transaction(rc->extent_root);
	if (IS_ERR(trans)) {
		unset_reloc_control(rc);
		/*
		 * extent tree is not a ref_cow tree and has no reloc_root to
		 * cleanup.  And callers are responsible to free the above
		 * block rsv.
		 */
		return PTR_ERR(trans);
	}

	ret = btrfs_commit_transaction(trans);
	if (ret)
		unset_reloc_control(rc);

	return ret;
}

static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
{
	struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
	struct rb_root blocks = RB_ROOT;
	struct btrfs_key key;
	struct btrfs_trans_handle *trans = NULL;
	BTRFS_PATH_AUTO_FREE(path);
	struct btrfs_extent_item *ei;
	u64 flags;
	int ret;
	int err = 0;
	int progress = 0;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
	path->reada = READA_FORWARD;

	ret = prepare_to_relocate(rc);
	if (ret) {
		err = ret;
		goto out_free;
	}

	while (1) {
		rc->reserved_bytes = 0;
		ret = btrfs_block_rsv_refill(fs_info, rc->block_rsv,
					     rc->block_rsv->size,
					     BTRFS_RESERVE_FLUSH_ALL);
		if (ret) {
			err = ret;
			break;
		}
		progress++;
		trans = btrfs_start_transaction(rc->extent_root, 0);
		if (IS_ERR(trans)) {
			err = PTR_ERR(trans);
			trans = NULL;
			break;
		}
restart:
		if (rc->backref_cache.last_trans != trans->transid)
			btrfs_backref_release_cache(&rc->backref_cache);
		rc->backref_cache.last_trans = trans->transid;

		ret = find_next_extent(rc, path, &key);
		if (ret < 0)
			err = ret;
		if (ret != 0)
			break;

		rc->extents_found++;

		ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
				    struct btrfs_extent_item);
		flags = btrfs_extent_flags(path->nodes[0], ei);

		/*
		 * If we are relocating a simple quota owned extent item, we
		 * need to note the owner on the reloc data root so that when
		 * we allocate the replacement item, we can attribute it to the
		 * correct eventual owner (rather than the reloc data root).
		 */
		if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_SIMPLE) {
			struct btrfs_root *root = BTRFS_I(rc->data_inode)->root;
			u64 owning_root_id = btrfs_get_extent_owner_root(fs_info,
								 path->nodes[0],
								 path->slots[0]);

			root->relocation_src_root = owning_root_id;
		}

		if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
			ret = add_tree_block(rc, &key, path, &blocks);
		} else if (rc->stage == UPDATE_DATA_PTRS &&
			   (flags & BTRFS_EXTENT_FLAG_DATA)) {
			ret = add_data_references(rc, &key, path, &blocks);
		} else {
			btrfs_release_path(path);
			ret = 0;
		}
		if (ret < 0) {
			err = ret;
			break;
		}

		if (!RB_EMPTY_ROOT(&blocks)) {
			ret = relocate_tree_blocks(trans, rc, &blocks);
			if (ret < 0) {
				if (ret != -EAGAIN) {
					err = ret;
					break;
				}
				rc->extents_found--;
				rc->search_start = key.objectid;
			}
		}

		btrfs_end_transaction_throttle(trans);
		btrfs_btree_balance_dirty(fs_info);
		trans = NULL;

		if (rc->stage == MOVE_DATA_EXTENTS &&
		    (flags & BTRFS_EXTENT_FLAG_DATA)) {
			rc->found_file_extent = true;
			ret = relocate_data_extent(rc, &key);
			if (ret < 0) {
				err = ret;
				break;
			}
		}
		if (btrfs_should_cancel_balance(fs_info)) {
			err = -ECANCELED;
			break;
		}
	}
	if (trans && progress && err == -ENOSPC) {
		ret = btrfs_force_chunk_alloc(trans, rc->block_group->flags);
		if (ret == 1) {
			err = 0;
			progress = 0;
			goto restart;
		}
	}

	btrfs_release_path(path);
	btrfs_clear_extent_bit(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY, NULL);

	if (trans) {
		btrfs_end_transaction_throttle(trans);
		btrfs_btree_balance_dirty(fs_info);
	}

	if (!err && !btrfs_fs_incompat(fs_info, REMAP_TREE)) {
		ret = relocate_file_extent_cluster(rc);
		if (ret < 0)
			err = ret;
	}

	rc->create_reloc_tree = false;
	set_reloc_control(rc);

	btrfs_backref_release_cache(&rc->backref_cache);
	btrfs_block_rsv_release(fs_info, rc->block_rsv, (u64)-1, NULL);

	/*
	 * Even in the case when the relocation is cancelled, we should all go
	 * through prepare_to_merge() and merge_reloc_roots().
	 *
	 * For error (including cancelled balance), prepare_to_merge() will
	 * mark all reloc trees orphan, then queue them for cleanup in
	 * merge_reloc_roots()
	 */
	err = prepare_to_merge(rc, err);

	merge_reloc_roots(rc);

	rc->merge_reloc_tree = false;
	unset_reloc_control(rc);
	btrfs_block_rsv_release(fs_info, rc->block_rsv, (u64)-1, NULL);

	/* get rid of pinned extents */
	ret = btrfs_commit_current_transaction(rc->extent_root);
	if (ret && !err)
		err = ret;
out_free:
	ret = clean_dirty_subvols(rc);
	if (ret < 0 && !err)
		err = ret;
	btrfs_free_block_rsv(fs_info, rc->block_rsv);
	return err;
}

static int __insert_orphan_inode(struct btrfs_trans_handle *trans,
				 struct btrfs_root *root, u64 objectid)
{
	BTRFS_PATH_AUTO_FREE(path);
	struct btrfs_inode_item *item;
	struct extent_buffer *leaf;
	int ret;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;

	ret = btrfs_insert_empty_inode(trans, root, path, objectid);
	if (ret)
		return ret;

	leaf = path->nodes[0];
	item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_inode_item);
	memzero_extent_buffer(leaf, (unsigned long)item, sizeof(*item));
	btrfs_set_inode_generation(leaf, item, 1);
	btrfs_set_inode_size(leaf, item, 0);
	btrfs_set_inode_mode(leaf, item, S_IFREG | 0600);
	btrfs_set_inode_flags(leaf, item, BTRFS_INODE_NOCOMPRESS |
					  BTRFS_INODE_PREALLOC);
	return 0;
}

static void delete_orphan_inode(struct btrfs_trans_handle *trans,
				struct btrfs_root *root, u64 objectid)
{
	BTRFS_PATH_AUTO_FREE(path);
	struct btrfs_key key;
	int ret = 0;

	path = btrfs_alloc_path();
	if (!path) {
		ret = -ENOMEM;
		goto out;
	}

	key.objectid = objectid;
	key.type = BTRFS_INODE_ITEM_KEY;
	key.offset = 0;
	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
	if (ret) {
		if (ret > 0)
			ret = -ENOENT;
		goto out;
	}
	ret = btrfs_del_item(trans, root, path);
out:
	if (ret)
		btrfs_abort_transaction(trans, ret);
}

/*
 * helper to create inode for data relocation.
 * the inode is in data relocation tree and its link count is 0
 */
static noinline_for_stack struct inode *create_reloc_inode(
					const struct btrfs_block_group *group)
{
	struct btrfs_fs_info *fs_info = group->fs_info;
	struct btrfs_inode *inode = NULL;
	struct btrfs_trans_handle *trans;
	struct btrfs_root *root;
	u64 objectid;
	int ret = 0;

	root = btrfs_grab_root(fs_info->data_reloc_root);
	trans = btrfs_start_transaction(root, 6);
	if (IS_ERR(trans)) {
		btrfs_put_root(root);
		return ERR_CAST(trans);
	}

	ret = btrfs_get_free_objectid(root, &objectid);
	if (ret)
		goto out;

	ret = __insert_orphan_inode(trans, root, objectid);
	if (ret)
		goto out;

	inode = btrfs_iget(objectid, root);
	if (IS_ERR(inode)) {
		delete_orphan_inode(trans, root, objectid);
		ret = PTR_ERR(inode);
		inode = NULL;
		goto out;
	}
	inode->reloc_block_group_start = group->start;

	ret = btrfs_orphan_add(trans, inode);
out:
	btrfs_put_root(root);
	btrfs_end_transaction(trans);
	btrfs_btree_balance_dirty(fs_info);
	if (ret) {
		if (inode)
			iput(&inode->vfs_inode);
		return ERR_PTR(ret);
	}
	return &inode->vfs_inode;
}

/*
 * Mark start of chunk relocation that is cancellable. Check if the cancellation
 * has been requested meanwhile and don't start in that case.
 * NOTE: if this returns an error, reloc_chunk_end() must not be called.
 *
 * Return:
 *   0             success
 *   -EINPROGRESS  operation is already in progress, that's probably a bug
 *   -ECANCELED    cancellation request was set before the operation started
 */
static int reloc_chunk_start(struct btrfs_fs_info *fs_info)
{
	if (test_and_set_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags)) {
		/* This should not happen */
		btrfs_err(fs_info, "reloc already running, cannot start");
		return -EINPROGRESS;
	}

	if (atomic_read(&fs_info->reloc_cancel_req) > 0) {
		btrfs_info(fs_info, "chunk relocation canceled on start");
		/* On cancel, clear all requests. */
		clear_and_wake_up_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags);
		atomic_set(&fs_info->reloc_cancel_req, 0);
		return -ECANCELED;
	}
	return 0;
}

/*
 * Mark end of chunk relocation that is cancellable and wake any waiters.
 * NOTE: call only if a previous call to reloc_chunk_start() succeeded.
 */
static void reloc_chunk_end(struct btrfs_fs_info *fs_info)
{
	ASSERT(test_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags));
	/* Requested after start, clear bit first so any waiters can continue */
	if (atomic_read(&fs_info->reloc_cancel_req) > 0)
		btrfs_info(fs_info, "chunk relocation canceled during operation");
	clear_and_wake_up_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags);
	atomic_set(&fs_info->reloc_cancel_req, 0);
}

static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info)
{
	struct reloc_control *rc;

	rc = kzalloc_obj(*rc, GFP_NOFS);
	if (!rc)
		return NULL;

	INIT_LIST_HEAD(&rc->reloc_roots);
	INIT_LIST_HEAD(&rc->dirty_subvol_roots);
	btrfs_backref_init_cache(fs_info, &rc->backref_cache, true);
	rc->reloc_root_tree.rb_root = RB_ROOT;
	spin_lock_init(&rc->reloc_root_tree.lock);
	btrfs_extent_io_tree_init(fs_info, &rc->processed_blocks, IO_TREE_RELOC_BLOCKS);
	return rc;
}

static void free_reloc_control(struct reloc_control *rc)
{
	struct mapping_node *node, *tmp;

	free_reloc_roots(&rc->reloc_roots);
	rbtree_postorder_for_each_entry_safe(node, tmp,
			&rc->reloc_root_tree.rb_root, rb_node)
		kfree(node);

	kfree(rc);
}

/*
 * Print the block group being relocated
 */
static void describe_relocation(struct btrfs_block_group *block_group)
{
	char buf[128] = "NONE";

	btrfs_describe_block_groups(block_group->flags, buf, sizeof(buf));

	btrfs_info(block_group->fs_info, "relocating block group %llu flags %s",
		   block_group->start, buf);
}

static const char *stage_to_string(enum reloc_stage stage)
{
	if (stage == MOVE_DATA_EXTENTS)
		return "move data extents";
	if (stage == UPDATE_DATA_PTRS)
		return "update data pointers";
	return "unknown";
}

static int add_remap_tree_entries(struct btrfs_trans_handle *trans, struct btrfs_path *path,
				  struct btrfs_key *entries, unsigned int num_entries)
{
	int ret;
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_item_batch batch;
	u32 *data_sizes;
	u32 max_items;

	max_items = BTRFS_LEAF_DATA_SIZE(trans->fs_info) / sizeof(struct btrfs_item);

	data_sizes = kzalloc(sizeof(u32) * min_t(u32, num_entries, max_items), GFP_NOFS);
	if (!data_sizes)
		return -ENOMEM;

	while (true) {
		batch.keys = entries;
		batch.data_sizes = data_sizes;
		batch.total_data_size = 0;
		batch.nr = min_t(u32, num_entries, max_items);

		ret = btrfs_insert_empty_items(trans, fs_info->remap_root, path, &batch);
		btrfs_release_path(path);

		if (ret || num_entries <= max_items)
			break;

		num_entries -= max_items;
		entries += max_items;
	}

	kfree(data_sizes);

	return ret;
}

struct space_run {
	u64 start;
	u64 end;
};

static void parse_bitmap(u64 block_size, const unsigned long *bitmap,
			 unsigned long size, u64 address, struct space_run *space_runs,
			 unsigned int *num_space_runs)
{
	unsigned long pos, end;
	u64 run_start, run_length;

	pos = find_first_bit(bitmap, size);
	if (pos == size)
		return;

	while (true) {
		end = find_next_zero_bit(bitmap, size, pos);

		run_start = address + (pos * block_size);
		run_length = (end - pos) * block_size;

		if (*num_space_runs != 0 &&
		    space_runs[*num_space_runs - 1].end == run_start) {
			space_runs[*num_space_runs - 1].end += run_length;
		} else {
			space_runs[*num_space_runs].start = run_start;
			space_runs[*num_space_runs].end = run_start + run_length;

			(*num_space_runs)++;
		}

		if (end == size)
			break;

		pos = find_next_bit(bitmap, size, end + 1);
		if (pos == size)
			break;
	}
}

static void adjust_block_group_remap_bytes(struct btrfs_trans_handle *trans,
					   struct btrfs_block_group *bg, s64 diff)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	bool bg_already_dirty = true;
	bool mark_unused = false;

	spin_lock(&bg->lock);
	bg->remap_bytes += diff;
	if (bg->used == 0 && bg->remap_bytes == 0)
		mark_unused = true;
	spin_unlock(&bg->lock);

	if (mark_unused)
		btrfs_mark_bg_unused(bg);

	spin_lock(&trans->transaction->dirty_bgs_lock);
	if (list_empty(&bg->dirty_list)) {
		list_add_tail(&bg->dirty_list, &trans->transaction->dirty_bgs);
		bg_already_dirty = false;
		btrfs_get_block_group(bg);
	}
	spin_unlock(&trans->transaction->dirty_bgs_lock);

	/* Modified block groups are accounted for in the delayed_refs_rsv. */
	if (!bg_already_dirty)
		btrfs_inc_delayed_refs_rsv_bg_updates(fs_info);
}

/* Private structure for I/O from copy_remapped_data().  */
struct reloc_io_private {
	struct completion done;
	refcount_t pending_refs;
	blk_status_t status;
};

static void reloc_endio(struct btrfs_bio *bbio)
{
	struct reloc_io_private *priv = bbio->private;

	if (bbio->bio.bi_status)
		WRITE_ONCE(priv->status, bbio->bio.bi_status);

	if (refcount_dec_and_test(&priv->pending_refs))
		complete(&priv->done);

	bio_put(&bbio->bio);
}

static int copy_remapped_data_io(struct btrfs_fs_info *fs_info,
				 struct reloc_io_private *priv,
				 struct page **pages, u64 addr, u64 length,
				 blk_opf_t op)
{
	struct btrfs_bio *bbio;
	int i;

	init_completion(&priv->done);
	refcount_set(&priv->pending_refs, 1);
	priv->status = 0;

	bbio = btrfs_bio_alloc(BIO_MAX_VECS, op, BTRFS_I(fs_info->btree_inode),
			       addr, reloc_endio, priv);
	bbio->bio.bi_iter.bi_sector = (addr >> SECTOR_SHIFT);
	bbio->is_remap = true;

	i = 0;
	do {
		size_t bytes = min_t(u64, length, PAGE_SIZE);

		if (bio_add_page(&bbio->bio, pages[i], bytes, 0) < bytes) {
			refcount_inc(&priv->pending_refs);
			btrfs_submit_bbio(bbio, 0);

			bbio = btrfs_bio_alloc(BIO_MAX_VECS, op,
					       BTRFS_I(fs_info->btree_inode),
					       addr, reloc_endio, priv);
			bbio->bio.bi_iter.bi_sector = (addr >> SECTOR_SHIFT);
			bbio->is_remap = true;
			continue;
		}

		i++;
		addr += bytes;
		length -= bytes;
	} while (length);

	refcount_inc(&priv->pending_refs);
	btrfs_submit_bbio(bbio, 0);

	if (!refcount_dec_and_test(&priv->pending_refs))
		wait_for_completion_io(&priv->done);

	return blk_status_to_errno(READ_ONCE(priv->status));
}

static int copy_remapped_data(struct btrfs_fs_info *fs_info, u64 old_addr,
			      u64 new_addr, u64 length)
{
	int ret;
	u64 copy_len = min_t(u64, length, SZ_1M);
	struct page **pages;
	struct reloc_io_private priv;
	unsigned int nr_pages = DIV_ROUND_UP(length, PAGE_SIZE);

	pages = kzalloc_objs(struct page *, nr_pages, GFP_NOFS);
	if (!pages)
		return -ENOMEM;

	ret = btrfs_alloc_page_array(nr_pages, pages, 0);
	if (ret) {
		ret = -ENOMEM;
		goto end;
	}

	/* Copy 1MB at a time, to avoid using too much memory. */
	do {
		u64 to_copy = min_t(u64, length, copy_len);

		/* Limit to one bio. */
		to_copy = min_t(u64, to_copy, BIO_MAX_VECS << PAGE_SHIFT);

		ret = copy_remapped_data_io(fs_info, &priv, pages, old_addr,
					    to_copy, REQ_OP_READ);
		if (ret)
			goto end;

		ret = copy_remapped_data_io(fs_info, &priv, pages, new_addr,
					    to_copy, REQ_OP_WRITE);
		if (ret)
			goto end;

		if (to_copy == length)
			break;

		old_addr += to_copy;
		new_addr += to_copy;
		length -= to_copy;
	} while (true);

	ret = 0;
end:
	for (int i = 0; i < nr_pages; i++) {
		if (pages[i])
			__free_page(pages[i]);
	}
	kfree(pages);

	return ret;
}

static int add_remap_item(struct btrfs_trans_handle *trans,
			  struct btrfs_path *path, u64 new_addr, u64 length,
			  u64 old_addr)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_remap_item remap = { 0 };
	struct btrfs_key key;
	struct extent_buffer *leaf;
	int ret;

	key.objectid = old_addr;
	key.type = BTRFS_REMAP_KEY;
	key.offset = length;

	ret = btrfs_insert_empty_item(trans, fs_info->remap_root, path,
				      &key, sizeof(struct btrfs_remap_item));
	if (ret)
		return ret;

	leaf = path->nodes[0];
	btrfs_set_stack_remap_address(&remap, new_addr);
	write_extent_buffer(leaf, &remap, btrfs_item_ptr_offset(leaf, path->slots[0]),
			    sizeof(struct btrfs_remap_item));

	btrfs_release_path(path);

	return 0;
}

static int add_remap_backref_item(struct btrfs_trans_handle *trans,
				  struct btrfs_path *path, u64 new_addr,
				  u64 length, u64 old_addr)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_remap_item remap = { 0 };
	struct btrfs_key key;
	struct extent_buffer *leaf;
	int ret;

	key.objectid = new_addr;
	key.type = BTRFS_REMAP_BACKREF_KEY;
	key.offset = length;

	ret = btrfs_insert_empty_item(trans, fs_info->remap_root, path, &key,
				      sizeof(struct btrfs_remap_item));
	if (ret)
		return ret;

	leaf = path->nodes[0];
	btrfs_set_stack_remap_address(&remap, old_addr);
	write_extent_buffer(leaf, &remap, btrfs_item_ptr_offset(leaf, path->slots[0]),
			    sizeof(struct btrfs_remap_item));

	btrfs_release_path(path);

	return 0;
}

static int move_existing_remap(struct btrfs_fs_info *fs_info,
			       struct btrfs_path *path,
			       struct btrfs_block_group *bg, u64 new_addr,
			       u64 length, u64 old_addr)
{
	struct btrfs_trans_handle *trans;
	struct extent_buffer *leaf;
	struct btrfs_remap_item *remap_ptr;
	struct btrfs_remap_item remap = { 0 };
	struct btrfs_key key, ins;
	u64 dest_addr, dest_length, min_size;
	struct btrfs_block_group *dest_bg;
	int ret;
	const bool is_data = (bg->flags & BTRFS_BLOCK_GROUP_DATA);
	struct btrfs_space_info *sinfo = bg->space_info;
	bool mutex_taken = false;
	bool bg_needs_free_space;

	spin_lock(&sinfo->lock);
	btrfs_space_info_update_bytes_may_use(sinfo, length);
	spin_unlock(&sinfo->lock);

	if (is_data)
		min_size = fs_info->sectorsize;
	else
		min_size = fs_info->nodesize;

	ret = btrfs_reserve_extent(fs_info->fs_root, length, length, min_size,
				   0, 0, &ins, is_data, false);
	if (unlikely(ret)) {
		spin_lock(&sinfo->lock);
		btrfs_space_info_update_bytes_may_use(sinfo, -length);
		spin_unlock(&sinfo->lock);
		return ret;
	}

	if (ins.offset < length) {
		spin_lock(&sinfo->lock);
		btrfs_space_info_update_bytes_may_use(sinfo, ins.offset - length);
		spin_unlock(&sinfo->lock);
	}

	dest_addr = ins.objectid;
	dest_length = ins.offset;

	dest_bg = btrfs_lookup_block_group(fs_info, dest_addr);

	if (!is_data && !IS_ALIGNED(dest_length, fs_info->nodesize)) {
		u64 new_length = ALIGN_DOWN(dest_length, fs_info->nodesize);

		btrfs_free_reserved_extent(fs_info, dest_addr + new_length,
					   dest_length - new_length, 0);

		dest_length = new_length;
	}

	trans = btrfs_join_transaction(fs_info->remap_root);
	if (IS_ERR(trans)) {
		ret = PTR_ERR(trans);
		trans = NULL;
		goto end;
	}

	mutex_lock(&fs_info->remap_mutex);
	mutex_taken = true;

	/* Find old remap entry. */
	key.objectid = old_addr;
	key.type = BTRFS_REMAP_KEY;
	key.offset = length;

	ret = btrfs_search_slot(trans, fs_info->remap_root, &key, path, 0, 1);
	if (ret == 1) {
		/*
		 * Not a problem if the remap entry wasn't found: that means
		 * that another transaction has deallocated the data.
		 * move_existing_remaps() loops until the BG contains no
		 * remaps, so we can just return 0 in this case.
		 */
		btrfs_release_path(path);
		ret = 0;
		goto end;
	} else if (unlikely(ret)) {
		goto end;
	}

	ret = copy_remapped_data(fs_info, new_addr, dest_addr, dest_length);
	if (unlikely(ret))
		goto end;

	/* Change data of old remap entry. */
	leaf = path->nodes[0];
	remap_ptr = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_remap_item);
	btrfs_set_remap_address(leaf, remap_ptr, dest_addr);
	btrfs_mark_buffer_dirty(trans, leaf);

	if (dest_length != length) {
		key.offset = dest_length;
		btrfs_set_item_key_safe(trans, path, &key);
	}

	btrfs_release_path(path);

	if (dest_length != length) {
		/* Add remap item for remainder. */
		ret = add_remap_item(trans, path, new_addr + dest_length,
				     length - dest_length, old_addr + dest_length);
		if (unlikely(ret))
			goto end;
	}

	/* Change or remove old backref. */
	key.objectid = new_addr;
	key.type = BTRFS_REMAP_BACKREF_KEY;
	key.offset = length;

	ret = btrfs_search_slot(trans, fs_info->remap_root, &key, path, -1, 1);
	if (unlikely(ret)) {
		if (ret == 1) {
			btrfs_release_path(path);
			ret = -ENOENT;
		}
		goto end;
	}

	leaf = path->nodes[0];

	if (dest_length == length) {
		ret = btrfs_del_item(trans, fs_info->remap_root, path);
		if (unlikely(ret)) {
			btrfs_release_path(path);
			goto end;
		}
	} else {
		key.objectid += dest_length;
		key.offset -= dest_length;
		btrfs_set_item_key_safe(trans, path, &key);
		btrfs_set_stack_remap_address(&remap, old_addr + dest_length);

		write_extent_buffer(leaf, &remap,
				    btrfs_item_ptr_offset(leaf, path->slots[0]),
				    sizeof(struct btrfs_remap_item));
	}

	btrfs_release_path(path);

	/* Add new backref. */
	ret = add_remap_backref_item(trans, path, dest_addr, dest_length, old_addr);
	if (unlikely(ret))
		goto end;

	adjust_block_group_remap_bytes(trans, bg, -dest_length);

	ret = btrfs_add_to_free_space_tree(trans, new_addr, dest_length);
	if (unlikely(ret))
		goto end;

	adjust_block_group_remap_bytes(trans, dest_bg, dest_length);

	mutex_lock(&dest_bg->free_space_lock);
	bg_needs_free_space = test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE,
				       &dest_bg->runtime_flags);
	mutex_unlock(&dest_bg->free_space_lock);

	if (bg_needs_free_space) {
		ret = btrfs_add_block_group_free_space(trans, dest_bg);
		if (unlikely(ret))
			goto end;
	}

	ret = btrfs_remove_from_free_space_tree(trans, dest_addr, dest_length);
	if (unlikely(ret)) {
		btrfs_remove_from_free_space_tree(trans, new_addr, dest_length);
		goto end;
	}

	ret = 0;

end:
	if (mutex_taken)
		mutex_unlock(&fs_info->remap_mutex);

	btrfs_dec_block_group_reservations(fs_info, dest_addr);

	if (unlikely(ret)) {
		btrfs_free_reserved_extent(fs_info, dest_addr, dest_length, 0);

		if (trans) {
			btrfs_abort_transaction(trans, ret);
			btrfs_end_transaction(trans);
		}
	} else {
		btrfs_free_reserved_bytes(dest_bg, dest_length, 0);

		ret = btrfs_commit_transaction(trans);
	}

	btrfs_put_block_group(dest_bg);

	return ret;
}

static int move_existing_remaps(struct btrfs_fs_info *fs_info,
				struct btrfs_block_group *bg,
				struct btrfs_path *path)
{
	int ret;
	struct btrfs_key key;
	struct extent_buffer *leaf;
	struct btrfs_remap_item *remap;
	u64 old_addr;

	/* Look for backrefs in remap tree. */
	while (bg->remap_bytes > 0) {
		key.objectid = bg->start;
		key.type = BTRFS_REMAP_BACKREF_KEY;
		key.offset = 0;

		ret = btrfs_search_slot(NULL, fs_info->remap_root, &key, path, 0, 0);
		if (ret < 0)
			return ret;

		leaf = path->nodes[0];

		if (path->slots[0] >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(fs_info->remap_root, path);
			if (ret < 0) {
				btrfs_release_path(path);
				return ret;
			}

			if (ret) {
				btrfs_release_path(path);
				break;
			}

			leaf = path->nodes[0];
		}

		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);

		if (key.type != BTRFS_REMAP_BACKREF_KEY) {
			path->slots[0]++;

			if (path->slots[0] >= btrfs_header_nritems(leaf)) {
				ret = btrfs_next_leaf(fs_info->remap_root, path);
				if (ret < 0) {
					btrfs_release_path(path);
					return ret;
				}

				if (ret) {
					btrfs_release_path(path);
					break;
				}

				leaf = path->nodes[0];
			}

			btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
		}

		remap = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_remap_item);
		old_addr = btrfs_remap_address(leaf, remap);

		btrfs_release_path(path);

		ret = move_existing_remap(fs_info, path, bg, key.objectid,
					  key.offset, old_addr);
		if (ret)
			return ret;
	}

	ASSERT(bg->remap_bytes == 0);

	return 0;
}

static int create_remap_tree_entries(struct btrfs_trans_handle *trans,
				     struct btrfs_path *path,
				     struct btrfs_block_group *bg)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_free_space_info *fsi;
	struct btrfs_key key, found_key;
	struct extent_buffer *leaf;
	struct btrfs_root *space_root;
	u32 extent_count;
	struct space_run *space_runs = NULL;
	unsigned int num_space_runs = 0;
	struct btrfs_key *entries = NULL;
	unsigned int max_entries, num_entries;
	int ret;

	mutex_lock(&bg->free_space_lock);

	if (test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &bg->runtime_flags)) {
		mutex_unlock(&bg->free_space_lock);

		ret = btrfs_add_block_group_free_space(trans, bg);
		if (ret)
			return ret;

		mutex_lock(&bg->free_space_lock);
	}

	fsi = btrfs_search_free_space_info(trans, bg, path, 0);
	if (IS_ERR(fsi)) {
		mutex_unlock(&bg->free_space_lock);
		return PTR_ERR(fsi);
	}

	extent_count = btrfs_free_space_extent_count(path->nodes[0], fsi);

	btrfs_release_path(path);

	space_runs = kmalloc(sizeof(*space_runs) * extent_count, GFP_NOFS);
	if (!space_runs) {
		mutex_unlock(&bg->free_space_lock);
		return -ENOMEM;
	}

	key.objectid = bg->start;
	key.type = 0;
	key.offset = 0;

	space_root = btrfs_free_space_root(bg);

	ret = btrfs_search_slot(trans, space_root, &key, path, 0, 0);
	if (ret < 0) {
		mutex_unlock(&bg->free_space_lock);
		goto out;
	}

	ret = 0;

	while (true) {
		leaf = path->nodes[0];

		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);

		if (found_key.objectid >= bg->start + bg->length)
			break;

		if (found_key.type == BTRFS_FREE_SPACE_EXTENT_KEY) {
			if (num_space_runs != 0 &&
			    space_runs[num_space_runs - 1].end == found_key.objectid) {
				space_runs[num_space_runs - 1].end =
					found_key.objectid + found_key.offset;
			} else {
				ASSERT(num_space_runs < extent_count);

				space_runs[num_space_runs].start = found_key.objectid;
				space_runs[num_space_runs].end =
					found_key.objectid + found_key.offset;

				num_space_runs++;
			}
		} else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) {
			void *bitmap;
			unsigned long offset;
			u32 data_size;

			offset = btrfs_item_ptr_offset(leaf, path->slots[0]);
			data_size = btrfs_item_size(leaf, path->slots[0]);

			if (data_size != 0) {
				bitmap = kmalloc(data_size, GFP_NOFS);
				if (!bitmap) {
					mutex_unlock(&bg->free_space_lock);
					ret = -ENOMEM;
					goto out;
				}

				read_extent_buffer(leaf, bitmap, offset, data_size);

				parse_bitmap(fs_info->sectorsize, bitmap,
					     data_size * BITS_PER_BYTE,
					     found_key.objectid, space_runs,
					     &num_space_runs);

				ASSERT(num_space_runs <= extent_count);

				kfree(bitmap);
			}
		}

		path->slots[0]++;

		if (path->slots[0] >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(space_root, path);
			if (ret != 0) {
				if (ret == 1)
					ret = 0;
				break;
			}
			leaf = path->nodes[0];
		}
	}

	btrfs_release_path(path);

	mutex_unlock(&bg->free_space_lock);

	max_entries = extent_count + 2;
	entries = kmalloc(sizeof(*entries) * max_entries, GFP_NOFS);
	if (!entries) {
		ret = -ENOMEM;
		goto out;
	}

	num_entries = 0;

	if (num_space_runs == 0) {
		entries[num_entries].objectid = bg->start;
		entries[num_entries].type = BTRFS_IDENTITY_REMAP_KEY;
		entries[num_entries].offset = bg->length;
		num_entries++;
	} else {
		if (space_runs[0].start > bg->start) {
			entries[num_entries].objectid = bg->start;
			entries[num_entries].type = BTRFS_IDENTITY_REMAP_KEY;
			entries[num_entries].offset = space_runs[0].start - bg->start;
			num_entries++;
		}

		for (unsigned int i = 1; i < num_space_runs; i++) {
			entries[num_entries].objectid = space_runs[i - 1].end;
			entries[num_entries].type = BTRFS_IDENTITY_REMAP_KEY;
			entries[num_entries].offset =
				space_runs[i].start - space_runs[i - 1].end;
			num_entries++;
		}

		if (space_runs[num_space_runs - 1].end < bg->start + bg->length) {
			entries[num_entries].objectid =
				space_runs[num_space_runs - 1].end;
			entries[num_entries].type = BTRFS_IDENTITY_REMAP_KEY;
			entries[num_entries].offset =
				bg->start + bg->length - space_runs[num_space_runs - 1].end;
			num_entries++;
		}

		if (num_entries == 0)
			goto out;
	}

	bg->identity_remap_count = num_entries;

	ret = add_remap_tree_entries(trans, path, entries, num_entries);

out:
	kfree(entries);
	kfree(space_runs);

	return ret;
}

static int find_next_identity_remap(struct btrfs_trans_handle *trans,
				    struct btrfs_path *path, u64 bg_end,
				    u64 last_start, u64 *start, u64 *length)
{
	int ret;
	struct btrfs_key key, found_key;
	struct btrfs_root *remap_root = trans->fs_info->remap_root;
	struct extent_buffer *leaf;

	key.objectid = last_start;
	key.type = BTRFS_IDENTITY_REMAP_KEY;
	key.offset = 0;

	ret = btrfs_search_slot(trans, remap_root, &key, path, 0, 0);
	if (ret < 0)
		goto out;

	leaf = path->nodes[0];
	while (true) {
		if (path->slots[0] >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(remap_root, path);

			if (ret != 0) {
				if (ret == 1)
					ret = -ENOENT;
				goto out;
			}

			leaf = path->nodes[0];
		}

		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);

		if (found_key.objectid >= bg_end) {
			ret = -ENOENT;
			goto out;
		}

		if (found_key.type == BTRFS_IDENTITY_REMAP_KEY) {
			*start = found_key.objectid;
			*length = found_key.offset;
			ret = 0;
			goto out;
		}

		path->slots[0]++;
	}

out:
	btrfs_release_path(path);

	return ret;
}

static int remove_chunk_stripes(struct btrfs_trans_handle *trans,
				struct btrfs_chunk_map *chunk_map,
				struct btrfs_path *path)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_key key;
	struct extent_buffer *leaf;
	struct btrfs_chunk *chunk;
	int ret;

	key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
	key.type = BTRFS_CHUNK_ITEM_KEY;
	key.offset = chunk_map->start;

	btrfs_reserve_chunk_metadata(trans, false);

	ret = btrfs_search_slot(trans, fs_info->chunk_root, &key, path, 0, 1);
	if (ret) {
		if (ret == 1) {
			btrfs_release_path(path);
			ret = -ENOENT;
		}
		btrfs_trans_release_chunk_metadata(trans);
		return ret;
	}

	leaf = path->nodes[0];

	chunk = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_chunk);
	btrfs_set_chunk_num_stripes(leaf, chunk, 0);
	btrfs_set_chunk_sub_stripes(leaf, chunk, 0);

	btrfs_truncate_item(trans, path, offsetof(struct btrfs_chunk, stripe), 1);

	btrfs_mark_buffer_dirty(trans, leaf);

	btrfs_release_path(path);
	btrfs_trans_release_chunk_metadata(trans);

	return 0;
}

int btrfs_last_identity_remap_gone(struct btrfs_chunk_map *chunk_map,
				   struct btrfs_block_group *bg)
{
	struct btrfs_fs_info *fs_info = bg->fs_info;
	struct btrfs_trans_handle *trans;
	int ret;
	unsigned int num_items;
	BTRFS_PATH_AUTO_FREE(path);

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;

	/*
	 * One item for each entry we're removing in the dev extents tree, and
	 * another for each device. DUP chunks are all on one device,
	 * everything else has one device per stripe.
	 */
	if (bg->flags & BTRFS_BLOCK_GROUP_DUP)
		num_items = chunk_map->num_stripes + 1;
	else
		num_items = 2 * chunk_map->num_stripes;

	trans = btrfs_start_transaction_fallback_global_rsv(fs_info->tree_root, num_items);
	if (IS_ERR(trans))
		return PTR_ERR(trans);

	ret = btrfs_remove_dev_extents(trans, chunk_map);
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		btrfs_end_transaction(trans);
		return ret;
	}

	mutex_lock(&trans->fs_info->chunk_mutex);
	for (unsigned int i = 0; i < chunk_map->num_stripes; i++) {
		ret = btrfs_update_device(trans, chunk_map->stripes[i].dev);
		if (unlikely(ret)) {
			mutex_unlock(&trans->fs_info->chunk_mutex);
			btrfs_abort_transaction(trans, ret);
			btrfs_end_transaction(trans);
			return ret;
		}
	}
	mutex_unlock(&trans->fs_info->chunk_mutex);

	write_lock(&trans->fs_info->mapping_tree_lock);
	btrfs_chunk_map_device_clear_bits(chunk_map, CHUNK_ALLOCATED);
	write_unlock(&trans->fs_info->mapping_tree_lock);

	btrfs_remove_bg_from_sinfo(bg);

	spin_lock(&bg->lock);
	clear_bit(BLOCK_GROUP_FLAG_STRIPE_REMOVAL_PENDING, &bg->runtime_flags);
	spin_unlock(&bg->lock);

	ret = remove_chunk_stripes(trans, chunk_map, path);
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		btrfs_end_transaction(trans);
		return ret;
	}

	ret = btrfs_commit_transaction(trans);
	if (ret)
		return ret;

	return 0;
}

static void adjust_identity_remap_count(struct btrfs_trans_handle *trans,
				        struct btrfs_block_group *bg, int delta)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	bool bg_already_dirty = true;
	bool mark_fully_remapped = false;

	WARN_ON(delta < 0 && -delta > bg->identity_remap_count);

	spin_lock(&bg->lock);

	bg->identity_remap_count += delta;

	if (bg->identity_remap_count == 0 &&
	    !test_bit(BLOCK_GROUP_FLAG_FULLY_REMAPPED, &bg->runtime_flags)) {
		set_bit(BLOCK_GROUP_FLAG_FULLY_REMAPPED, &bg->runtime_flags);
		mark_fully_remapped = true;
	}

	spin_unlock(&bg->lock);

	spin_lock(&trans->transaction->dirty_bgs_lock);
	if (list_empty(&bg->dirty_list)) {
		list_add_tail(&bg->dirty_list, &trans->transaction->dirty_bgs);
		bg_already_dirty = false;
		btrfs_get_block_group(bg);
	}
	spin_unlock(&trans->transaction->dirty_bgs_lock);

	/* Modified block groups are accounted for in the delayed_refs_rsv. */
	if (!bg_already_dirty)
		btrfs_inc_delayed_refs_rsv_bg_updates(fs_info);

	if (mark_fully_remapped)
		btrfs_mark_bg_fully_remapped(bg, trans);
}

static int add_remap_entry(struct btrfs_trans_handle *trans,
			   struct btrfs_path *path,
			   struct btrfs_block_group *src_bg, u64 old_addr,
			   u64 new_addr, u64 length)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_key key, new_key;
	int ret;
	int identity_count_delta = 0;

	key.objectid = old_addr;
	key.type = (u8)-1;
	key.offset = (u64)-1;

	ret = btrfs_search_slot(trans, fs_info->remap_root, &key, path, -1, 1);
	if (ret < 0)
		goto end;

	if (path->slots[0] == 0) {
		ret = -ENOENT;
		goto end;
	}

	path->slots[0]--;

	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);

	if (key.type != BTRFS_IDENTITY_REMAP_KEY ||
	    key.objectid > old_addr ||
	    key.objectid + key.offset <= old_addr) {
		ret = -ENOENT;
		goto end;
	}

	/* Shorten or delete identity mapping entry. */
	if (key.objectid == old_addr) {
		ret = btrfs_del_item(trans, fs_info->remap_root, path);
		if (ret)
			goto end;

		identity_count_delta--;
	} else {
		new_key.objectid = key.objectid;
		new_key.type = BTRFS_IDENTITY_REMAP_KEY;
		new_key.offset = old_addr - key.objectid;

		btrfs_set_item_key_safe(trans, path, &new_key);
	}

	btrfs_release_path(path);

	/* Create new remap entry. */
	ret = add_remap_item(trans, path, new_addr, length, old_addr);
	if (ret)
		goto end;

	/* Add entry for remainder of identity mapping, if necessary. */
	if (key.objectid + key.offset != old_addr + length) {
		new_key.objectid = old_addr + length;
		new_key.type = BTRFS_IDENTITY_REMAP_KEY;
		new_key.offset = key.objectid + key.offset - old_addr - length;

		ret = btrfs_insert_empty_item(trans, fs_info->remap_root,
					      path, &new_key, 0);
		if (ret)
			goto end;

		btrfs_release_path(path);

		identity_count_delta++;
	}

	/* Add backref. */
	ret = add_remap_backref_item(trans, path, new_addr, length, old_addr);
	if (ret)
		goto end;

	if (identity_count_delta != 0)
		adjust_identity_remap_count(trans, src_bg, identity_count_delta);

end:
	btrfs_release_path(path);

	return ret;
}

static int mark_chunk_remapped(struct btrfs_trans_handle *trans,
			       struct btrfs_path *path, u64 start)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_chunk_map *chunk_map;
	struct btrfs_key key;
	u64 type;
	int ret;
	struct extent_buffer *leaf;
	struct btrfs_chunk *chunk;

	read_lock(&fs_info->mapping_tree_lock);

	chunk_map = btrfs_find_chunk_map_nolock(fs_info, start, 1);
	if (!chunk_map) {
		read_unlock(&fs_info->mapping_tree_lock);
		return -ENOENT;
	}

	chunk_map->type |= BTRFS_BLOCK_GROUP_REMAPPED;
	type = chunk_map->type;

	read_unlock(&fs_info->mapping_tree_lock);

	key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
	key.type = BTRFS_CHUNK_ITEM_KEY;
	key.offset = start;

	ret = btrfs_search_slot(trans, fs_info->chunk_root, &key, path, 0, 1);
	if (ret == 1) {
		ret = -ENOENT;
		goto end;
	} else if (ret < 0)
		goto end;

	leaf = path->nodes[0];

	chunk = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_chunk);
	btrfs_set_chunk_type(leaf, chunk, type);
	btrfs_mark_buffer_dirty(trans, leaf);

	ret = 0;
end:
	btrfs_free_chunk_map(chunk_map);
	btrfs_release_path(path);

	return ret;
}

static int do_remap_reloc_trans(struct btrfs_fs_info *fs_info,
				struct btrfs_block_group *src_bg,
				struct btrfs_path *path, u64 *last_start)
{
	struct btrfs_trans_handle *trans;
	struct btrfs_root *extent_root;
	struct btrfs_key ins;
	struct btrfs_block_group *dest_bg = NULL;
	u64 start = 0, remap_length = 0;
	u64 length, new_addr, min_size;
	int ret;
	const bool is_data = (src_bg->flags & BTRFS_BLOCK_GROUP_DATA);
	bool no_more = false;
	bool made_reservation = false, bg_needs_free_space;
	struct btrfs_space_info *sinfo = src_bg->space_info;

	extent_root = btrfs_extent_root(fs_info, src_bg->start);
	if (unlikely(!extent_root)) {
		btrfs_err(fs_info,
			  "missing extent root for block group at offset %llu",
			  src_bg->start);
		return -EUCLEAN;
	}

	trans = btrfs_start_transaction(extent_root, 0);
	if (IS_ERR(trans))
		return PTR_ERR(trans);

	mutex_lock(&fs_info->remap_mutex);

	ret = find_next_identity_remap(trans, path, src_bg->start + src_bg->length,
				       *last_start, &start, &remap_length);
	if (ret == -ENOENT) {
		no_more = true;
		goto next;
	} else if (ret) {
		mutex_unlock(&fs_info->remap_mutex);
		btrfs_end_transaction(trans);
		return ret;
	}

	/* Try to reserve enough space for block. */
	spin_lock(&sinfo->lock);
	btrfs_space_info_update_bytes_may_use(sinfo, remap_length);
	spin_unlock(&sinfo->lock);

	if (is_data)
		min_size = fs_info->sectorsize;
	else
		min_size = fs_info->nodesize;

	/*
	 * We're using btrfs_reserve_extent() to allocate a contiguous
	 * logical address range, but this will become a remap item rather than
	 * an extent in the extent tree.
	 *
	 * Short allocations are fine: it means that we chop off the beginning
	 * of the identity remap that we're processing, and will tackle the
	 * rest of it the next time round.
	 */
	ret = btrfs_reserve_extent(fs_info->fs_root, remap_length, remap_length,
				   min_size, 0, 0, &ins, is_data, false);
	if (ret) {
		spin_lock(&sinfo->lock);
		btrfs_space_info_update_bytes_may_use(sinfo, -remap_length);
		spin_unlock(&sinfo->lock);

		mutex_unlock(&fs_info->remap_mutex);
		btrfs_end_transaction(trans);
		return ret;
	}

	if (ins.offset < remap_length) {
		spin_lock(&sinfo->lock);
		btrfs_space_info_update_bytes_may_use(sinfo, ins.offset - remap_length);
		spin_unlock(&sinfo->lock);
	}

	made_reservation = true;

	new_addr = ins.objectid;
	length = ins.offset;

	if (!is_data && !IS_ALIGNED(length, fs_info->nodesize)) {
		u64 new_length = ALIGN_DOWN(length, fs_info->nodesize);

		btrfs_free_reserved_extent(fs_info, new_addr + new_length,
					   length - new_length, 0);

		length = new_length;
	}

	dest_bg = btrfs_lookup_block_group(fs_info, new_addr);

	mutex_lock(&dest_bg->free_space_lock);
	bg_needs_free_space = test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE,
				       &dest_bg->runtime_flags);
	mutex_unlock(&dest_bg->free_space_lock);

	if (bg_needs_free_space) {
		ret = btrfs_add_block_group_free_space(trans, dest_bg);
		if (ret) {
			btrfs_abort_transaction(trans, ret);
			goto fail;
		}
	}

	ret = copy_remapped_data(fs_info, start, new_addr, length);
	if (ret) {
		btrfs_abort_transaction(trans, ret);
		goto fail;
	}

	ret = btrfs_remove_from_free_space_tree(trans, new_addr, length);
	if (ret) {
		btrfs_abort_transaction(trans, ret);
		goto fail;
	}

	ret = add_remap_entry(trans, path, src_bg, start, new_addr, length);
	if (ret) {
		btrfs_abort_transaction(trans, ret);
		goto fail;
	}

	adjust_block_group_remap_bytes(trans, dest_bg, length);
	btrfs_free_reserved_bytes(dest_bg, length, 0);

	spin_lock(&sinfo->lock);
	sinfo->bytes_readonly += length;
	spin_unlock(&sinfo->lock);

next:
	if (dest_bg)
		btrfs_put_block_group(dest_bg);

	if (made_reservation)
		btrfs_dec_block_group_reservations(fs_info, new_addr);

	mutex_unlock(&fs_info->remap_mutex);

	if (src_bg->identity_remap_count == 0) {
		bool mark_fully_remapped = false;

		spin_lock(&src_bg->lock);
		if (!test_bit(BLOCK_GROUP_FLAG_FULLY_REMAPPED, &src_bg->runtime_flags)) {
			mark_fully_remapped = true;
			set_bit(BLOCK_GROUP_FLAG_FULLY_REMAPPED, &src_bg->runtime_flags);
		}
		spin_unlock(&src_bg->lock);

		if (mark_fully_remapped)
			btrfs_mark_bg_fully_remapped(src_bg, trans);
	}

	ret = btrfs_end_transaction(trans);
	if (ret)
		return ret;

	if (no_more)
		return 1;

	*last_start = start;

	return 0;

fail:
	if (dest_bg)
		btrfs_put_block_group(dest_bg);

	btrfs_free_reserved_extent(fs_info, new_addr, length, 0);

	mutex_unlock(&fs_info->remap_mutex);
	btrfs_end_transaction(trans);

	return ret;
}

static int do_remap_reloc(struct btrfs_fs_info *fs_info, struct btrfs_path *path,
			  struct btrfs_block_group *bg)
{
	u64 last_start = bg->start;
	int ret;

	while (true) {
		ret = do_remap_reloc_trans(fs_info, bg, path, &last_start);
		if (ret) {
			if (ret == 1)
				ret = 0;
			break;
		}
	}

	return ret;
}

int btrfs_translate_remap(struct btrfs_fs_info *fs_info, u64 *logical, u64 *length)
{
	int ret;
	struct btrfs_key key, found_key;
	struct extent_buffer *leaf;
	struct btrfs_remap_item *remap;
	BTRFS_PATH_AUTO_FREE(path);

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;

	key.objectid = *logical;
	key.type = (u8)-1;
	key.offset = (u64)-1;

	ret = btrfs_search_slot(NULL, fs_info->remap_root, &key, path, 0, 0);
	if (ret < 0)
		return ret;

	leaf = path->nodes[0];
	if (path->slots[0] == 0)
		return -ENOENT;

	path->slots[0]--;

	btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);

	if (found_key.type != BTRFS_REMAP_KEY &&
	    found_key.type != BTRFS_IDENTITY_REMAP_KEY) {
		return -ENOENT;
	}

	if (found_key.objectid > *logical ||
	    found_key.objectid + found_key.offset <= *logical) {
		return -ENOENT;
	}

	if (*logical + *length > found_key.objectid + found_key.offset)
		*length = found_key.objectid + found_key.offset - *logical;

	if (found_key.type == BTRFS_IDENTITY_REMAP_KEY)
		return 0;

	remap = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_remap_item);
	*logical += btrfs_remap_address(leaf, remap) - found_key.objectid;

	return 0;
}

static int start_block_group_remapping(struct btrfs_fs_info *fs_info,
				       struct btrfs_path *path,
				       struct btrfs_block_group *bg)
{
	struct btrfs_trans_handle *trans;
	bool bg_already_dirty = true;
	int ret, ret2;

	ret = btrfs_cache_block_group(bg, true);
	if (ret)
		return ret;

	trans = btrfs_start_transaction(fs_info->remap_root, 0);
	if (IS_ERR(trans))
		return PTR_ERR(trans);

	/* We need to run delayed refs, to make sure FST is up to date. */
	ret = btrfs_run_delayed_refs(trans, U64_MAX);
	if (ret) {
		btrfs_end_transaction(trans);
		return ret;
	}

	mutex_lock(&fs_info->remap_mutex);

	if (bg->flags & BTRFS_BLOCK_GROUP_REMAPPED) {
		ret = 0;
		goto end;
	}

	ret = create_remap_tree_entries(trans, path, bg);
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		goto end;
	}

	spin_lock(&bg->lock);
	bg->flags |= BTRFS_BLOCK_GROUP_REMAPPED;
	spin_unlock(&bg->lock);

	spin_lock(&trans->transaction->dirty_bgs_lock);
	if (list_empty(&bg->dirty_list)) {
		list_add_tail(&bg->dirty_list, &trans->transaction->dirty_bgs);
		bg_already_dirty = false;
		btrfs_get_block_group(bg);
	}
	spin_unlock(&trans->transaction->dirty_bgs_lock);

	/* Modified block groups are accounted for in the delayed_refs_rsv. */
	if (!bg_already_dirty)
		btrfs_inc_delayed_refs_rsv_bg_updates(fs_info);

	ret = mark_chunk_remapped(trans, path, bg->start);
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		goto end;
	}

	ret = btrfs_remove_block_group_free_space(trans, bg);
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		goto end;
	}

	btrfs_remove_free_space_cache(bg);

end:
	mutex_unlock(&fs_info->remap_mutex);

	ret2 = btrfs_end_transaction(trans);
	if (!ret)
		ret = ret2;

	return ret;
}

static int do_nonremap_reloc(struct btrfs_fs_info *fs_info, bool verbose,
			     struct reloc_control *rc)
{
	int ret;

	while (1) {
		enum reloc_stage finishes_stage;

		mutex_lock(&fs_info->cleaner_mutex);
		ret = relocate_block_group(rc);
		mutex_unlock(&fs_info->cleaner_mutex);

		finishes_stage = rc->stage;
		/*
		 * We may have gotten ENOSPC after we already dirtied some
		 * extents.  If writeout happens while we're relocating a
		 * different block group we could end up hitting the
		 * BUG_ON(rc->stage == UPDATE_DATA_PTRS) in
		 * btrfs_reloc_cow_block.  Make sure we write everything out
		 * properly so we don't trip over this problem, and then break
		 * out of the loop if we hit an error.
		 */
		if (rc->stage == MOVE_DATA_EXTENTS && rc->found_file_extent) {
			int wb_ret;

			wb_ret = btrfs_wait_ordered_range(BTRFS_I(rc->data_inode),
							  0, (u64)-1);
			if (wb_ret && ret == 0)
				ret = wb_ret;
			invalidate_mapping_pages(rc->data_inode->i_mapping, 0, -1);
			rc->stage = UPDATE_DATA_PTRS;
		}

		if (ret < 0)
			return ret;

		if (rc->extents_found == 0)
			break;

		if (verbose)
			btrfs_info(fs_info, "found %llu extents, stage: %s",
				   rc->extents_found, stage_to_string(finishes_stage));
	}

	WARN_ON(rc->block_group->pinned > 0);
	WARN_ON(rc->block_group->reserved > 0);
	WARN_ON(rc->block_group->used > 0);

	return 0;
}

/*
 * function to relocate all extents in a block group.
 */
int btrfs_relocate_block_group(struct btrfs_fs_info *fs_info, u64 group_start,
			       bool verbose)
{
	struct btrfs_block_group *bg;
	struct btrfs_root *extent_root = btrfs_extent_root(fs_info, group_start);
	struct reloc_control *rc;
	struct inode *inode;
	struct btrfs_path *path = NULL;
	int ret;
	bool bg_is_ro = false;

	if (unlikely(!extent_root)) {
		btrfs_err(fs_info,
			  "missing extent root for block group at offset %llu",
			  group_start);
		return -EUCLEAN;
	}

	/*
	 * This only gets set if we had a half-deleted snapshot on mount.  We
	 * cannot allow relocation to start while we're still trying to clean up
	 * these pending deletions.
	 */
	ret = wait_on_bit(&fs_info->flags, BTRFS_FS_UNFINISHED_DROPS, TASK_INTERRUPTIBLE);
	if (ret)
		return ret;

	/* We may have been woken up by close_ctree, so bail if we're closing. */
	if (btrfs_fs_closing(fs_info))
		return -EINTR;

	bg = btrfs_lookup_block_group(fs_info, group_start);
	if (!bg)
		return -ENOENT;

	/*
	 * Relocation of a data block group creates ordered extents.  Without
	 * sb_start_write(), we can freeze the filesystem while unfinished
	 * ordered extents are left. Such ordered extents can cause a deadlock
	 * e.g. when syncfs() is waiting for their completion but they can't
	 * finish because they block when joining a transaction, due to the
	 * fact that the freeze locks are being held in write mode.
	 */
	if (bg->flags & BTRFS_BLOCK_GROUP_DATA)
		ASSERT(sb_write_started(fs_info->sb));

	if (btrfs_pinned_by_swapfile(fs_info, bg)) {
		btrfs_put_block_group(bg);
		return -ETXTBSY;
	}

	rc = alloc_reloc_control(fs_info);
	if (!rc) {
		btrfs_put_block_group(bg);
		return -ENOMEM;
	}

	ret = reloc_chunk_start(fs_info);
	if (ret < 0)
		goto out_put_bg;

	rc->extent_root = extent_root;
	rc->block_group = bg;

	ret = btrfs_inc_block_group_ro(rc->block_group, true);
	if (ret)
		goto out;
	bg_is_ro = true;

	path = btrfs_alloc_path();
	if (!path) {
		ret = -ENOMEM;
		goto out;
	}

	inode = lookup_free_space_inode(rc->block_group, path);
	btrfs_release_path(path);

	if (!IS_ERR(inode))
		ret = delete_block_group_cache(rc->block_group, inode, 0);
	else
		ret = PTR_ERR(inode);

	if (ret && ret != -ENOENT)
		goto out;

	if (!btrfs_fs_incompat(fs_info, REMAP_TREE)) {
		rc->data_inode = create_reloc_inode(rc->block_group);
		if (IS_ERR(rc->data_inode)) {
			ret = PTR_ERR(rc->data_inode);
			rc->data_inode = NULL;
			goto out;
		}
	}

	if (verbose)
		describe_relocation(rc->block_group);

	btrfs_wait_block_group_reservations(rc->block_group);
	btrfs_wait_nocow_writers(rc->block_group);
	btrfs_wait_ordered_roots(fs_info, U64_MAX, rc->block_group);

	ret = btrfs_zone_finish(rc->block_group);
	WARN_ON(ret && ret != -EAGAIN);

	if (should_relocate_using_remap_tree(bg)) {
		if (bg->remap_bytes != 0) {
			ret = move_existing_remaps(fs_info, bg, path);
			if (ret)
				goto out;
		}
		ret = start_block_group_remapping(fs_info, path, bg);
		if (ret)
			goto out;

		ret = do_remap_reloc(fs_info, path, rc->block_group);
		if (ret)
			goto out;

		btrfs_delete_unused_bgs(fs_info);
	} else {
		ret = do_nonremap_reloc(fs_info, verbose, rc);
	}

out:
	if (ret && bg_is_ro)
		btrfs_dec_block_group_ro(rc->block_group);
	if (!btrfs_fs_incompat(fs_info, REMAP_TREE))
		iput(rc->data_inode);
	btrfs_free_path(path);
	reloc_chunk_end(fs_info);
out_put_bg:
	btrfs_put_block_group(bg);
	free_reloc_control(rc);
	return ret;
}

static noinline_for_stack int mark_garbage_root(struct btrfs_root *root)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_trans_handle *trans;
	int ret, err;

	trans = btrfs_start_transaction(fs_info->tree_root, 0);
	if (IS_ERR(trans))
		return PTR_ERR(trans);

	memset(&root->root_item.drop_progress, 0,
		sizeof(root->root_item.drop_progress));
	btrfs_set_root_drop_level(&root->root_item, 0);
	btrfs_set_root_refs(&root->root_item, 0);
	ret = btrfs_update_root(trans, fs_info->tree_root,
				&root->root_key, &root->root_item);

	err = btrfs_end_transaction(trans);
	if (err)
		return err;
	return ret;
}

/*
 * recover relocation interrupted by system crash.
 *
 * this function resumes merging reloc trees with corresponding fs trees.
 * this is important for keeping the sharing of tree blocks
 */
int btrfs_recover_relocation(struct btrfs_fs_info *fs_info)
{
	LIST_HEAD(reloc_roots);
	struct btrfs_key key;
	struct btrfs_root *fs_root;
	struct btrfs_root *reloc_root;
	struct btrfs_path *path;
	struct extent_buffer *leaf;
	struct reloc_control *rc = NULL;
	struct btrfs_trans_handle *trans;
	int ret2;
	int ret = 0;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
	path->reada = READA_BACK;

	key.objectid = BTRFS_TREE_RELOC_OBJECTID;
	key.type = BTRFS_ROOT_ITEM_KEY;
	key.offset = (u64)-1;

	while (1) {
		ret = btrfs_search_slot(NULL, fs_info->tree_root, &key,
					path, 0, 0);
		if (ret < 0)
			goto out;
		if (ret > 0) {
			if (path->slots[0] == 0)
				break;
			path->slots[0]--;
		}
		ret = 0;
		leaf = path->nodes[0];
		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
		btrfs_release_path(path);

		if (key.objectid != BTRFS_TREE_RELOC_OBJECTID ||
		    key.type != BTRFS_ROOT_ITEM_KEY)
			break;

		reloc_root = btrfs_read_tree_root(fs_info->tree_root, &key);
		if (IS_ERR(reloc_root)) {
			ret = PTR_ERR(reloc_root);
			goto out;
		}

		set_bit(BTRFS_ROOT_SHAREABLE, &reloc_root->state);
		list_add(&reloc_root->root_list, &reloc_roots);

		if (btrfs_root_refs(&reloc_root->root_item) > 0) {
			fs_root = btrfs_get_fs_root(fs_info,
					reloc_root->root_key.offset, false);
			if (IS_ERR(fs_root)) {
				ret = PTR_ERR(fs_root);
				if (ret != -ENOENT)
					goto out;
				ret = mark_garbage_root(reloc_root);
				if (ret < 0)
					goto out;
				ret = 0;
			} else {
				btrfs_put_root(fs_root);
			}
		}

		if (key.offset == 0)
			break;

		key.offset--;
	}
	btrfs_release_path(path);

	if (list_empty(&reloc_roots))
		goto out;

	rc = alloc_reloc_control(fs_info);
	if (!rc) {
		ret = -ENOMEM;
		goto out;
	}

	rc->extent_root = btrfs_extent_root(fs_info, 0);
	if (unlikely(!rc->extent_root)) {
		btrfs_err(fs_info, "missing extent root for extent at bytenr 0");
		ret = -EUCLEAN;
		goto out;
	}

	ret = reloc_chunk_start(fs_info);
	if (ret < 0)
		goto out_end;

	set_reloc_control(rc);

	trans = btrfs_join_transaction(rc->extent_root);
	if (IS_ERR(trans)) {
		ret = PTR_ERR(trans);
		goto out_unset;
	}

	rc->merge_reloc_tree = true;

	while (!list_empty(&reloc_roots)) {
		reloc_root = list_first_entry(&reloc_roots, struct btrfs_root, root_list);
		list_del(&reloc_root->root_list);

		if (btrfs_root_refs(&reloc_root->root_item) == 0) {
			list_add_tail(&reloc_root->root_list,
				      &rc->reloc_roots);
			continue;
		}

		fs_root = btrfs_get_fs_root(fs_info, reloc_root->root_key.offset,
					    false);
		if (IS_ERR(fs_root)) {
			ret = PTR_ERR(fs_root);
			list_add_tail(&reloc_root->root_list, &reloc_roots);
			btrfs_end_transaction(trans);
			goto out_unset;
		}

		ret = __add_reloc_root(reloc_root);
		ASSERT(ret != -EEXIST);
		if (ret) {
			list_add_tail(&reloc_root->root_list, &reloc_roots);
			btrfs_put_root(fs_root);
			btrfs_end_transaction(trans);
			goto out_unset;
		}
		fs_root->reloc_root = btrfs_grab_root(reloc_root);
		btrfs_put_root(fs_root);
	}

	ret = btrfs_commit_transaction(trans);
	if (ret)
		goto out_unset;

	merge_reloc_roots(rc);

	unset_reloc_control(rc);

	trans = btrfs_join_transaction(rc->extent_root);
	if (IS_ERR(trans)) {
		ret = PTR_ERR(trans);
		goto out_clean;
	}
	ret = btrfs_commit_transaction(trans);
out_clean:
	ret2 = clean_dirty_subvols(rc);
	if (ret2 < 0 && !ret)
		ret = ret2;
out_unset:
	unset_reloc_control(rc);
	reloc_chunk_end(fs_info);
out_end:
	free_reloc_control(rc);
out:
	free_reloc_roots(&reloc_roots);

	btrfs_free_path(path);

	if (ret == 0 && !btrfs_fs_incompat(fs_info, REMAP_TREE)) {
		/* cleanup orphan inode in data relocation tree */
		fs_root = btrfs_grab_root(fs_info->data_reloc_root);
		ASSERT(fs_root);
		ret = btrfs_orphan_cleanup(fs_root);
		btrfs_put_root(fs_root);
	}
	return ret;
}

/*
 * helper to add ordered checksum for data relocation.
 *
 * cloning checksum properly handles the nodatasum extents.
 * it also saves CPU time to re-calculate the checksum.
 */
int btrfs_reloc_clone_csums(struct btrfs_ordered_extent *ordered)
{
	struct btrfs_inode *inode = ordered->inode;
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
	u64 disk_bytenr = ordered->file_offset + inode->reloc_block_group_start;
	struct btrfs_root *csum_root = btrfs_csum_root(fs_info, disk_bytenr);
	LIST_HEAD(list);
	int ret;

	if (unlikely(!csum_root)) {
		btrfs_mark_ordered_extent_error(ordered);
		btrfs_err(fs_info,
			  "missing csum root for extent at bytenr %llu",
			  disk_bytenr);
		return -EUCLEAN;
	}

	ret = btrfs_lookup_csums_list(csum_root, disk_bytenr,
				      disk_bytenr + ordered->num_bytes - 1,
				      &list, false);
	if (ret < 0) {
		btrfs_mark_ordered_extent_error(ordered);
		return ret;
	}

	while (!list_empty(&list)) {
		struct btrfs_ordered_sum *sums =
			list_first_entry(&list, struct btrfs_ordered_sum, list);

		list_del_init(&sums->list);

		/*
		 * We need to offset the new_bytenr based on where the csum is.
		 * We need to do this because we will read in entire prealloc
		 * extents but we may have written to say the middle of the
		 * prealloc extent, so we need to make sure the csum goes with
		 * the right disk offset.
		 *
		 * We can do this because the data reloc inode refers strictly
		 * to the on disk bytes, so we don't have to worry about
		 * disk_len vs real len like with real inodes since it's all
		 * disk length.
		 */
		sums->logical = ordered->disk_bytenr + sums->logical - disk_bytenr;
		btrfs_add_ordered_sum(ordered, sums);
	}

	return 0;
}

int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
			  struct btrfs_root *root,
			  const struct extent_buffer *buf,
			  struct extent_buffer *cow)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct reloc_control *rc;
	struct btrfs_backref_node *node;
	int first_cow = 0;
	int level;
	int ret = 0;

	rc = fs_info->reloc_ctl;
	if (!rc)
		return 0;

	BUG_ON(rc->stage == UPDATE_DATA_PTRS && btrfs_is_data_reloc_root(root));

	level = btrfs_header_level(buf);
	if (btrfs_header_generation(buf) <=
	    btrfs_root_last_snapshot(&root->root_item))
		first_cow = 1;

	if (btrfs_root_id(root) == BTRFS_TREE_RELOC_OBJECTID && rc->create_reloc_tree) {
		WARN_ON(!first_cow && level == 0);

		node = rc->backref_cache.path[level];

		/*
		 * If node->bytenr != buf->start and node->new_bytenr !=
		 * buf->start then we've got the wrong backref node for what we
		 * expected to see here and the cache is incorrect.
		 */
		if (unlikely(node->bytenr != buf->start && node->new_bytenr != buf->start)) {
			btrfs_err(fs_info,
"bytenr %llu was found but our backref cache was expecting %llu or %llu",
				  buf->start, node->bytenr, node->new_bytenr);
			return -EUCLEAN;
		}

		btrfs_backref_drop_node_buffer(node);
		refcount_inc(&cow->refs);
		node->eb = cow;
		node->new_bytenr = cow->start;

		if (!node->pending) {
			list_move_tail(&node->list,
				       &rc->backref_cache.pending[level]);
			node->pending = 1;
		}

		if (first_cow)
			mark_block_processed(rc, node);

		if (first_cow && level > 0)
			rc->nodes_relocated += buf->len;
	}

	if (level == 0 && first_cow && rc->stage == UPDATE_DATA_PTRS)
		ret = replace_file_extents(trans, rc, root, cow);
	return ret;
}

/*
 * called before creating snapshot. it calculates metadata reservation
 * required for relocating tree blocks in the snapshot
 */
void btrfs_reloc_pre_snapshot(struct btrfs_pending_snapshot *pending,
			      u64 *bytes_to_reserve)
{
	struct btrfs_root *root = pending->root;
	struct reloc_control *rc = root->fs_info->reloc_ctl;

	if (!rc || !have_reloc_root(root))
		return;

	if (!rc->merge_reloc_tree)
		return;

	root = root->reloc_root;
	BUG_ON(btrfs_root_refs(&root->root_item) == 0);
	/*
	 * relocation is in the stage of merging trees. the space
	 * used by merging a reloc tree is twice the size of
	 * relocated tree nodes in the worst case. half for cowing
	 * the reloc tree, half for cowing the fs tree. the space
	 * used by cowing the reloc tree will be freed after the
	 * tree is dropped. if we create snapshot, cowing the fs
	 * tree may use more space than it frees. so we need
	 * reserve extra space.
	 */
	*bytes_to_reserve += rc->nodes_relocated;
}

/*
 * called after snapshot is created. migrate block reservation
 * and create reloc root for the newly created snapshot
 *
 * This is similar to btrfs_init_reloc_root(), we come out of here with two
 * references held on the reloc_root, one for root->reloc_root and one for
 * rc->reloc_roots.
 */
int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
			       struct btrfs_pending_snapshot *pending)
{
	struct btrfs_root *root = pending->root;
	struct btrfs_root *reloc_root;
	struct btrfs_root *new_root;
	struct reloc_control *rc = root->fs_info->reloc_ctl;
	int ret;

	if (!rc || !have_reloc_root(root))
		return 0;

	rc = root->fs_info->reloc_ctl;
	rc->merging_rsv_size += rc->nodes_relocated;

	if (rc->merge_reloc_tree) {
		ret = btrfs_block_rsv_migrate(&pending->block_rsv,
					      rc->block_rsv,
					      rc->nodes_relocated, true);
		if (ret)
			return ret;
	}

	new_root = pending->snap;
	reloc_root = create_reloc_root(trans, root->reloc_root, btrfs_root_id(new_root));
	if (IS_ERR(reloc_root))
		return PTR_ERR(reloc_root);

	ret = __add_reloc_root(reloc_root);
	ASSERT(ret != -EEXIST);
	if (ret) {
		/* Pairs with create_reloc_root */
		btrfs_put_root(reloc_root);
		return ret;
	}
	new_root->reloc_root = btrfs_grab_root(reloc_root);
	return 0;
}

/*
 * Get the current bytenr for the block group which is being relocated.
 *
 * Return U64_MAX if no running relocation.
 */
u64 btrfs_get_reloc_bg_bytenr(const struct btrfs_fs_info *fs_info)
{
	u64 logical = U64_MAX;

	lockdep_assert_held(&fs_info->reloc_mutex);

	if (fs_info->reloc_ctl && fs_info->reloc_ctl->block_group)
		logical = fs_info->reloc_ctl->block_group->start;
	return logical;
}

static int insert_remap_item(struct btrfs_trans_handle *trans, struct btrfs_path *path,
			     u64 old_addr, u64 length, u64 new_addr)
{
	int ret;
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_key key;
	struct btrfs_remap_item remap = { 0 };

	if (old_addr == new_addr) {
		/* Add new identity remap item. */
		key.objectid = old_addr;
		key.type = BTRFS_IDENTITY_REMAP_KEY;
		key.offset = length;

		ret = btrfs_insert_empty_item(trans, fs_info->remap_root, path,
					      &key, 0);
		if (ret)
			return ret;
	} else {
		/* Add new remap item. */
		key.objectid = old_addr;
		key.type = BTRFS_REMAP_KEY;
		key.offset = length;

		ret = btrfs_insert_empty_item(trans, fs_info->remap_root,
					      path, &key, sizeof(struct btrfs_remap_item));
		if (ret)
			return ret;

		btrfs_set_stack_remap_address(&remap, new_addr);

		write_extent_buffer(path->nodes[0], &remap,
			btrfs_item_ptr_offset(path->nodes[0], path->slots[0]),
			sizeof(struct btrfs_remap_item));

		btrfs_release_path(path);

		/* Add new backref item. */
		key.objectid = new_addr;
		key.type = BTRFS_REMAP_BACKREF_KEY;
		key.offset = length;

		ret = btrfs_insert_empty_item(trans, fs_info->remap_root,
					      path, &key,
					      sizeof(struct btrfs_remap_item));
		if (ret)
			return ret;

		btrfs_set_stack_remap_address(&remap, old_addr);

		write_extent_buffer(path->nodes[0], &remap,
			btrfs_item_ptr_offset(path->nodes[0], path->slots[0]),
			sizeof(struct btrfs_remap_item));
	}

	btrfs_release_path(path);

	return 0;
}

/*
 * Punch a hole in the remap item or identity remap item pointed to by path,
 * for the range [hole_start, hole_start + hole_length).
 */
static int remove_range_from_remap_tree(struct btrfs_trans_handle *trans,
					struct btrfs_path *path,
					struct btrfs_block_group *bg,
					u64 hole_start, u64 hole_length)
{
	int ret;
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct extent_buffer *leaf = path->nodes[0];
	struct btrfs_key key;
	u64 hole_end, new_addr, remap_start, remap_length, remap_end;
	u64 overlap_length;
	bool is_identity_remap;
	int identity_count_delta = 0;

	hole_end = hole_start + hole_length;

	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);

	is_identity_remap = (key.type == BTRFS_IDENTITY_REMAP_KEY);

	remap_start = key.objectid;
	remap_length = key.offset;
	remap_end = remap_start + remap_length;

	if (is_identity_remap) {
		new_addr = remap_start;
	} else {
		struct btrfs_remap_item *remap_ptr;

		remap_ptr = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_remap_item);
		new_addr = btrfs_remap_address(leaf, remap_ptr);
	}

	/* Delete old item. */
	ret = btrfs_del_item(trans, fs_info->remap_root, path);
	btrfs_release_path(path);
	if (ret)
		return ret;

	if (is_identity_remap) {
		identity_count_delta = -1;
	} else {
		/* Remove backref. */
		key.objectid = new_addr;
		key.type = BTRFS_REMAP_BACKREF_KEY;
		key.offset = remap_length;

		ret = btrfs_search_slot(trans, fs_info->remap_root, &key, path, -1, 1);
		if (ret) {
			if (ret == 1) {
				btrfs_release_path(path);
				ret = -ENOENT;
			}
			return ret;
		}

		ret = btrfs_del_item(trans, fs_info->remap_root, path);

		btrfs_release_path(path);

		if (ret)
			return ret;
	}

	/* If hole_start > remap_start, re-add the start of the remap item. */
	if (hole_start > remap_start) {
		ret = insert_remap_item(trans, path, remap_start,
					hole_start - remap_start, new_addr);
		if (ret)
			return ret;

		if (is_identity_remap)
			identity_count_delta++;
	}

	/* If hole_end < remap_end, re-add the end of the remap item. */
	if (hole_end < remap_end) {
		ret = insert_remap_item(trans, path, hole_end,
					remap_end - hole_end,
					hole_end - remap_start + new_addr);
		if (ret)
			return ret;

		if (is_identity_remap)
			identity_count_delta++;
	}

	if (identity_count_delta != 0)
		adjust_identity_remap_count(trans, bg, identity_count_delta);

	overlap_length = min_t(u64, hole_end, remap_end) -
			 max_t(u64, hole_start, remap_start);

	if (!is_identity_remap) {
		struct btrfs_block_group *dest_bg;

		dest_bg = btrfs_lookup_block_group(fs_info, new_addr);
		if (unlikely(!dest_bg))
			return -EUCLEAN;

		adjust_block_group_remap_bytes(trans, dest_bg, -overlap_length);
		btrfs_put_block_group(dest_bg);
		ret = btrfs_add_to_free_space_tree(trans,
						   hole_start - remap_start + new_addr,
						   overlap_length);
		if (ret)
			return ret;
	}

	ret = overlap_length;

	return ret;
}

/*
 * Return 1 if remove_range_from_remap_tree() has been called successfully,
 * 0 if block group wasn't remapped, and a negative number on error.
 */
int btrfs_remove_extent_from_remap_tree(struct btrfs_trans_handle *trans,
					struct btrfs_path *path,
					u64 bytenr, u64 num_bytes)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_key key, found_key;
	struct extent_buffer *leaf;
	struct btrfs_block_group *bg;
	int ret, length;

	if (!(btrfs_super_incompat_flags(fs_info->super_copy) &
	      BTRFS_FEATURE_INCOMPAT_REMAP_TREE))
		return 0;

	bg = btrfs_lookup_block_group(fs_info, bytenr);
	if (!bg)
		return 0;

	mutex_lock(&fs_info->remap_mutex);

	if (!(bg->flags & BTRFS_BLOCK_GROUP_REMAPPED)) {
		mutex_unlock(&fs_info->remap_mutex);
		btrfs_put_block_group(bg);
		return 0;
	}

	do {
		key.objectid = bytenr;
		key.type = (u8)-1;
		key.offset = (u64)-1;

		ret = btrfs_search_slot(trans, fs_info->remap_root, &key, path, -1, 1);
		if (ret < 0)
			goto end;

		leaf = path->nodes[0];
		if (path->slots[0] == 0) {
			ret = -ENOENT;
			goto end;
		}

		path->slots[0]--;

		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);

		if (found_key.type != BTRFS_IDENTITY_REMAP_KEY &&
		    found_key.type != BTRFS_REMAP_KEY) {
			ret = -ENOENT;
			goto end;
		}

		if (bytenr < found_key.objectid ||
		    bytenr >= found_key.objectid + found_key.offset) {
			ret = -ENOENT;
			goto end;
		}

		length = remove_range_from_remap_tree(trans, path, bg, bytenr, num_bytes);
		if (length < 0) {
			ret = length;
			goto end;
		}

		bytenr += length;
		num_bytes -= length;
	} while (num_bytes > 0);

	ret = 1;

end:
	mutex_unlock(&fs_info->remap_mutex);

	btrfs_put_block_group(bg);
	btrfs_release_path(path);

	return ret;
}
