// SPDX-License-Identifier: GPL-2.0

#include "messages.h"
#include "tree-mod-log.h"
#include "disk-io.h"
#include "fs.h"
#include "accessors.h"
#include "tree-checker.h"

struct tree_mod_root {
	u64 logical;
	u8 level;
};

struct tree_mod_elem {
	struct rb_node node;
	u64 logical;
	u64 seq;
	enum btrfs_mod_log_op op;

	/*
	 * This is used for BTRFS_MOD_LOG_KEY_* and BTRFS_MOD_LOG_MOVE_KEYS
	 * operations.
	 */
	int slot;

	/* This is used for BTRFS_MOD_LOG_KEY* and BTRFS_MOD_LOG_ROOT_REPLACE. */
	u64 generation;

	/* Those are used for op == BTRFS_MOD_LOG_KEY_{REPLACE,REMOVE}. */
	struct btrfs_disk_key key;
	u64 blockptr;

	/* This is used for op == BTRFS_MOD_LOG_MOVE_KEYS. */
	struct {
		int dst_slot;
		int nr_items;
	} move;

	/* This is used for op == BTRFS_MOD_LOG_ROOT_REPLACE. */
	struct tree_mod_root old_root;
};

/*
 * Pull a new tree mod seq number for our operation.
 */
static u64 btrfs_inc_tree_mod_seq(struct btrfs_fs_info *fs_info)
{
	return atomic64_inc_return(&fs_info->tree_mod_seq);
}

/*
 * This adds a new blocker to the tree mod log's blocker list if the @elem
 * passed does not already have a sequence number set. So when a caller expects
 * to record tree modifications, it should ensure to set elem->seq to zero
 * before calling btrfs_get_tree_mod_seq.
 * Returns a fresh, unused tree log modification sequence number, even if no new
 * blocker was added.
 */
u64 btrfs_get_tree_mod_seq(struct btrfs_fs_info *fs_info,
			   struct btrfs_seq_list *elem)
{
	write_lock(&fs_info->tree_mod_log_lock);
	if (!elem->seq) {
		elem->seq = btrfs_inc_tree_mod_seq(fs_info);
		list_add_tail(&elem->list, &fs_info->tree_mod_seq_list);
		set_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags);
	}
	write_unlock(&fs_info->tree_mod_log_lock);

	return elem->seq;
}

void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
			    struct btrfs_seq_list *elem)
{
	struct rb_root *tm_root;
	struct rb_node *node;
	struct rb_node *next;
	struct tree_mod_elem *tm;
	u64 min_seq = BTRFS_SEQ_LAST;
	u64 seq_putting = elem->seq;

	if (!seq_putting)
		return;

	write_lock(&fs_info->tree_mod_log_lock);
	list_del(&elem->list);
	elem->seq = 0;

	if (list_empty(&fs_info->tree_mod_seq_list)) {
		clear_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags);
	} else {
		struct btrfs_seq_list *first;

		first = list_first_entry(&fs_info->tree_mod_seq_list,
					 struct btrfs_seq_list, list);
		if (seq_putting > first->seq) {
			/*
			 * Blocker with lower sequence number exists, we cannot
			 * remove anything from the log.
			 */
			write_unlock(&fs_info->tree_mod_log_lock);
			return;
		}
		min_seq = first->seq;
	}

	/*
	 * Anything that's lower than the lowest existing (read: blocked)
	 * sequence number can be removed from the tree.
	 */
	tm_root = &fs_info->tree_mod_log;
	for (node = rb_first(tm_root); node; node = next) {
		next = rb_next(node);
		tm = rb_entry(node, struct tree_mod_elem, node);
		if (tm->seq >= min_seq)
			continue;
		rb_erase(node, tm_root);
		kfree(tm);
	}
	write_unlock(&fs_info->tree_mod_log_lock);
}

/*
 * Key order of the log:
 *       node/leaf start address -> sequence
 *
 * The 'start address' is the logical address of the *new* root node for root
 * replace operations, or the logical address of the affected block for all
 * other operations.
 */
static noinline int tree_mod_log_insert(struct btrfs_fs_info *fs_info,
					struct tree_mod_elem *tm)
{
	struct rb_root *tm_root;
	struct rb_node **new;
	struct rb_node *parent = NULL;
	struct tree_mod_elem *cur;

	lockdep_assert_held_write(&fs_info->tree_mod_log_lock);

	tm->seq = btrfs_inc_tree_mod_seq(fs_info);

	tm_root = &fs_info->tree_mod_log;
	new = &tm_root->rb_node;
	while (*new) {
		cur = rb_entry(*new, struct tree_mod_elem, node);
		parent = *new;
		if (cur->logical < tm->logical)
			new = &((*new)->rb_left);
		else if (cur->logical > tm->logical)
			new = &((*new)->rb_right);
		else if (cur->seq < tm->seq)
			new = &((*new)->rb_left);
		else if (cur->seq > tm->seq)
			new = &((*new)->rb_right);
		else
			return -EEXIST;
	}

	rb_link_node(&tm->node, parent, new);
	rb_insert_color(&tm->node, tm_root);
	return 0;
}

/*
 * Determines if logging can be omitted. Returns true if it can. Otherwise, it
 * returns false with the tree_mod_log_lock acquired. The caller must hold
 * this until all tree mod log insertions are recorded in the rb tree and then
 * write unlock fs_info::tree_mod_log_lock.
 */
static bool tree_mod_dont_log(struct btrfs_fs_info *fs_info, const struct extent_buffer *eb)
{
	if (!test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
		return true;
	if (eb && btrfs_header_level(eb) == 0)
		return true;

	write_lock(&fs_info->tree_mod_log_lock);
	if (list_empty(&(fs_info)->tree_mod_seq_list)) {
		write_unlock(&fs_info->tree_mod_log_lock);
		return true;
	}

	return false;
}

/* Similar to tree_mod_dont_log, but doesn't acquire any locks. */
static bool tree_mod_need_log(const struct btrfs_fs_info *fs_info,
			      const struct extent_buffer *eb)
{
	if (!test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
		return false;
	if (eb && btrfs_header_level(eb) == 0)
		return false;

	return true;
}

static struct tree_mod_elem *alloc_tree_mod_elem(const struct extent_buffer *eb,
						 int slot,
						 enum btrfs_mod_log_op op)
{
	struct tree_mod_elem *tm;

	tm = kzalloc(sizeof(*tm), GFP_NOFS);
	if (!tm)
		return NULL;

	tm->logical = eb->start;
	if (op != BTRFS_MOD_LOG_KEY_ADD) {
		btrfs_node_key(eb, &tm->key, slot);
		tm->blockptr = btrfs_node_blockptr(eb, slot);
	}
	tm->op = op;
	tm->slot = slot;
	tm->generation = btrfs_node_ptr_generation(eb, slot);
	RB_CLEAR_NODE(&tm->node);

	return tm;
}

int btrfs_tree_mod_log_insert_key(const struct extent_buffer *eb, int slot,
				  enum btrfs_mod_log_op op)
{
	struct tree_mod_elem *tm;
	int ret = 0;

	if (!tree_mod_need_log(eb->fs_info, eb))
		return 0;

	tm = alloc_tree_mod_elem(eb, slot, op);
	if (!tm)
		ret = -ENOMEM;

	if (tree_mod_dont_log(eb->fs_info, eb)) {
		kfree(tm);
		/*
		 * Don't error if we failed to allocate memory because we don't
		 * need to log.
		 */
		return 0;
	} else if (ret != 0) {
		/*
		 * We previously failed to allocate memory and we need to log,
		 * so we have to fail.
		 */
		goto out_unlock;
	}

	ret = tree_mod_log_insert(eb->fs_info, tm);
out_unlock:
	write_unlock(&eb->fs_info->tree_mod_log_lock);
	if (ret)
		kfree(tm);

	return ret;
}

static struct tree_mod_elem *tree_mod_log_alloc_move(const struct extent_buffer *eb,
						     int dst_slot, int src_slot,
						     int nr_items)
{
	struct tree_mod_elem *tm;

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

	tm->logical = eb->start;
	tm->slot = src_slot;
	tm->move.dst_slot = dst_slot;
	tm->move.nr_items = nr_items;
	tm->op = BTRFS_MOD_LOG_MOVE_KEYS;
	RB_CLEAR_NODE(&tm->node);

	return tm;
}

int btrfs_tree_mod_log_insert_move(const struct extent_buffer *eb,
				   int dst_slot, int src_slot,
				   int nr_items)
{
	struct tree_mod_elem *tm = NULL;
	struct tree_mod_elem **tm_list = NULL;
	int ret = 0;
	int i;
	bool locked = false;

	if (!tree_mod_need_log(eb->fs_info, eb))
		return 0;

	tm_list = kcalloc(nr_items, sizeof(struct tree_mod_elem *), GFP_NOFS);
	if (!tm_list) {
		ret = -ENOMEM;
		goto lock;
	}

	tm = tree_mod_log_alloc_move(eb, dst_slot, src_slot, nr_items);
	if (IS_ERR(tm)) {
		ret = PTR_ERR(tm);
		tm = NULL;
		goto lock;
	}

	for (i = 0; i + dst_slot < src_slot && i < nr_items; i++) {
		tm_list[i] = alloc_tree_mod_elem(eb, i + dst_slot,
				BTRFS_MOD_LOG_KEY_REMOVE_WHILE_MOVING);
		if (!tm_list[i]) {
			ret = -ENOMEM;
			goto lock;
		}
	}

lock:
	if (tree_mod_dont_log(eb->fs_info, eb)) {
		/*
		 * Don't error if we failed to allocate memory because we don't
		 * need to log.
		 */
		ret = 0;
		goto free_tms;
	}
	locked = true;

	/*
	 * We previously failed to allocate memory and we need to log, so we
	 * have to fail.
	 */
	if (ret != 0)
		goto free_tms;

	/*
	 * When we override something during the move, we log these removals.
	 * This can only happen when we move towards the beginning of the
	 * buffer, i.e. dst_slot < src_slot.
	 */
	for (i = 0; i + dst_slot < src_slot && i < nr_items; i++) {
		ret = tree_mod_log_insert(eb->fs_info, tm_list[i]);
		if (ret)
			goto free_tms;
	}

	ret = tree_mod_log_insert(eb->fs_info, tm);
	if (ret)
		goto free_tms;
	write_unlock(&eb->fs_info->tree_mod_log_lock);
	kfree(tm_list);

	return 0;

free_tms:
	if (tm_list) {
		for (i = 0; i < nr_items; i++) {
			if (tm_list[i] && !RB_EMPTY_NODE(&tm_list[i]->node))
				rb_erase(&tm_list[i]->node, &eb->fs_info->tree_mod_log);
			kfree(tm_list[i]);
		}
	}
	if (locked)
		write_unlock(&eb->fs_info->tree_mod_log_lock);
	kfree(tm_list);
	kfree(tm);

	return ret;
}

static int tree_mod_log_free_eb(struct btrfs_fs_info *fs_info,
				struct tree_mod_elem **tm_list,
				int nritems)
{
	int i, j;
	int ret;

	for (i = nritems - 1; i >= 0; i--) {
		ret = tree_mod_log_insert(fs_info, tm_list[i]);
		if (ret) {
			for (j = nritems - 1; j > i; j--)
				rb_erase(&tm_list[j]->node,
					 &fs_info->tree_mod_log);
			return ret;
		}
	}

	return 0;
}

int btrfs_tree_mod_log_insert_root(struct extent_buffer *old_root,
				   struct extent_buffer *new_root,
				   bool log_removal)
{
	struct btrfs_fs_info *fs_info = old_root->fs_info;
	struct tree_mod_elem *tm = NULL;
	struct tree_mod_elem **tm_list = NULL;
	int nritems = 0;
	int ret = 0;
	int i;

	if (!tree_mod_need_log(fs_info, NULL))
		return 0;

	if (log_removal && btrfs_header_level(old_root) > 0) {
		nritems = btrfs_header_nritems(old_root);
		tm_list = kcalloc(nritems, sizeof(struct tree_mod_elem *),
				  GFP_NOFS);
		if (!tm_list) {
			ret = -ENOMEM;
			goto lock;
		}
		for (i = 0; i < nritems; i++) {
			tm_list[i] = alloc_tree_mod_elem(old_root, i,
			    BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING);
			if (!tm_list[i]) {
				ret = -ENOMEM;
				goto lock;
			}
		}
	}

	tm = kzalloc(sizeof(*tm), GFP_NOFS);
	if (!tm) {
		ret = -ENOMEM;
		goto lock;
	}

	tm->logical = new_root->start;
	tm->old_root.logical = old_root->start;
	tm->old_root.level = btrfs_header_level(old_root);
	tm->generation = btrfs_header_generation(old_root);
	tm->op = BTRFS_MOD_LOG_ROOT_REPLACE;

lock:
	if (tree_mod_dont_log(fs_info, NULL)) {
		/*
		 * Don't error if we failed to allocate memory because we don't
		 * need to log.
		 */
		ret = 0;
		goto free_tms;
	} else if (ret != 0) {
		/*
		 * We previously failed to allocate memory and we need to log,
		 * so we have to fail.
		 */
		goto out_unlock;
	}

	if (tm_list)
		ret = tree_mod_log_free_eb(fs_info, tm_list, nritems);
	if (!ret)
		ret = tree_mod_log_insert(fs_info, tm);

out_unlock:
	write_unlock(&fs_info->tree_mod_log_lock);
	if (ret)
		goto free_tms;
	kfree(tm_list);

	return ret;

free_tms:
	if (tm_list) {
		for (i = 0; i < nritems; i++)
			kfree(tm_list[i]);
		kfree(tm_list);
	}
	kfree(tm);

	return ret;
}

static struct tree_mod_elem *__tree_mod_log_search(struct btrfs_fs_info *fs_info,
						   u64 start, u64 min_seq,
						   bool smallest)
{
	struct rb_root *tm_root;
	struct rb_node *node;
	struct tree_mod_elem *cur = NULL;
	struct tree_mod_elem *found = NULL;

	read_lock(&fs_info->tree_mod_log_lock);
	tm_root = &fs_info->tree_mod_log;
	node = tm_root->rb_node;
	while (node) {
		cur = rb_entry(node, struct tree_mod_elem, node);
		if (cur->logical < start) {
			node = node->rb_left;
		} else if (cur->logical > start) {
			node = node->rb_right;
		} else if (cur->seq < min_seq) {
			node = node->rb_left;
		} else if (!smallest) {
			/* We want the node with the highest seq */
			if (found)
				BUG_ON(found->seq > cur->seq);
			found = cur;
			node = node->rb_left;
		} else if (cur->seq > min_seq) {
			/* We want the node with the smallest seq */
			if (found)
				BUG_ON(found->seq < cur->seq);
			found = cur;
			node = node->rb_right;
		} else {
			found = cur;
			break;
		}
	}
	read_unlock(&fs_info->tree_mod_log_lock);

	return found;
}

/*
 * This returns the element from the log with the smallest time sequence
 * value that's in the log (the oldest log item). Any element with a time
 * sequence lower than min_seq will be ignored.
 */
static struct tree_mod_elem *tree_mod_log_search_oldest(struct btrfs_fs_info *fs_info,
							u64 start, u64 min_seq)
{
	return __tree_mod_log_search(fs_info, start, min_seq, true);
}

/*
 * This returns the element from the log with the largest time sequence
 * value that's in the log (the most recent log item). Any element with
 * a time sequence lower than min_seq will be ignored.
 */
static struct tree_mod_elem *tree_mod_log_search(struct btrfs_fs_info *fs_info,
						 u64 start, u64 min_seq)
{
	return __tree_mod_log_search(fs_info, start, min_seq, false);
}

int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst,
			       const struct extent_buffer *src,
			       unsigned long dst_offset,
			       unsigned long src_offset,
			       int nr_items)
{
	struct btrfs_fs_info *fs_info = dst->fs_info;
	int ret = 0;
	struct tree_mod_elem **tm_list = NULL;
	struct tree_mod_elem **tm_list_add = NULL;
	struct tree_mod_elem **tm_list_rem = NULL;
	int i;
	bool locked = false;
	struct tree_mod_elem *dst_move_tm = NULL;
	struct tree_mod_elem *src_move_tm = NULL;
	u32 dst_move_nr_items = btrfs_header_nritems(dst) - dst_offset;
	u32 src_move_nr_items = btrfs_header_nritems(src) - (src_offset + nr_items);

	if (!tree_mod_need_log(fs_info, NULL))
		return 0;

	if (btrfs_header_level(dst) == 0 && btrfs_header_level(src) == 0)
		return 0;

	tm_list = kcalloc(nr_items * 2, sizeof(struct tree_mod_elem *),
			  GFP_NOFS);
	if (!tm_list) {
		ret = -ENOMEM;
		goto lock;
	}

	if (dst_move_nr_items) {
		dst_move_tm = tree_mod_log_alloc_move(dst, dst_offset + nr_items,
						      dst_offset, dst_move_nr_items);
		if (IS_ERR(dst_move_tm)) {
			ret = PTR_ERR(dst_move_tm);
			dst_move_tm = NULL;
			goto lock;
		}
	}
	if (src_move_nr_items) {
		src_move_tm = tree_mod_log_alloc_move(src, src_offset,
						      src_offset + nr_items,
						      src_move_nr_items);
		if (IS_ERR(src_move_tm)) {
			ret = PTR_ERR(src_move_tm);
			src_move_tm = NULL;
			goto lock;
		}
	}

	tm_list_add = tm_list;
	tm_list_rem = tm_list + nr_items;
	for (i = 0; i < nr_items; i++) {
		tm_list_rem[i] = alloc_tree_mod_elem(src, i + src_offset,
						     BTRFS_MOD_LOG_KEY_REMOVE);
		if (!tm_list_rem[i]) {
			ret = -ENOMEM;
			goto lock;
		}

		tm_list_add[i] = alloc_tree_mod_elem(dst, i + dst_offset,
						     BTRFS_MOD_LOG_KEY_ADD);
		if (!tm_list_add[i]) {
			ret = -ENOMEM;
			goto lock;
		}
	}

lock:
	if (tree_mod_dont_log(fs_info, NULL)) {
		/*
		 * Don't error if we failed to allocate memory because we don't
		 * need to log.
		 */
		ret = 0;
		goto free_tms;
	}
	locked = true;

	/*
	 * We previously failed to allocate memory and we need to log, so we
	 * have to fail.
	 */
	if (ret != 0)
		goto free_tms;

	if (dst_move_tm) {
		ret = tree_mod_log_insert(fs_info, dst_move_tm);
		if (ret)
			goto free_tms;
	}
	for (i = 0; i < nr_items; i++) {
		ret = tree_mod_log_insert(fs_info, tm_list_rem[i]);
		if (ret)
			goto free_tms;
		ret = tree_mod_log_insert(fs_info, tm_list_add[i]);
		if (ret)
			goto free_tms;
	}
	if (src_move_tm) {
		ret = tree_mod_log_insert(fs_info, src_move_tm);
		if (ret)
			goto free_tms;
	}

	write_unlock(&fs_info->tree_mod_log_lock);
	kfree(tm_list);

	return 0;

free_tms:
	if (dst_move_tm && !RB_EMPTY_NODE(&dst_move_tm->node))
		rb_erase(&dst_move_tm->node, &fs_info->tree_mod_log);
	kfree(dst_move_tm);
	if (src_move_tm && !RB_EMPTY_NODE(&src_move_tm->node))
		rb_erase(&src_move_tm->node, &fs_info->tree_mod_log);
	kfree(src_move_tm);
	if (tm_list) {
		for (i = 0; i < nr_items * 2; i++) {
			if (tm_list[i] && !RB_EMPTY_NODE(&tm_list[i]->node))
				rb_erase(&tm_list[i]->node, &fs_info->tree_mod_log);
			kfree(tm_list[i]);
		}
	}
	if (locked)
		write_unlock(&fs_info->tree_mod_log_lock);
	kfree(tm_list);

	return ret;
}

int btrfs_tree_mod_log_free_eb(struct extent_buffer *eb)
{
	struct tree_mod_elem **tm_list = NULL;
	int nritems = 0;
	int i;
	int ret = 0;

	if (!tree_mod_need_log(eb->fs_info, eb))
		return 0;

	nritems = btrfs_header_nritems(eb);
	tm_list = kcalloc(nritems, sizeof(struct tree_mod_elem *), GFP_NOFS);
	if (!tm_list) {
		ret = -ENOMEM;
		goto lock;
	}

	for (i = 0; i < nritems; i++) {
		tm_list[i] = alloc_tree_mod_elem(eb, i,
				    BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING);
		if (!tm_list[i]) {
			ret = -ENOMEM;
			goto lock;
		}
	}

lock:
	if (tree_mod_dont_log(eb->fs_info, eb)) {
		/*
		 * Don't error if we failed to allocate memory because we don't
		 * need to log.
		 */
		ret = 0;
		goto free_tms;
	} else if (ret != 0) {
		/*
		 * We previously failed to allocate memory and we need to log,
		 * so we have to fail.
		 */
		goto out_unlock;
	}

	ret = tree_mod_log_free_eb(eb->fs_info, tm_list, nritems);
out_unlock:
	write_unlock(&eb->fs_info->tree_mod_log_lock);
	if (ret)
		goto free_tms;
	kfree(tm_list);

	return 0;

free_tms:
	if (tm_list) {
		for (i = 0; i < nritems; i++)
			kfree(tm_list[i]);
		kfree(tm_list);
	}

	return ret;
}

/*
 * Returns the logical address of the oldest predecessor of the given root.
 * Entries older than time_seq are ignored.
 */
static struct tree_mod_elem *tree_mod_log_oldest_root(struct extent_buffer *eb_root,
						      u64 time_seq)
{
	struct tree_mod_elem *tm;
	struct tree_mod_elem *found = NULL;
	u64 root_logical = eb_root->start;
	bool looped = false;

	if (!time_seq)
		return NULL;

	/*
	 * The very last operation that's logged for a root is the replacement
	 * operation (if it is replaced at all). This has the logical address
	 * of the *new* root, making it the very first operation that's logged
	 * for this root.
	 */
	while (1) {
		tm = tree_mod_log_search_oldest(eb_root->fs_info, root_logical,
						time_seq);
		if (!looped && !tm)
			return NULL;
		/*
		 * If there are no tree operation for the oldest root, we simply
		 * return it. This should only happen if that (old) root is at
		 * level 0.
		 */
		if (!tm)
			break;

		/*
		 * If there's an operation that's not a root replacement, we
		 * found the oldest version of our root. Normally, we'll find a
		 * BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING operation here.
		 */
		if (tm->op != BTRFS_MOD_LOG_ROOT_REPLACE)
			break;

		found = tm;
		root_logical = tm->old_root.logical;
		looped = true;
	}

	/* If there's no old root to return, return what we found instead */
	if (!found)
		found = tm;

	return found;
}


/*
 * tm is a pointer to the first operation to rewind within eb. Then, all
 * previous operations will be rewound (until we reach something older than
 * time_seq).
 */
static void tree_mod_log_rewind(struct btrfs_fs_info *fs_info,
				struct extent_buffer *eb,
				u64 time_seq,
				struct tree_mod_elem *first_tm)
{
	u32 n;
	struct rb_node *next;
	struct tree_mod_elem *tm = first_tm;
	unsigned long o_dst;
	unsigned long o_src;
	unsigned long p_size = sizeof(struct btrfs_key_ptr);
	/*
	 * max_slot tracks the maximum valid slot of the rewind eb at every
	 * step of the rewind. This is in contrast with 'n' which eventually
	 * matches the number of items, but can be wrong during moves or if
	 * removes overlap on already valid slots (which is probably separately
	 * a bug). We do this to validate the offsets of memmoves for rewinding
	 * moves and detect invalid memmoves.
	 *
	 * Since a rewind eb can start empty, max_slot is a signed integer with
	 * a special meaning for -1, which is that no slot is valid to move out
	 * of. Any other negative value is invalid.
	 */
	int max_slot;
	int move_src_end_slot;
	int move_dst_end_slot;

	n = btrfs_header_nritems(eb);
	max_slot = n - 1;
	read_lock(&fs_info->tree_mod_log_lock);
	while (tm && tm->seq >= time_seq) {
		ASSERT(max_slot >= -1);
		/*
		 * All the operations are recorded with the operator used for
		 * the modification. As we're going backwards, we do the
		 * opposite of each operation here.
		 */
		switch (tm->op) {
		case BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING:
			BUG_ON(tm->slot < n);
			fallthrough;
		case BTRFS_MOD_LOG_KEY_REMOVE_WHILE_MOVING:
		case BTRFS_MOD_LOG_KEY_REMOVE:
			btrfs_set_node_key(eb, &tm->key, tm->slot);
			btrfs_set_node_blockptr(eb, tm->slot, tm->blockptr);
			btrfs_set_node_ptr_generation(eb, tm->slot,
						      tm->generation);
			n++;
			if (tm->slot > max_slot)
				max_slot = tm->slot;
			break;
		case BTRFS_MOD_LOG_KEY_REPLACE:
			BUG_ON(tm->slot >= n);
			btrfs_set_node_key(eb, &tm->key, tm->slot);
			btrfs_set_node_blockptr(eb, tm->slot, tm->blockptr);
			btrfs_set_node_ptr_generation(eb, tm->slot,
						      tm->generation);
			break;
		case BTRFS_MOD_LOG_KEY_ADD:
			/*
			 * It is possible we could have already removed keys
			 * behind the known max slot, so this will be an
			 * overestimate. In practice, the copy operation
			 * inserts them in increasing order, and overestimating
			 * just means we miss some warnings, so it's OK. It
			 * isn't worth carefully tracking the full array of
			 * valid slots to check against when moving.
			 */
			if (tm->slot == max_slot)
				max_slot--;
			/* if a move operation is needed it's in the log */
			n--;
			break;
		case BTRFS_MOD_LOG_MOVE_KEYS:
			ASSERT(tm->move.nr_items > 0);
			move_src_end_slot = tm->move.dst_slot + tm->move.nr_items - 1;
			move_dst_end_slot = tm->slot + tm->move.nr_items - 1;
			o_dst = btrfs_node_key_ptr_offset(eb, tm->slot);
			o_src = btrfs_node_key_ptr_offset(eb, tm->move.dst_slot);
			if (WARN_ON(move_src_end_slot > max_slot ||
				    tm->move.nr_items <= 0)) {
				btrfs_warn(fs_info,
"move from invalid tree mod log slot eb %llu slot %d dst_slot %d nr_items %d seq %llu n %u max_slot %d",
					   eb->start, tm->slot,
					   tm->move.dst_slot, tm->move.nr_items,
					   tm->seq, n, max_slot);
			}
			memmove_extent_buffer(eb, o_dst, o_src,
					      tm->move.nr_items * p_size);
			max_slot = move_dst_end_slot;
			break;
		case BTRFS_MOD_LOG_ROOT_REPLACE:
			/*
			 * This operation is special. For roots, this must be
			 * handled explicitly before rewinding.
			 * For non-roots, this operation may exist if the node
			 * was a root: root A -> child B; then A gets empty and
			 * B is promoted to the new root. In the mod log, we'll
			 * have a root-replace operation for B, a tree block
			 * that is no root. We simply ignore that operation.
			 */
			break;
		}
		next = rb_next(&tm->node);
		if (!next)
			break;
		tm = rb_entry(next, struct tree_mod_elem, node);
		if (tm->logical != first_tm->logical)
			break;
	}
	read_unlock(&fs_info->tree_mod_log_lock);
	btrfs_set_header_nritems(eb, n);
}

/*
 * Called with eb read locked. If the buffer cannot be rewound, the same buffer
 * is returned. If rewind operations happen, a fresh buffer is returned. The
 * returned buffer is always read-locked. If the returned buffer is not the
 * input buffer, the lock on the input buffer is released and the input buffer
 * is freed (its refcount is decremented).
 */
struct extent_buffer *btrfs_tree_mod_log_rewind(struct btrfs_fs_info *fs_info,
						struct extent_buffer *eb,
						u64 time_seq)
{
	struct extent_buffer *eb_rewin;
	struct tree_mod_elem *tm;

	if (!time_seq)
		return eb;

	if (btrfs_header_level(eb) == 0)
		return eb;

	tm = tree_mod_log_search(fs_info, eb->start, time_seq);
	if (!tm)
		return eb;

	if (tm->op == BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING) {
		BUG_ON(tm->slot != 0);
		eb_rewin = alloc_dummy_extent_buffer(fs_info, eb->start);
		if (!eb_rewin) {
			btrfs_tree_read_unlock(eb);
			free_extent_buffer(eb);
			return NULL;
		}
		btrfs_set_header_bytenr(eb_rewin, eb->start);
		btrfs_set_header_backref_rev(eb_rewin,
					     btrfs_header_backref_rev(eb));
		btrfs_set_header_owner(eb_rewin, btrfs_header_owner(eb));
		btrfs_set_header_level(eb_rewin, btrfs_header_level(eb));
	} else {
		eb_rewin = btrfs_clone_extent_buffer(eb);
		if (!eb_rewin) {
			btrfs_tree_read_unlock(eb);
			free_extent_buffer(eb);
			return NULL;
		}
	}

	btrfs_tree_read_unlock(eb);
	free_extent_buffer(eb);

	btrfs_set_buffer_lockdep_class(btrfs_header_owner(eb_rewin),
				       eb_rewin, btrfs_header_level(eb_rewin));
	btrfs_tree_read_lock(eb_rewin);
	tree_mod_log_rewind(fs_info, eb_rewin, time_seq, tm);
	WARN_ON(btrfs_header_nritems(eb_rewin) >
		BTRFS_NODEPTRS_PER_BLOCK(fs_info));

	return eb_rewin;
}

/*
 * Rewind the state of @root's root node to the given @time_seq value.
 * If there are no changes, the current root->root_node is returned. If anything
 * changed in between, there's a fresh buffer allocated on which the rewind
 * operations are done. In any case, the returned buffer is read locked.
 * Returns NULL on error (with no locks held).
 */
struct extent_buffer *btrfs_get_old_root(struct btrfs_root *root, u64 time_seq)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct tree_mod_elem *tm;
	struct extent_buffer *eb = NULL;
	struct extent_buffer *eb_root;
	u64 eb_root_owner = 0;
	struct extent_buffer *old;
	struct tree_mod_root *old_root = NULL;
	u64 old_generation = 0;
	u64 logical;
	int level;

	eb_root = btrfs_read_lock_root_node(root);
	tm = tree_mod_log_oldest_root(eb_root, time_seq);
	if (!tm)
		return eb_root;

	if (tm->op == BTRFS_MOD_LOG_ROOT_REPLACE) {
		old_root = &tm->old_root;
		old_generation = tm->generation;
		logical = old_root->logical;
		level = old_root->level;
	} else {
		logical = eb_root->start;
		level = btrfs_header_level(eb_root);
	}

	tm = tree_mod_log_search(fs_info, logical, time_seq);
	if (old_root && tm && tm->op != BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING) {
		struct btrfs_tree_parent_check check = { 0 };

		btrfs_tree_read_unlock(eb_root);
		free_extent_buffer(eb_root);

		check.level = level;
		check.owner_root = btrfs_root_id(root);

		old = read_tree_block(fs_info, logical, &check);
		if (WARN_ON(IS_ERR(old) || !extent_buffer_uptodate(old))) {
			if (!IS_ERR(old))
				free_extent_buffer(old);
			btrfs_warn(fs_info,
				   "failed to read tree block %llu from get_old_root",
				   logical);
		} else {
			struct tree_mod_elem *tm2;

			btrfs_tree_read_lock(old);
			eb = btrfs_clone_extent_buffer(old);
			/*
			 * After the lookup for the most recent tree mod operation
			 * above and before we locked and cloned the extent buffer
			 * 'old', a new tree mod log operation may have been added.
			 * So lookup for a more recent one to make sure the number
			 * of mod log operations we replay is consistent with the
			 * number of items we have in the cloned extent buffer,
			 * otherwise we can hit a BUG_ON when rewinding the extent
			 * buffer.
			 */
			tm2 = tree_mod_log_search(fs_info, logical, time_seq);
			btrfs_tree_read_unlock(old);
			free_extent_buffer(old);
			ASSERT(tm2);
			ASSERT(tm2 == tm || tm2->seq > tm->seq);
			if (!tm2 || tm2->seq < tm->seq) {
				free_extent_buffer(eb);
				return NULL;
			}
			tm = tm2;
		}
	} else if (old_root) {
		eb_root_owner = btrfs_header_owner(eb_root);
		btrfs_tree_read_unlock(eb_root);
		free_extent_buffer(eb_root);
		eb = alloc_dummy_extent_buffer(fs_info, logical);
	} else {
		eb = btrfs_clone_extent_buffer(eb_root);
		btrfs_tree_read_unlock(eb_root);
		free_extent_buffer(eb_root);
	}

	if (!eb)
		return NULL;
	if (old_root) {
		btrfs_set_header_bytenr(eb, eb->start);
		btrfs_set_header_backref_rev(eb, BTRFS_MIXED_BACKREF_REV);
		btrfs_set_header_owner(eb, eb_root_owner);
		btrfs_set_header_level(eb, old_root->level);
		btrfs_set_header_generation(eb, old_generation);
	}
	btrfs_set_buffer_lockdep_class(btrfs_header_owner(eb), eb,
				       btrfs_header_level(eb));
	btrfs_tree_read_lock(eb);
	if (tm)
		tree_mod_log_rewind(fs_info, eb, time_seq, tm);
	else
		WARN_ON(btrfs_header_level(eb) != 0);
	WARN_ON(btrfs_header_nritems(eb) > BTRFS_NODEPTRS_PER_BLOCK(fs_info));

	return eb;
}

int btrfs_old_root_level(struct btrfs_root *root, u64 time_seq)
{
	struct tree_mod_elem *tm;
	int level;
	struct extent_buffer *eb_root = btrfs_root_node(root);

	tm = tree_mod_log_oldest_root(eb_root, time_seq);
	if (tm && tm->op == BTRFS_MOD_LOG_ROOT_REPLACE)
		level = tm->old_root.level;
	else
		level = btrfs_header_level(eb_root);

	free_extent_buffer(eb_root);

	return level;
}

/*
 * Return the lowest sequence number in the tree modification log.
 *
 * Return the sequence number of the oldest tree modification log user, which
 * corresponds to the lowest sequence number of all existing users. If there are
 * no users it returns 0.
 */
u64 btrfs_tree_mod_log_lowest_seq(struct btrfs_fs_info *fs_info)
{
	u64 ret = 0;

	read_lock(&fs_info->tree_mod_log_lock);
	if (!list_empty(&fs_info->tree_mod_seq_list)) {
		struct btrfs_seq_list *elem;

		elem = list_first_entry(&fs_info->tree_mod_seq_list,
					struct btrfs_seq_list, list);
		ret = elem->seq;
	}
	read_unlock(&fs_info->tree_mod_log_lock);

	return ret;
}
