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

#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/list_sort.h>
#include <linux/iversion.h>
#include "misc.h"
#include "ctree.h"
#include "tree-log.h"
#include "disk-io.h"
#include "locking.h"
#include "backref.h"
#include "compression.h"
#include "qgroup.h"
#include "block-group.h"
#include "space-info.h"
#include "inode-item.h"
#include "fs.h"
#include "accessors.h"
#include "extent-tree.h"
#include "root-tree.h"
#include "dir-item.h"
#include "file-item.h"
#include "file.h"
#include "orphan.h"
#include "print-tree.h"
#include "tree-checker.h"
#include "delayed-inode.h"

#define MAX_CONFLICT_INODES 10

/* magic values for the inode_only field in btrfs_log_inode:
 *
 * LOG_INODE_ALL means to log everything
 * LOG_INODE_EXISTS means to log just enough to recreate the inode
 * during log replay
 */
enum {
	LOG_INODE_ALL,
	LOG_INODE_EXISTS,
};

/*
 * directory trouble cases
 *
 * 1) on rename or unlink, if the inode being unlinked isn't in the fsync
 * log, we must force a full commit before doing an fsync of the directory
 * where the unlink was done.
 * ---> record transid of last unlink/rename per directory
 *
 * mkdir foo/some_dir
 * normal commit
 * rename foo/some_dir foo2/some_dir
 * mkdir foo/some_dir
 * fsync foo/some_dir/some_file
 *
 * The fsync above will unlink the original some_dir without recording
 * it in its new location (foo2).  After a crash, some_dir will be gone
 * unless the fsync of some_file forces a full commit
 *
 * 2) we must log any new names for any file or dir that is in the fsync
 * log. ---> check inode while renaming/linking.
 *
 * 2a) we must log any new names for any file or dir during rename
 * when the directory they are being removed from was logged.
 * ---> check inode and old parent dir during rename
 *
 *  2a is actually the more important variant.  With the extra logging
 *  a crash might unlink the old name without recreating the new one
 *
 * 3) after a crash, we must go through any directories with a link count
 * of zero and redo the rm -rf
 *
 * mkdir f1/foo
 * normal commit
 * rm -rf f1/foo
 * fsync(f1)
 *
 * The directory f1 was fully removed from the FS, but fsync was never
 * called on f1, only its parent dir.  After a crash the rm -rf must
 * be replayed.  This must be able to recurse down the entire
 * directory tree.  The inode link count fixup code takes care of the
 * ugly details.
 */

/*
 * stages for the tree walking.  The first
 * stage (0) is to only pin down the blocks we find
 * the second stage (1) is to make sure that all the inodes
 * we find in the log are created in the subvolume.
 *
 * The last stage is to deal with directories and links and extents
 * and all the other fun semantics
 */
enum {
	LOG_WALK_PIN_ONLY,
	LOG_WALK_REPLAY_INODES,
	LOG_WALK_REPLAY_DIR_INDEX,
	LOG_WALK_REPLAY_ALL,
};

/*
 * The walk control struct is used to pass state down the chain when processing
 * the log tree. The stage field tells us which part of the log tree processing
 * we are currently doing.
 */
struct walk_control {
	/*
	 * Signal that we are freeing the metadata extents of a log tree.
	 * This is used at transaction commit time while freeing a log tree.
	 */
	bool free;

	/*
	 * Signal that we are pinning the metadata extents of a log tree and the
	 * data extents its leaves point to (if using mixed block groups).
	 * This happens in the first stage of log replay to ensure that during
	 * replay, while we are modifying subvolume trees, we don't overwrite
	 * the metadata extents of log trees.
	 */
	bool pin;

	/* What stage of the replay code we're currently in. */
	int stage;

	/*
	 * Ignore any items from the inode currently being processed. Needs
	 * to be set every time we find a BTRFS_INODE_ITEM_KEY.
	 */
	bool ignore_cur_inode;

	/*
	 * The root we are currently replaying to. This is NULL for the replay
	 * stage LOG_WALK_PIN_ONLY.
	 */
	struct btrfs_root *root;

	/* The log tree we are currently processing (not NULL for any stage). */
	struct btrfs_root *log;

	/* The transaction handle used for replaying all log trees. */
	struct btrfs_trans_handle *trans;

	/*
	 * The function that gets used to process blocks we find in the tree.
	 * Note the extent_buffer might not be up to date when it is passed in,
	 * and it must be checked or read if you need the data inside it.
	 */
	int (*process_func)(struct extent_buffer *eb,
			    struct walk_control *wc, u64 gen, int level);

	/*
	 * The following are used only when stage is >= LOG_WALK_REPLAY_INODES
	 * and by the replay_one_buffer() callback.
	 */

	/* The current log leaf being processed. */
	struct extent_buffer *log_leaf;
	/* The key being processed of the current log leaf. */
	struct btrfs_key log_key;
	/* The slot being processed of the current log leaf. */
	int log_slot;

	/* A path used for searches and modifications to subvolume trees. */
	struct btrfs_path *subvol_path;
};

static void do_abort_log_replay(struct walk_control *wc, const char *function,
				unsigned int line, int error, const char *fmt, ...)
{
	struct btrfs_fs_info *fs_info = wc->trans->fs_info;
	struct va_format vaf;
	va_list args;

	/*
	 * Do nothing if we already aborted, to avoid dumping leaves again which
	 * can be verbose. Further more, only the first call is useful since it
	 * is where we have a problem. Note that we do not use the flag
	 * BTRFS_FS_STATE_TRANS_ABORTED because log replay calls functions that
	 * are outside of tree-log.c that can abort transactions (such as
	 * btrfs_add_link() for example), so if that happens we still want to
	 * dump all log replay specific information below.
	 */
	if (test_and_set_bit(BTRFS_FS_STATE_LOG_REPLAY_ABORTED, &fs_info->fs_state))
		return;

	btrfs_abort_transaction(wc->trans, error);

	if (wc->subvol_path && wc->subvol_path->nodes[0]) {
		btrfs_crit(fs_info,
			   "subvolume (root %llu) leaf currently being processed:",
			   btrfs_root_id(wc->root));
		btrfs_print_leaf(wc->subvol_path->nodes[0]);
	}

	if (wc->log_leaf) {
		btrfs_crit(fs_info,
	  "log tree (for root %llu) leaf currently being processed (slot %d key %llu %u %llu):",
			   btrfs_root_id(wc->root), wc->log_slot,
			   wc->log_key.objectid, wc->log_key.type, wc->log_key.offset);
		btrfs_print_leaf(wc->log_leaf);
	}

	va_start(args, fmt);
	vaf.fmt = fmt;
	vaf.va = &args;

	btrfs_crit(fs_info,
	   "log replay failed in %s:%u for root %llu, stage %d, with error %d: %pV",
		   function, line, btrfs_root_id(wc->root), wc->stage, error, &vaf);

	va_end(args);
}

/*
 * Use this for aborting a transaction during log replay while we are down the
 * call chain of replay_one_buffer(), so that we get a lot more useful
 * information for debugging issues when compared to a plain call to
 * btrfs_abort_transaction().
 */
#define btrfs_abort_log_replay(wc, error, fmt, args...) \
	do_abort_log_replay((wc), __func__, __LINE__, (error), fmt, ##args)

static int btrfs_log_inode(struct btrfs_trans_handle *trans,
			   struct btrfs_inode *inode,
			   int inode_only,
			   struct btrfs_log_ctx *ctx);
static int link_to_fixup_dir(struct walk_control *wc, u64 objectid);
static noinline int replay_dir_deletes(struct walk_control *wc,
				       u64 dirid, bool del_all);
static void wait_log_commit(struct btrfs_root *root, int transid);

/*
 * tree logging is a special write ahead log used to make sure that
 * fsyncs and O_SYNCs can happen without doing full tree commits.
 *
 * Full tree commits are expensive because they require commonly
 * modified blocks to be recowed, creating many dirty pages in the
 * extent tree an 4x-6x higher write load than ext3.
 *
 * Instead of doing a tree commit on every fsync, we use the
 * key ranges and transaction ids to find items for a given file or directory
 * that have changed in this transaction.  Those items are copied into
 * a special tree (one per subvolume root), that tree is written to disk
 * and then the fsync is considered complete.
 *
 * After a crash, items are copied out of the log-tree back into the
 * subvolume tree.  Any file data extents found are recorded in the extent
 * allocation tree, and the log-tree freed.
 *
 * The log tree is read three times, once to pin down all the extents it is
 * using in ram and once, once to create all the inodes logged in the tree
 * and once to do all the other items.
 */

static struct btrfs_inode *btrfs_iget_logging(u64 objectid, struct btrfs_root *root)
{
	unsigned int nofs_flag;
	struct btrfs_inode *inode;

	/* Only meant to be called for subvolume roots and not for log roots. */
	ASSERT(btrfs_is_fstree(btrfs_root_id(root)));

	/*
	 * We're holding a transaction handle whether we are logging or
	 * replaying a log tree, so we must make sure NOFS semantics apply
	 * because btrfs_alloc_inode() may be triggered and it uses GFP_KERNEL
	 * to allocate an inode, which can recurse back into the filesystem and
	 * attempt a transaction commit, resulting in a deadlock.
	 */
	nofs_flag = memalloc_nofs_save();
	inode = btrfs_iget(objectid, root);
	memalloc_nofs_restore(nofs_flag);

	return inode;
}

/*
 * start a sub transaction and setup the log tree
 * this increments the log tree writer count to make the people
 * syncing the tree wait for us to finish
 */
static int start_log_trans(struct btrfs_trans_handle *trans,
			   struct btrfs_root *root,
			   struct btrfs_log_ctx *ctx)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_root *tree_root = fs_info->tree_root;
	const bool zoned = btrfs_is_zoned(fs_info);
	int ret = 0;
	bool created = false;

	/*
	 * First check if the log root tree was already created. If not, create
	 * it before locking the root's log_mutex, just to keep lockdep happy.
	 */
	if (!test_bit(BTRFS_ROOT_HAS_LOG_TREE, &tree_root->state)) {
		mutex_lock(&tree_root->log_mutex);
		if (!fs_info->log_root_tree) {
			ret = btrfs_init_log_root_tree(trans, fs_info);
			if (!ret) {
				set_bit(BTRFS_ROOT_HAS_LOG_TREE, &tree_root->state);
				created = true;
			}
		}
		mutex_unlock(&tree_root->log_mutex);
		if (ret)
			return ret;
	}

	mutex_lock(&root->log_mutex);

again:
	if (root->log_root) {
		int index = (root->log_transid + 1) % 2;

		if (btrfs_need_log_full_commit(trans)) {
			ret = BTRFS_LOG_FORCE_COMMIT;
			goto out;
		}

		if (zoned && atomic_read(&root->log_commit[index])) {
			wait_log_commit(root, root->log_transid - 1);
			goto again;
		}

		if (!root->log_start_pid) {
			clear_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state);
			root->log_start_pid = current->pid;
		} else if (root->log_start_pid != current->pid) {
			set_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state);
		}
	} else {
		/*
		 * This means fs_info->log_root_tree was already created
		 * for some other FS trees. Do the full commit not to mix
		 * nodes from multiple log transactions to do sequential
		 * writing.
		 */
		if (zoned && !created) {
			ret = BTRFS_LOG_FORCE_COMMIT;
			goto out;
		}

		ret = btrfs_add_log_tree(trans, root);
		if (ret)
			goto out;

		set_bit(BTRFS_ROOT_HAS_LOG_TREE, &root->state);
		clear_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state);
		root->log_start_pid = current->pid;
	}

	atomic_inc(&root->log_writers);
	if (!ctx->logging_new_name) {
		int index = root->log_transid % 2;
		list_add_tail(&ctx->list, &root->log_ctxs[index]);
		ctx->log_transid = root->log_transid;
	}

out:
	mutex_unlock(&root->log_mutex);
	return ret;
}

/*
 * returns 0 if there was a log transaction running and we were able
 * to join, or returns -ENOENT if there were not transactions
 * in progress
 */
static int join_running_log_trans(struct btrfs_root *root)
{
	const bool zoned = btrfs_is_zoned(root->fs_info);
	int ret = -ENOENT;

	if (!test_bit(BTRFS_ROOT_HAS_LOG_TREE, &root->state))
		return ret;

	mutex_lock(&root->log_mutex);
again:
	if (root->log_root) {
		int index = (root->log_transid + 1) % 2;

		ret = 0;
		if (zoned && atomic_read(&root->log_commit[index])) {
			wait_log_commit(root, root->log_transid - 1);
			goto again;
		}
		atomic_inc(&root->log_writers);
	}
	mutex_unlock(&root->log_mutex);
	return ret;
}

/*
 * This either makes the current running log transaction wait
 * until you call btrfs_end_log_trans() or it makes any future
 * log transactions wait until you call btrfs_end_log_trans()
 */
void btrfs_pin_log_trans(struct btrfs_root *root)
{
	atomic_inc(&root->log_writers);
}

/*
 * indicate we're done making changes to the log tree
 * and wake up anyone waiting to do a sync
 */
void btrfs_end_log_trans(struct btrfs_root *root)
{
	if (atomic_dec_and_test(&root->log_writers)) {
		/* atomic_dec_and_test implies a barrier */
		cond_wake_up_nomb(&root->log_writer_wait);
	}
}

/*
 * process_func used to pin down extents, write them or wait on them
 */
static int process_one_buffer(struct extent_buffer *eb,
			      struct walk_control *wc, u64 gen, int level)
{
	struct btrfs_root *log = wc->log;
	struct btrfs_trans_handle *trans = wc->trans;
	struct btrfs_fs_info *fs_info = log->fs_info;
	int ret = 0;

	/*
	 * If this fs is mixed then we need to be able to process the leaves to
	 * pin down any logged extents, so we have to read the block.
	 */
	if (btrfs_fs_incompat(fs_info, MIXED_GROUPS)) {
		struct btrfs_tree_parent_check check = {
			.level = level,
			.transid = gen
		};

		ret = btrfs_read_extent_buffer(eb, &check);
		if (unlikely(ret)) {
			if (trans)
				btrfs_abort_transaction(trans, ret);
			else
				btrfs_handle_fs_error(fs_info, ret, NULL);
			return ret;
		}
	}

	if (wc->pin) {
		ASSERT(trans != NULL);
		ret = btrfs_pin_extent_for_log_replay(trans, eb);
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			return ret;
		}

		if (btrfs_buffer_uptodate(eb, gen, false) && level == 0) {
			ret = btrfs_exclude_logged_extents(eb);
			if (ret)
				btrfs_abort_transaction(trans, ret);
		}
	}
	return ret;
}

/*
 * Item overwrite used by log replay. The given log tree leaf, slot and key
 * from the walk_control structure all refer to the source data we are copying
 * out.
 *
 * The given root is for the tree we are copying into, and path is a scratch
 * path for use in this function (it should be released on entry and will be
 * released on exit).
 *
 * If the key is already in the destination tree the existing item is
 * overwritten.  If the existing item isn't big enough, it is extended.
 * If it is too large, it is truncated.
 *
 * If the key isn't in the destination yet, a new item is inserted.
 */
static int overwrite_item(struct walk_control *wc)
{
	struct btrfs_trans_handle *trans = wc->trans;
	struct btrfs_root *root = wc->root;
	int ret;
	u32 item_size;
	u64 saved_i_size = 0;
	int save_old_i_size = 0;
	unsigned long src_ptr;
	unsigned long dst_ptr;
	struct extent_buffer *dst_eb;
	int dst_slot;
	const bool is_inode_item = (wc->log_key.type == BTRFS_INODE_ITEM_KEY);

	/*
	 * This is only used during log replay, so the root is always from a
	 * fs/subvolume tree. In case we ever need to support a log root, then
	 * we'll have to clone the leaf in the path, release the path and use
	 * the leaf before writing into the log tree. See the comments at
	 * copy_items() for more details.
	 */
	ASSERT(btrfs_root_id(root) != BTRFS_TREE_LOG_OBJECTID);

	item_size = btrfs_item_size(wc->log_leaf, wc->log_slot);
	src_ptr = btrfs_item_ptr_offset(wc->log_leaf, wc->log_slot);

	/* Look for the key in the destination tree. */
	ret = btrfs_search_slot(NULL, root, &wc->log_key, wc->subvol_path, 0, 0);
	if (ret < 0) {
		btrfs_abort_log_replay(wc, ret,
		"failed to search subvolume tree for key (%llu %u %llu) root %llu",
				       wc->log_key.objectid, wc->log_key.type,
				       wc->log_key.offset, btrfs_root_id(root));
		return ret;
	}

	dst_eb = wc->subvol_path->nodes[0];
	dst_slot = wc->subvol_path->slots[0];

	if (ret == 0) {
		char *src_copy;
		const u32 dst_size = btrfs_item_size(dst_eb, dst_slot);

		if (dst_size != item_size)
			goto insert;

		if (item_size == 0) {
			btrfs_release_path(wc->subvol_path);
			return 0;
		}
		src_copy = kmalloc(item_size, GFP_NOFS);
		if (!src_copy) {
			btrfs_abort_log_replay(wc, -ENOMEM,
			       "failed to allocate memory for log leaf item");
			return -ENOMEM;
		}

		read_extent_buffer(wc->log_leaf, src_copy, src_ptr, item_size);
		dst_ptr = btrfs_item_ptr_offset(dst_eb, dst_slot);
		ret = memcmp_extent_buffer(dst_eb, src_copy, dst_ptr, item_size);

		kfree(src_copy);
		/*
		 * they have the same contents, just return, this saves
		 * us from cowing blocks in the destination tree and doing
		 * extra writes that may not have been done by a previous
		 * sync
		 */
		if (ret == 0) {
			btrfs_release_path(wc->subvol_path);
			return 0;
		}

		/*
		 * We need to load the old nbytes into the inode so when we
		 * replay the extents we've logged we get the right nbytes.
		 */
		if (is_inode_item) {
			struct btrfs_inode_item *item;
			u64 nbytes;
			u32 mode;

			item = btrfs_item_ptr(dst_eb, dst_slot,
					      struct btrfs_inode_item);
			nbytes = btrfs_inode_nbytes(dst_eb, item);
			item = btrfs_item_ptr(wc->log_leaf, wc->log_slot,
					      struct btrfs_inode_item);
			btrfs_set_inode_nbytes(wc->log_leaf, item, nbytes);

			/*
			 * If this is a directory we need to reset the i_size to
			 * 0 so that we can set it up properly when replaying
			 * the rest of the items in this log.
			 */
			mode = btrfs_inode_mode(wc->log_leaf, item);
			if (S_ISDIR(mode))
				btrfs_set_inode_size(wc->log_leaf, item, 0);
		}
	} else if (is_inode_item) {
		struct btrfs_inode_item *item;
		u32 mode;

		/*
		 * New inode, set nbytes to 0 so that the nbytes comes out
		 * properly when we replay the extents.
		 */
		item = btrfs_item_ptr(wc->log_leaf, wc->log_slot, struct btrfs_inode_item);
		btrfs_set_inode_nbytes(wc->log_leaf, item, 0);

		/*
		 * If this is a directory we need to reset the i_size to 0 so
		 * that we can set it up properly when replaying the rest of
		 * the items in this log.
		 */
		mode = btrfs_inode_mode(wc->log_leaf, item);
		if (S_ISDIR(mode))
			btrfs_set_inode_size(wc->log_leaf, item, 0);
	}
insert:
	btrfs_release_path(wc->subvol_path);
	/* try to insert the key into the destination tree */
	wc->subvol_path->skip_release_on_error = 1;
	ret = btrfs_insert_empty_item(trans, root, wc->subvol_path, &wc->log_key, item_size);
	wc->subvol_path->skip_release_on_error = 0;

	dst_eb = wc->subvol_path->nodes[0];
	dst_slot = wc->subvol_path->slots[0];

	/* make sure any existing item is the correct size */
	if (ret == -EEXIST || ret == -EOVERFLOW) {
		const u32 found_size = btrfs_item_size(dst_eb, dst_slot);

		if (found_size > item_size)
			btrfs_truncate_item(trans, wc->subvol_path, item_size, 1);
		else if (found_size < item_size)
			btrfs_extend_item(trans, wc->subvol_path, item_size - found_size);
	} else if (ret) {
		btrfs_abort_log_replay(wc, ret,
				       "failed to insert item for key (%llu %u %llu)",
				       wc->log_key.objectid, wc->log_key.type,
				       wc->log_key.offset);
		return ret;
	}
	dst_ptr = btrfs_item_ptr_offset(dst_eb, dst_slot);

	/* don't overwrite an existing inode if the generation number
	 * was logged as zero.  This is done when the tree logging code
	 * is just logging an inode to make sure it exists after recovery.
	 *
	 * Also, don't overwrite i_size on directories during replay.
	 * log replay inserts and removes directory items based on the
	 * state of the tree found in the subvolume, and i_size is modified
	 * as it goes
	 */
	if (is_inode_item && ret == -EEXIST) {
		struct btrfs_inode_item *src_item;
		struct btrfs_inode_item *dst_item;

		src_item = (struct btrfs_inode_item *)src_ptr;
		dst_item = (struct btrfs_inode_item *)dst_ptr;

		if (btrfs_inode_generation(wc->log_leaf, src_item) == 0) {
			const u64 ino_size = btrfs_inode_size(wc->log_leaf, src_item);

			/*
			 * For regular files an ino_size == 0 is used only when
			 * logging that an inode exists, as part of a directory
			 * fsync, and the inode wasn't fsynced before. In this
			 * case don't set the size of the inode in the fs/subvol
			 * tree, otherwise we would be throwing valid data away.
			 */
			if (S_ISREG(btrfs_inode_mode(wc->log_leaf, src_item)) &&
			    S_ISREG(btrfs_inode_mode(dst_eb, dst_item)) &&
			    ino_size != 0)
				btrfs_set_inode_size(dst_eb, dst_item, ino_size);
			goto no_copy;
		}

		if (S_ISDIR(btrfs_inode_mode(wc->log_leaf, src_item)) &&
		    S_ISDIR(btrfs_inode_mode(dst_eb, dst_item))) {
			save_old_i_size = 1;
			saved_i_size = btrfs_inode_size(dst_eb, dst_item);
		}
	}

	copy_extent_buffer(dst_eb, wc->log_leaf, dst_ptr, src_ptr, item_size);

	if (save_old_i_size) {
		struct btrfs_inode_item *dst_item;

		dst_item = (struct btrfs_inode_item *)dst_ptr;
		btrfs_set_inode_size(dst_eb, dst_item, saved_i_size);
	}

	/* make sure the generation is filled in */
	if (is_inode_item) {
		struct btrfs_inode_item *dst_item;

		dst_item = (struct btrfs_inode_item *)dst_ptr;
		if (btrfs_inode_generation(dst_eb, dst_item) == 0)
			btrfs_set_inode_generation(dst_eb, dst_item, trans->transid);
	}
no_copy:
	btrfs_release_path(wc->subvol_path);
	return 0;
}

static int read_alloc_one_name(struct extent_buffer *eb, void *start, int len,
			       struct fscrypt_str *name)
{
	char *buf;

	buf = kmalloc(len, GFP_NOFS);
	if (!buf)
		return -ENOMEM;

	read_extent_buffer(eb, buf, (unsigned long)start, len);
	name->name = buf;
	name->len = len;
	return 0;
}

/* replays a single extent in 'eb' at 'slot' with 'key' into the
 * subvolume 'root'.  path is released on entry and should be released
 * on exit.
 *
 * extents in the log tree have not been allocated out of the extent
 * tree yet.  So, this completes the allocation, taking a reference
 * as required if the extent already exists or creating a new extent
 * if it isn't in the extent allocation tree yet.
 *
 * The extent is inserted into the file, dropping any existing extents
 * from the file that overlap the new one.
 */
static noinline int replay_one_extent(struct walk_control *wc)
{
	struct btrfs_trans_handle *trans = wc->trans;
	struct btrfs_root *root = wc->root;
	struct btrfs_drop_extents_args drop_args = { 0 };
	struct btrfs_fs_info *fs_info = root->fs_info;
	int found_type;
	u64 extent_end;
	const u64 start = wc->log_key.offset;
	u64 nbytes = 0;
	u64 csum_start;
	u64 csum_end;
	LIST_HEAD(ordered_sums);
	u64 offset;
	unsigned long dest_offset;
	struct btrfs_key ins;
	struct btrfs_file_extent_item *item;
	struct btrfs_inode *inode = NULL;
	int ret = 0;

	item = btrfs_item_ptr(wc->log_leaf, wc->log_slot, struct btrfs_file_extent_item);
	found_type = btrfs_file_extent_type(wc->log_leaf, item);

	if (found_type == BTRFS_FILE_EXTENT_REG ||
	    found_type == BTRFS_FILE_EXTENT_PREALLOC) {
		extent_end = start + btrfs_file_extent_num_bytes(wc->log_leaf, item);
		/* Holes don't take up space. */
		if (btrfs_file_extent_disk_bytenr(wc->log_leaf, item) != 0)
			nbytes = btrfs_file_extent_num_bytes(wc->log_leaf, item);
	} else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
		nbytes = btrfs_file_extent_ram_bytes(wc->log_leaf, item);
		extent_end = ALIGN(start + nbytes, fs_info->sectorsize);
	} else {
		btrfs_abort_log_replay(wc, -EUCLEAN,
		       "unexpected extent type=%d root=%llu inode=%llu offset=%llu",
				       found_type, btrfs_root_id(root),
				       wc->log_key.objectid, wc->log_key.offset);
		return -EUCLEAN;
	}

	inode = btrfs_iget_logging(wc->log_key.objectid, root);
	if (IS_ERR(inode)) {
		ret = PTR_ERR(inode);
		btrfs_abort_log_replay(wc, ret,
				       "failed to get inode %llu for root %llu",
				       wc->log_key.objectid, btrfs_root_id(root));
		return ret;
	}

	/*
	 * first check to see if we already have this extent in the
	 * file.  This must be done before the btrfs_drop_extents run
	 * so we don't try to drop this extent.
	 */
	ret = btrfs_lookup_file_extent(trans, root, wc->subvol_path,
				       btrfs_ino(inode), start, 0);

	if (ret == 0 &&
	    (found_type == BTRFS_FILE_EXTENT_REG ||
	     found_type == BTRFS_FILE_EXTENT_PREALLOC)) {
		struct extent_buffer *leaf = wc->subvol_path->nodes[0];
		struct btrfs_file_extent_item existing;
		unsigned long ptr;

		ptr = btrfs_item_ptr_offset(leaf, wc->subvol_path->slots[0]);
		read_extent_buffer(leaf, &existing, ptr, sizeof(existing));

		/*
		 * we already have a pointer to this exact extent,
		 * we don't have to do anything
		 */
		if (memcmp_extent_buffer(wc->log_leaf, &existing, (unsigned long)item,
					 sizeof(existing)) == 0) {
			btrfs_release_path(wc->subvol_path);
			goto out;
		}
	}
	btrfs_release_path(wc->subvol_path);

	/* drop any overlapping extents */
	drop_args.start = start;
	drop_args.end = extent_end;
	drop_args.drop_cache = true;
	drop_args.path = wc->subvol_path;
	ret = btrfs_drop_extents(trans, root, inode, &drop_args);
	if (ret) {
		btrfs_abort_log_replay(wc, ret,
	       "failed to drop extents for inode %llu range [%llu, %llu) root %llu",
				       wc->log_key.objectid, start, extent_end,
				       btrfs_root_id(root));
		goto out;
	}

	if (found_type == BTRFS_FILE_EXTENT_INLINE) {
		/* inline extents are easy, we just overwrite them */
		ret = overwrite_item(wc);
		if (ret)
			goto out;
		goto update_inode;
	}

	/*
	 * If not an inline extent, it can only be a regular or prealloc one.
	 * We have checked that above and returned -EUCLEAN if not.
	 */

	/* A hole and NO_HOLES feature enabled, nothing else to do. */
	if (btrfs_file_extent_disk_bytenr(wc->log_leaf, item) == 0 &&
	    btrfs_fs_incompat(fs_info, NO_HOLES))
		goto update_inode;

	ret = btrfs_insert_empty_item(trans, root, wc->subvol_path,
				      &wc->log_key, sizeof(*item));
	if (ret) {
		btrfs_abort_log_replay(wc, ret,
		       "failed to insert item with key (%llu %u %llu) root %llu",
				       wc->log_key.objectid, wc->log_key.type,
				       wc->log_key.offset, btrfs_root_id(root));
		goto out;
	}
	dest_offset = btrfs_item_ptr_offset(wc->subvol_path->nodes[0],
					    wc->subvol_path->slots[0]);
	copy_extent_buffer(wc->subvol_path->nodes[0], wc->log_leaf, dest_offset,
			   (unsigned long)item, sizeof(*item));

	/*
	 * We have an explicit hole and NO_HOLES is not enabled. We have added
	 * the hole file extent item to the subvolume tree, so we don't have
	 * anything else to do other than update the file extent item range and
	 * update the inode item.
	 */
	if (btrfs_file_extent_disk_bytenr(wc->log_leaf, item) == 0) {
		btrfs_release_path(wc->subvol_path);
		goto update_inode;
	}

	ins.objectid = btrfs_file_extent_disk_bytenr(wc->log_leaf, item);
	ins.type = BTRFS_EXTENT_ITEM_KEY;
	ins.offset = btrfs_file_extent_disk_num_bytes(wc->log_leaf, item);
	offset = wc->log_key.offset - btrfs_file_extent_offset(wc->log_leaf, item);

	/*
	 * Manually record dirty extent, as here we did a shallow file extent
	 * item copy and skip normal backref update, but modifying extent tree
	 * all by ourselves. So need to manually record dirty extent for qgroup,
	 * as the owner of the file extent changed from log tree (doesn't affect
	 * qgroup) to fs/file tree (affects qgroup).
	 */
	ret = btrfs_qgroup_trace_extent(trans, ins.objectid, ins.offset);
	if (ret < 0) {
		btrfs_abort_log_replay(wc, ret,
"failed to trace extent for bytenr %llu disk_num_bytes %llu inode %llu root %llu",
				       ins.objectid, ins.offset,
				       wc->log_key.objectid, btrfs_root_id(root));
		goto out;
	}

	/*
	 * Is this extent already allocated in the extent tree?
	 * If so, just add a reference.
	 */
	ret = btrfs_lookup_data_extent(fs_info, ins.objectid, ins.offset);
	if (ret < 0) {
		btrfs_abort_log_replay(wc, ret,
"failed to lookup data extent for bytenr %llu disk_num_bytes %llu inode %llu root %llu",
				       ins.objectid, ins.offset,
				       wc->log_key.objectid, btrfs_root_id(root));
		goto out;
	} else if (ret == 0) {
		struct btrfs_ref ref = {
			.action = BTRFS_ADD_DELAYED_REF,
			.bytenr = ins.objectid,
			.num_bytes = ins.offset,
			.owning_root = btrfs_root_id(root),
			.ref_root = btrfs_root_id(root),
		};

		btrfs_init_data_ref(&ref, wc->log_key.objectid, offset, 0, false);
		ret = btrfs_inc_extent_ref(trans, &ref);
		if (ret) {
			btrfs_abort_log_replay(wc, ret,
"failed to increment data extent for bytenr %llu disk_num_bytes %llu inode %llu root %llu",
					       ins.objectid, ins.offset,
					       wc->log_key.objectid,
					       btrfs_root_id(root));
			goto out;
		}
	} else {
		/* Insert the extent pointer in the extent tree. */
		ret = btrfs_alloc_logged_file_extent(trans, btrfs_root_id(root),
						     wc->log_key.objectid, offset, &ins);
		if (ret) {
			btrfs_abort_log_replay(wc, ret,
"failed to allocate logged data extent for bytenr %llu disk_num_bytes %llu offset %llu inode %llu root %llu",
					       ins.objectid, ins.offset, offset,
					       wc->log_key.objectid, btrfs_root_id(root));
			goto out;
		}
	}

	btrfs_release_path(wc->subvol_path);

	if (btrfs_file_extent_compression(wc->log_leaf, item)) {
		csum_start = ins.objectid;
		csum_end = csum_start + ins.offset;
	} else {
		csum_start = ins.objectid + btrfs_file_extent_offset(wc->log_leaf, item);
		csum_end = csum_start + btrfs_file_extent_num_bytes(wc->log_leaf, item);
	}

	ret = btrfs_lookup_csums_list(root->log_root, csum_start, csum_end - 1,
				      &ordered_sums, false);
	if (ret < 0) {
		btrfs_abort_log_replay(wc, ret,
	       "failed to lookups csums for range [%llu, %llu) inode %llu root %llu",
				       csum_start, csum_end, wc->log_key.objectid,
				       btrfs_root_id(root));
		goto out;
	}
	ret = 0;
	/*
	 * Now delete all existing cums in the csum root that cover our range.
	 * We do this because we can have an extent that is completely
	 * referenced by one file extent item and partially referenced by
	 * another file extent item (like after using the clone or extent_same
	 * ioctls). In this case if we end up doing the replay of the one that
	 * partially references the extent first, and we do not do the csum
	 * deletion below, we can get 2 csum items in the csum tree that overlap
	 * each other. For example, imagine our log has the two following file
	 * extent items:
	 *
	 * key (257 EXTENT_DATA 409600)
	 *     extent data disk byte 12845056 nr 102400
	 *     extent data offset 20480 nr 20480 ram 102400
	 *
	 * key (257 EXTENT_DATA 819200)
	 *     extent data disk byte 12845056 nr 102400
	 *     extent data offset 0 nr 102400 ram 102400
	 *
	 * Where the second one fully references the 100K extent that starts at
	 * disk byte 12845056, and the log tree has a single csum item that
	 * covers the entire range of the extent:
	 *
	 * key (EXTENT_CSUM EXTENT_CSUM 12845056) itemsize 100
	 *
	 * After the first file extent item is replayed, the csum tree gets the
	 * following csum item:
	 *
	 * key (EXTENT_CSUM EXTENT_CSUM 12865536) itemsize 20
	 *
	 * Which covers the 20K sub-range starting at offset 20K of our extent.
	 * Now when we replay the second file extent item, if we do not delete
	 * existing csum items that cover any of its blocks, we end up getting
	 * two csum items in our csum tree that overlap each other:
	 *
	 * key (EXTENT_CSUM EXTENT_CSUM 12845056) itemsize 100
	 * key (EXTENT_CSUM EXTENT_CSUM 12865536) itemsize 20
	 *
	 * Which is a problem, because after this anyone trying to lookup for
	 * the checksum of any block of our extent starting at an offset of 40K
	 * or higher, will end up looking at the second csum item only, which
	 * does not contain the checksum for any block starting at offset 40K or
	 * higher of our extent.
	 */
	while (!list_empty(&ordered_sums)) {
		struct btrfs_ordered_sum *sums;
		struct btrfs_root *csum_root;

		sums = list_first_entry(&ordered_sums, struct btrfs_ordered_sum, list);
		csum_root = btrfs_csum_root(fs_info, sums->logical);
		if (!ret) {
			ret = btrfs_del_csums(trans, csum_root, sums->logical,
					      sums->len);
			if (ret)
				btrfs_abort_log_replay(wc, ret,
	       "failed to delete csums for range [%llu, %llu) inode %llu root %llu",
						       sums->logical,
						       sums->logical + sums->len,
						       wc->log_key.objectid,
						       btrfs_root_id(root));
		}
		if (!ret) {
			ret = btrfs_csum_file_blocks(trans, csum_root, sums);
			if (ret)
				btrfs_abort_log_replay(wc, ret,
	       "failed to add csums for range [%llu, %llu) inode %llu root %llu",
						       sums->logical,
						       sums->logical + sums->len,
						       wc->log_key.objectid,
						       btrfs_root_id(root));
		}
		list_del(&sums->list);
		kfree(sums);
	}
	if (ret)
		goto out;

update_inode:
	ret = btrfs_inode_set_file_extent_range(inode, start, extent_end - start);
	if (ret) {
		btrfs_abort_log_replay(wc, ret,
	       "failed to set file extent range [%llu, %llu) inode %llu root %llu",
				       start, extent_end, wc->log_key.objectid,
				       btrfs_root_id(root));
		goto out;
	}

	btrfs_update_inode_bytes(inode, nbytes, drop_args.bytes_found);
	ret = btrfs_update_inode(trans, inode);
	if (ret)
		btrfs_abort_log_replay(wc, ret,
				       "failed to update inode %llu root %llu",
				       wc->log_key.objectid, btrfs_root_id(root));
out:
	iput(&inode->vfs_inode);
	return ret;
}

static int unlink_inode_for_log_replay(struct walk_control *wc,
				       struct btrfs_inode *dir,
				       struct btrfs_inode *inode,
				       const struct fscrypt_str *name)
{
	struct btrfs_trans_handle *trans = wc->trans;
	int ret;

	ret = btrfs_unlink_inode(trans, dir, inode, name);
	if (ret) {
		btrfs_abort_log_replay(wc, ret,
	       "failed to unlink inode %llu parent dir %llu name %.*s root %llu",
				       btrfs_ino(inode), btrfs_ino(dir), name->len,
				       name->name, btrfs_root_id(inode->root));
		return ret;
	}
	/*
	 * Whenever we need to check if a name exists or not, we check the
	 * fs/subvolume tree. So after an unlink we must run delayed items, so
	 * that future checks for a name during log replay see that the name
	 * does not exists anymore.
	 */
	ret = btrfs_run_delayed_items(trans);
	if (ret)
		btrfs_abort_log_replay(wc, ret,
"failed to run delayed items current inode %llu parent dir %llu name %.*s root %llu",
				       btrfs_ino(inode), btrfs_ino(dir), name->len,
				       name->name, btrfs_root_id(inode->root));

	return ret;
}

/*
 * when cleaning up conflicts between the directory names in the
 * subvolume, directory names in the log and directory names in the
 * inode back references, we may have to unlink inodes from directories.
 *
 * This is a helper function to do the unlink of a specific directory
 * item
 */
static noinline int drop_one_dir_item(struct walk_control *wc,
				      struct btrfs_inode *dir,
				      struct btrfs_dir_item *di)
{
	struct btrfs_root *root = dir->root;
	struct btrfs_inode *inode;
	struct fscrypt_str name;
	struct extent_buffer *leaf = wc->subvol_path->nodes[0];
	struct btrfs_key location;
	int ret;

	btrfs_dir_item_key_to_cpu(leaf, di, &location);
	ret = read_alloc_one_name(leaf, di + 1, btrfs_dir_name_len(leaf, di), &name);
	if (ret) {
		btrfs_abort_log_replay(wc, ret,
				       "failed to allocate name for dir %llu root %llu",
				       btrfs_ino(dir), btrfs_root_id(root));
		return ret;
	}

	btrfs_release_path(wc->subvol_path);

	inode = btrfs_iget_logging(location.objectid, root);
	if (IS_ERR(inode)) {
		ret = PTR_ERR(inode);
		btrfs_abort_log_replay(wc, ret,
		       "failed to open inode %llu parent dir %llu name %.*s root %llu",
				       location.objectid, btrfs_ino(dir),
				       name.len, name.name, btrfs_root_id(root));
		inode = NULL;
		goto out;
	}

	ret = link_to_fixup_dir(wc, location.objectid);
	if (ret)
		goto out;

	ret = unlink_inode_for_log_replay(wc, dir, inode, &name);
out:
	kfree(name.name);
	if (inode)
		iput(&inode->vfs_inode);
	return ret;
}

/*
 * See if a given name and sequence number found in an inode back reference are
 * already in a directory and correctly point to this inode.
 *
 * Returns: < 0 on error, 0 if the directory entry does not exists and 1 if it
 * exists.
 */
static noinline int inode_in_dir(struct btrfs_root *root,
				 struct btrfs_path *path,
				 u64 dirid, u64 objectid, u64 index,
				 struct fscrypt_str *name)
{
	struct btrfs_dir_item *di;
	struct btrfs_key location;
	int ret = 0;

	di = btrfs_lookup_dir_index_item(NULL, root, path, dirid,
					 index, name, 0);
	if (IS_ERR(di)) {
		ret = PTR_ERR(di);
		goto out;
	} else if (di) {
		btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
		if (location.objectid != objectid)
			goto out;
	} else {
		goto out;
	}

	btrfs_release_path(path);
	di = btrfs_lookup_dir_item(NULL, root, path, dirid, name, 0);
	if (IS_ERR(di)) {
		ret = PTR_ERR(di);
		goto out;
	} else if (di) {
		btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
		if (location.objectid == objectid)
			ret = 1;
	}
out:
	btrfs_release_path(path);
	return ret;
}

/*
 * helper function to check a log tree for a named back reference in
 * an inode.  This is used to decide if a back reference that is
 * found in the subvolume conflicts with what we find in the log.
 *
 * inode backreferences may have multiple refs in a single item,
 * during replay we process one reference at a time, and we don't
 * want to delete valid links to a file from the subvolume if that
 * link is also in the log.
 */
static noinline int backref_in_log(struct btrfs_root *log,
				   struct btrfs_key *key,
				   u64 ref_objectid,
				   const struct fscrypt_str *name)
{
	BTRFS_PATH_AUTO_FREE(path);
	int ret;

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

	ret = btrfs_search_slot(NULL, log, key, path, 0, 0);
	if (ret < 0)
		return ret;
	if (ret == 1)
		return 0;

	if (key->type == BTRFS_INODE_EXTREF_KEY)
		ret = !!btrfs_find_name_in_ext_backref(path->nodes[0],
						       path->slots[0],
						       ref_objectid, name);
	else
		ret = !!btrfs_find_name_in_backref(path->nodes[0],
						   path->slots[0], name);
	return ret;
}

static int unlink_refs_not_in_log(struct walk_control *wc,
				  struct btrfs_key *search_key,
				  struct btrfs_inode *dir,
				  struct btrfs_inode *inode)
{
	struct extent_buffer *leaf = wc->subvol_path->nodes[0];
	unsigned long ptr;
	unsigned long ptr_end;

	/*
	 * Check all the names in this back reference to see if they are in the
	 * log. If so, we allow them to stay otherwise they must be unlinked as
	 * a conflict.
	 */
	ptr = btrfs_item_ptr_offset(leaf, wc->subvol_path->slots[0]);
	ptr_end = ptr + btrfs_item_size(leaf, wc->subvol_path->slots[0]);
	while (ptr < ptr_end) {
		struct fscrypt_str victim_name;
		struct btrfs_inode_ref *victim_ref;
		int ret;

		victim_ref = (struct btrfs_inode_ref *)ptr;
		ret = read_alloc_one_name(leaf, (victim_ref + 1),
					  btrfs_inode_ref_name_len(leaf, victim_ref),
					  &victim_name);
		if (ret) {
			btrfs_abort_log_replay(wc, ret,
	       "failed to allocate name for inode %llu parent dir %llu root %llu",
					       btrfs_ino(inode), btrfs_ino(dir),
					       btrfs_root_id(inode->root));
			return ret;
		}

		ret = backref_in_log(wc->log, search_key, btrfs_ino(dir), &victim_name);
		if (ret) {
			if (ret < 0) {
				btrfs_abort_log_replay(wc, ret,
"failed to check if backref is in log tree for inode %llu parent dir %llu name %.*s root %llu",
						       btrfs_ino(inode), btrfs_ino(dir),
						       victim_name.len, victim_name.name,
						       btrfs_root_id(inode->root));
				kfree(victim_name.name);
				return ret;
			}
			kfree(victim_name.name);
			ptr = (unsigned long)(victim_ref + 1) + victim_name.len;
			continue;
		}

		inc_nlink(&inode->vfs_inode);
		btrfs_release_path(wc->subvol_path);

		ret = unlink_inode_for_log_replay(wc, dir, inode, &victim_name);
		kfree(victim_name.name);
		if (ret)
			return ret;
		return -EAGAIN;
	}

	return 0;
}

static int unlink_extrefs_not_in_log(struct walk_control *wc,
				     struct btrfs_key *search_key,
				     struct btrfs_inode *dir,
				     struct btrfs_inode *inode)
{
	struct extent_buffer *leaf = wc->subvol_path->nodes[0];
	const unsigned long base = btrfs_item_ptr_offset(leaf, wc->subvol_path->slots[0]);
	const u32 item_size = btrfs_item_size(leaf, wc->subvol_path->slots[0]);
	u32 cur_offset = 0;

	while (cur_offset < item_size) {
		struct btrfs_root *log_root = wc->log;
		struct btrfs_inode_extref *extref;
		struct fscrypt_str victim_name;
		int ret;

		extref = (struct btrfs_inode_extref *)(base + cur_offset);
		victim_name.len = btrfs_inode_extref_name_len(leaf, extref);

		if (btrfs_inode_extref_parent(leaf, extref) != btrfs_ino(dir))
			goto next;

		ret = read_alloc_one_name(leaf, &extref->name, victim_name.len,
					  &victim_name);
		if (ret) {
			btrfs_abort_log_replay(wc, ret,
	       "failed to allocate name for inode %llu parent dir %llu root %llu",
					       btrfs_ino(inode), btrfs_ino(dir),
					       btrfs_root_id(inode->root));
			return ret;
		}

		search_key->objectid = btrfs_ino(inode);
		search_key->type = BTRFS_INODE_EXTREF_KEY;
		search_key->offset = btrfs_extref_hash(btrfs_ino(dir),
						       victim_name.name,
						       victim_name.len);
		ret = backref_in_log(log_root, search_key, btrfs_ino(dir), &victim_name);
		if (ret) {
			if (ret < 0) {
				btrfs_abort_log_replay(wc, ret,
"failed to check if backref is in log tree for inode %llu parent dir %llu name %.*s root %llu",
						       btrfs_ino(inode), btrfs_ino(dir),
						       victim_name.len, victim_name.name,
						       btrfs_root_id(inode->root));
				kfree(victim_name.name);
				return ret;
			}
			kfree(victim_name.name);
next:
			cur_offset += victim_name.len + sizeof(*extref);
			continue;
		}

		inc_nlink(&inode->vfs_inode);
		btrfs_release_path(wc->subvol_path);

		ret = unlink_inode_for_log_replay(wc, dir, inode, &victim_name);
		kfree(victim_name.name);
		if (ret)
			return ret;
		return -EAGAIN;
	}

	return 0;
}

static inline int __add_inode_ref(struct walk_control *wc,
				  struct btrfs_inode *dir,
				  struct btrfs_inode *inode,
				  u64 ref_index, struct fscrypt_str *name)
{
	int ret;
	struct btrfs_trans_handle *trans = wc->trans;
	struct btrfs_root *root = wc->root;
	struct btrfs_dir_item *di;
	struct btrfs_key search_key;
	struct btrfs_inode_extref *extref;

again:
	/* Search old style refs */
	search_key.objectid = btrfs_ino(inode);
	search_key.type = BTRFS_INODE_REF_KEY;
	search_key.offset = btrfs_ino(dir);
	ret = btrfs_search_slot(NULL, root, &search_key, wc->subvol_path, 0, 0);
	if (ret < 0) {
		btrfs_abort_log_replay(wc, ret,
	       "failed to search subvolume tree for key (%llu %u %llu) root %llu",
				       search_key.objectid, search_key.type,
				       search_key.offset, btrfs_root_id(root));
		return ret;
	} else if (ret == 0) {
		/*
		 * Are we trying to overwrite a back ref for the root directory?
		 * If so, we're done.
		 */
		if (search_key.objectid == search_key.offset)
			return 1;

		ret = unlink_refs_not_in_log(wc, &search_key, dir, inode);
		if (ret == -EAGAIN)
			goto again;
		else if (ret)
			return ret;
	}
	btrfs_release_path(wc->subvol_path);

	/* Same search but for extended refs */
	extref = btrfs_lookup_inode_extref(root, wc->subvol_path, name,
					   btrfs_ino(inode), btrfs_ino(dir));
	if (IS_ERR(extref)) {
		return PTR_ERR(extref);
	} else if (extref) {
		ret = unlink_extrefs_not_in_log(wc, &search_key, dir, inode);
		if (ret == -EAGAIN)
			goto again;
		else if (ret)
			return ret;
	}
	btrfs_release_path(wc->subvol_path);

	/* look for a conflicting sequence number */
	di = btrfs_lookup_dir_index_item(trans, root, wc->subvol_path, btrfs_ino(dir),
					 ref_index, name, 0);
	if (IS_ERR(di)) {
		ret = PTR_ERR(di);
		btrfs_abort_log_replay(wc, ret,
"failed to lookup dir index item for dir %llu ref_index %llu name %.*s root %llu",
				       btrfs_ino(dir), ref_index, name->len,
				       name->name, btrfs_root_id(root));
		return ret;
	} else if (di) {
		ret = drop_one_dir_item(wc, dir, di);
		if (ret)
			return ret;
	}
	btrfs_release_path(wc->subvol_path);

	/* look for a conflicting name */
	di = btrfs_lookup_dir_item(trans, root, wc->subvol_path, btrfs_ino(dir), name, 0);
	if (IS_ERR(di)) {
		ret = PTR_ERR(di);
		btrfs_abort_log_replay(wc, ret,
	"failed to lookup dir item for dir %llu name %.*s root %llu",
				       btrfs_ino(dir), name->len, name->name,
				       btrfs_root_id(root));
		return ret;
	} else if (di) {
		ret = drop_one_dir_item(wc, dir, di);
		if (ret)
			return ret;
	}
	btrfs_release_path(wc->subvol_path);

	return 0;
}

static int extref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
			     struct fscrypt_str *name, u64 *index,
			     u64 *parent_objectid)
{
	struct btrfs_inode_extref *extref;
	int ret;

	extref = (struct btrfs_inode_extref *)ref_ptr;

	ret = read_alloc_one_name(eb, &extref->name,
				  btrfs_inode_extref_name_len(eb, extref), name);
	if (ret)
		return ret;

	if (index)
		*index = btrfs_inode_extref_index(eb, extref);
	if (parent_objectid)
		*parent_objectid = btrfs_inode_extref_parent(eb, extref);

	return 0;
}

static int ref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
			  struct fscrypt_str *name, u64 *index)
{
	struct btrfs_inode_ref *ref;
	int ret;

	ref = (struct btrfs_inode_ref *)ref_ptr;

	ret = read_alloc_one_name(eb, ref + 1, btrfs_inode_ref_name_len(eb, ref),
				  name);
	if (ret)
		return ret;

	if (index)
		*index = btrfs_inode_ref_index(eb, ref);

	return 0;
}

/*
 * Take an inode reference item from the log tree and iterate all names from the
 * inode reference item in the subvolume tree with the same key (if it exists).
 * For any name that is not in the inode reference item from the log tree, do a
 * proper unlink of that name (that is, remove its entry from the inode
 * reference item and both dir index keys).
 */
static int unlink_old_inode_refs(struct walk_control *wc, struct btrfs_inode *inode)
{
	struct btrfs_root *root = wc->root;
	int ret;
	unsigned long ref_ptr;
	unsigned long ref_end;
	struct extent_buffer *eb;

again:
	btrfs_release_path(wc->subvol_path);
	ret = btrfs_search_slot(NULL, root, &wc->log_key, wc->subvol_path, 0, 0);
	if (ret > 0) {
		ret = 0;
		goto out;
	}
	if (ret < 0) {
		btrfs_abort_log_replay(wc, ret,
	       "failed to search subvolume tree for key (%llu %u %llu) root %llu",
				       wc->log_key.objectid, wc->log_key.type,
				       wc->log_key.offset, btrfs_root_id(root));
		goto out;
	}

	eb = wc->subvol_path->nodes[0];
	ref_ptr = btrfs_item_ptr_offset(eb, wc->subvol_path->slots[0]);
	ref_end = ref_ptr + btrfs_item_size(eb, wc->subvol_path->slots[0]);
	while (ref_ptr < ref_end) {
		struct fscrypt_str name;
		u64 parent_id;

		if (wc->log_key.type == BTRFS_INODE_EXTREF_KEY) {
			ret = extref_get_fields(eb, ref_ptr, &name,
						NULL, &parent_id);
			if (ret) {
				btrfs_abort_log_replay(wc, ret,
			       "failed to get extref details for inode %llu root %llu",
						       btrfs_ino(inode),
						       btrfs_root_id(root));
				goto out;
			}
		} else {
			parent_id = wc->log_key.offset;
			ret = ref_get_fields(eb, ref_ptr, &name, NULL);
			if (ret) {
				btrfs_abort_log_replay(wc, ret,
	       "failed to get ref details for inode %llu parent_id %llu root %llu",
						       btrfs_ino(inode), parent_id,
						       btrfs_root_id(root));
				goto out;
			}
		}

		if (wc->log_key.type == BTRFS_INODE_EXTREF_KEY)
			ret = !!btrfs_find_name_in_ext_backref(wc->log_leaf, wc->log_slot,
							       parent_id, &name);
		else
			ret = !!btrfs_find_name_in_backref(wc->log_leaf, wc->log_slot,
							   &name);

		if (!ret) {
			struct btrfs_inode *dir;

			btrfs_release_path(wc->subvol_path);
			dir = btrfs_iget_logging(parent_id, root);
			if (IS_ERR(dir)) {
				ret = PTR_ERR(dir);
				kfree(name.name);
				btrfs_abort_log_replay(wc, ret,
				       "failed to lookup dir inode %llu root %llu",
						       parent_id, btrfs_root_id(root));
				goto out;
			}
			ret = unlink_inode_for_log_replay(wc, dir, inode, &name);
			kfree(name.name);
			iput(&dir->vfs_inode);
			if (ret)
				goto out;
			goto again;
		}

		kfree(name.name);
		ref_ptr += name.len;
		if (wc->log_key.type == BTRFS_INODE_EXTREF_KEY)
			ref_ptr += sizeof(struct btrfs_inode_extref);
		else
			ref_ptr += sizeof(struct btrfs_inode_ref);
	}
	ret = 0;
 out:
	btrfs_release_path(wc->subvol_path);
	return ret;
}

/*
 * Replay one inode back reference item found in the log tree.
 * Path is for temporary use by this function (it should be released on return).
 */
static noinline int add_inode_ref(struct walk_control *wc)
{
	struct btrfs_trans_handle *trans = wc->trans;
	struct btrfs_root *root = wc->root;
	struct btrfs_inode *dir = NULL;
	struct btrfs_inode *inode = NULL;
	unsigned long ref_ptr;
	unsigned long ref_end;
	struct fscrypt_str name = { 0 };
	int ret;
	const bool is_extref_item = (wc->log_key.type == BTRFS_INODE_EXTREF_KEY);
	u64 parent_objectid;
	u64 inode_objectid;
	u64 ref_index = 0;
	int ref_struct_size;

	ref_ptr = btrfs_item_ptr_offset(wc->log_leaf, wc->log_slot);
	ref_end = ref_ptr + btrfs_item_size(wc->log_leaf, wc->log_slot);

	if (is_extref_item) {
		struct btrfs_inode_extref *r;

		ref_struct_size = sizeof(struct btrfs_inode_extref);
		r = (struct btrfs_inode_extref *)ref_ptr;
		parent_objectid = btrfs_inode_extref_parent(wc->log_leaf, r);
	} else {
		ref_struct_size = sizeof(struct btrfs_inode_ref);
		parent_objectid = wc->log_key.offset;
	}
	inode_objectid = wc->log_key.objectid;

	/*
	 * it is possible that we didn't log all the parent directories
	 * for a given inode.  If we don't find the dir, just don't
	 * copy the back ref in.  The link count fixup code will take
	 * care of the rest
	 */
	dir = btrfs_iget_logging(parent_objectid, root);
	if (IS_ERR(dir)) {
		ret = PTR_ERR(dir);
		if (ret == -ENOENT)
			ret = 0;
		else
			btrfs_abort_log_replay(wc, ret,
			       "failed to lookup dir inode %llu root %llu",
					       parent_objectid, btrfs_root_id(root));
		dir = NULL;
		goto out;
	}

	inode = btrfs_iget_logging(inode_objectid, root);
	if (IS_ERR(inode)) {
		ret = PTR_ERR(inode);
		btrfs_abort_log_replay(wc, ret,
				       "failed to lookup inode %llu root %llu",
				       inode_objectid, btrfs_root_id(root));
		inode = NULL;
		goto out;
	}

	while (ref_ptr < ref_end) {
		if (is_extref_item) {
			ret = extref_get_fields(wc->log_leaf, ref_ptr, &name,
						&ref_index, &parent_objectid);
			if (ret) {
				btrfs_abort_log_replay(wc, ret,
			       "failed to get extref details for inode %llu root %llu",
						       btrfs_ino(inode),
						       btrfs_root_id(root));
				goto out;
			}
			/*
			 * parent object can change from one array
			 * item to another.
			 */
			if (!dir) {
				dir = btrfs_iget_logging(parent_objectid, root);
				if (IS_ERR(dir)) {
					ret = PTR_ERR(dir);
					dir = NULL;
					/*
					 * A new parent dir may have not been
					 * logged and not exist in the subvolume
					 * tree, see the comment above before
					 * the loop when getting the first
					 * parent dir.
					 */
					if (ret == -ENOENT) {
						/*
						 * The next extref may refer to
						 * another parent dir that
						 * exists, so continue.
						 */
						ret = 0;
						goto next;
					} else {
						btrfs_abort_log_replay(wc, ret,
				       "failed to lookup dir inode %llu root %llu",
								       parent_objectid,
								       btrfs_root_id(root));
					}
					goto out;
				}
			}
		} else {
			ret = ref_get_fields(wc->log_leaf, ref_ptr, &name, &ref_index);
			if (ret) {
				btrfs_abort_log_replay(wc, ret,
	"failed to get ref details for inode %llu parent_objectid %llu root %llu",
						       btrfs_ino(inode),
						       parent_objectid,
						       btrfs_root_id(root));
				goto out;
			}
		}

		ret = inode_in_dir(root, wc->subvol_path, btrfs_ino(dir),
				   btrfs_ino(inode), ref_index, &name);
		if (ret < 0) {
			btrfs_abort_log_replay(wc, ret,
"failed to check if inode %llu is in dir %llu ref_index %llu name %.*s root %llu",
					       btrfs_ino(inode), btrfs_ino(dir),
					       ref_index, name.len, name.name,
					       btrfs_root_id(root));
			goto out;
		} else if (ret == 0) {
			/*
			 * look for a conflicting back reference in the
			 * metadata. if we find one we have to unlink that name
			 * of the file before we add our new link.  Later on, we
			 * overwrite any existing back reference, and we don't
			 * want to create dangling pointers in the directory.
			 */
			ret = __add_inode_ref(wc, dir, inode, ref_index, &name);
			if (ret) {
				if (ret == 1)
					ret = 0;
				goto out;
			}

			/* insert our name */
			ret = btrfs_add_link(trans, dir, inode, &name, 0, ref_index);
			if (ret) {
				btrfs_abort_log_replay(wc, ret,
"failed to add link for inode %llu in dir %llu ref_index %llu name %.*s root %llu",
						       btrfs_ino(inode),
						       btrfs_ino(dir), ref_index,
						       name.len, name.name,
						       btrfs_root_id(root));
				goto out;
			}

			ret = btrfs_update_inode(trans, inode);
			if (ret) {
				btrfs_abort_log_replay(wc, ret,
				       "failed to update inode %llu root %llu",
						       btrfs_ino(inode),
						       btrfs_root_id(root));
				goto out;
			}
		}
		/* Else, ret == 1, we already have a perfect match, we're done. */

next:
		ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + name.len;
		kfree(name.name);
		name.name = NULL;
		if (is_extref_item && dir) {
			iput(&dir->vfs_inode);
			dir = NULL;
		}
	}

	/*
	 * Before we overwrite the inode reference item in the subvolume tree
	 * with the item from the log tree, we must unlink all names from the
	 * parent directory that are in the subvolume's tree inode reference
	 * item, otherwise we end up with an inconsistent subvolume tree where
	 * dir index entries exist for a name but there is no inode reference
	 * item with the same name.
	 */
	ret = unlink_old_inode_refs(wc, inode);
	if (ret)
		goto out;

	/* finally write the back reference in the inode */
	ret = overwrite_item(wc);
out:
	btrfs_release_path(wc->subvol_path);
	kfree(name.name);
	if (dir)
		iput(&dir->vfs_inode);
	if (inode)
		iput(&inode->vfs_inode);
	return ret;
}

static int count_inode_extrefs(struct btrfs_inode *inode, struct btrfs_path *path)
{
	int ret = 0;
	int name_len;
	unsigned int nlink = 0;
	u32 item_size;
	u32 cur_offset = 0;
	u64 inode_objectid = btrfs_ino(inode);
	u64 offset = 0;
	unsigned long ptr;
	struct btrfs_inode_extref *extref;
	struct extent_buffer *leaf;

	while (1) {
		ret = btrfs_find_one_extref(inode->root, inode_objectid, offset,
					    path, &extref, &offset);
		if (ret)
			break;

		leaf = path->nodes[0];
		item_size = btrfs_item_size(leaf, path->slots[0]);
		ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
		cur_offset = 0;

		while (cur_offset < item_size) {
			extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
			name_len = btrfs_inode_extref_name_len(leaf, extref);

			nlink++;

			cur_offset += name_len + sizeof(*extref);
		}

		offset++;
		btrfs_release_path(path);
	}
	btrfs_release_path(path);

	if (ret < 0 && ret != -ENOENT)
		return ret;
	return nlink;
}

static int count_inode_refs(struct btrfs_inode *inode, struct btrfs_path *path)
{
	int ret;
	struct btrfs_key key;
	unsigned int nlink = 0;
	unsigned long ptr;
	unsigned long ptr_end;
	int name_len;
	u64 ino = btrfs_ino(inode);

	key.objectid = ino;
	key.type = BTRFS_INODE_REF_KEY;
	key.offset = (u64)-1;

	while (1) {
		ret = btrfs_search_slot(NULL, inode->root, &key, path, 0, 0);
		if (ret < 0)
			break;
		if (ret > 0) {
			if (path->slots[0] == 0)
				break;
			path->slots[0]--;
		}
process_slot:
		btrfs_item_key_to_cpu(path->nodes[0], &key,
				      path->slots[0]);
		if (key.objectid != ino ||
		    key.type != BTRFS_INODE_REF_KEY)
			break;
		ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]);
		ptr_end = ptr + btrfs_item_size(path->nodes[0],
						   path->slots[0]);
		while (ptr < ptr_end) {
			struct btrfs_inode_ref *ref;

			ref = (struct btrfs_inode_ref *)ptr;
			name_len = btrfs_inode_ref_name_len(path->nodes[0],
							    ref);
			ptr = (unsigned long)(ref + 1) + name_len;
			nlink++;
		}

		if (key.offset == 0)
			break;
		if (path->slots[0] > 0) {
			path->slots[0]--;
			goto process_slot;
		}
		key.offset--;
		btrfs_release_path(path);
	}
	btrfs_release_path(path);

	return nlink;
}

/*
 * There are a few corners where the link count of the file can't
 * be properly maintained during replay.  So, instead of adding
 * lots of complexity to the log code, we just scan the backrefs
 * for any file that has been through replay.
 *
 * The scan will update the link count on the inode to reflect the
 * number of back refs found.  If it goes down to zero, the iput
 * will free the inode.
 */
static noinline int fixup_inode_link_count(struct walk_control *wc,
					   struct btrfs_inode *inode)
{
	struct btrfs_trans_handle *trans = wc->trans;
	struct btrfs_root *root = inode->root;
	int ret;
	u64 nlink = 0;
	const u64 ino = btrfs_ino(inode);

	ret = count_inode_refs(inode, wc->subvol_path);
	if (ret < 0)
		goto out;

	nlink = ret;

	ret = count_inode_extrefs(inode, wc->subvol_path);
	if (ret < 0)
		goto out;

	nlink += ret;

	ret = 0;

	if (nlink != inode->vfs_inode.i_nlink) {
		set_nlink(&inode->vfs_inode, nlink);
		ret = btrfs_update_inode(trans, inode);
		if (ret)
			goto out;
	}
	if (S_ISDIR(inode->vfs_inode.i_mode))
		inode->index_cnt = (u64)-1;

	if (inode->vfs_inode.i_nlink == 0) {
		if (S_ISDIR(inode->vfs_inode.i_mode)) {
			ret = replay_dir_deletes(wc, ino, true);
			if (ret)
				goto out;
		}
		ret = btrfs_insert_orphan_item(trans, root, ino);
		if (ret == -EEXIST)
			ret = 0;
	}

out:
	btrfs_release_path(wc->subvol_path);
	return ret;
}

static noinline int fixup_inode_link_counts(struct walk_control *wc)
{
	int ret;
	struct btrfs_key key;

	key.objectid = BTRFS_TREE_LOG_FIXUP_OBJECTID;
	key.type = BTRFS_ORPHAN_ITEM_KEY;
	key.offset = (u64)-1;
	while (1) {
		struct btrfs_trans_handle *trans = wc->trans;
		struct btrfs_root *root = wc->root;
		struct btrfs_inode *inode;

		ret = btrfs_search_slot(trans, root, &key, wc->subvol_path, -1, 1);
		if (ret < 0)
			break;

		if (ret == 1) {
			ret = 0;
			if (wc->subvol_path->slots[0] == 0)
				break;
			wc->subvol_path->slots[0]--;
		}

		btrfs_item_key_to_cpu(wc->subvol_path->nodes[0], &key, wc->subvol_path->slots[0]);
		if (key.objectid != BTRFS_TREE_LOG_FIXUP_OBJECTID ||
		    key.type != BTRFS_ORPHAN_ITEM_KEY)
			break;

		ret = btrfs_del_item(trans, root, wc->subvol_path);
		if (ret)
			break;

		btrfs_release_path(wc->subvol_path);
		inode = btrfs_iget_logging(key.offset, root);
		if (IS_ERR(inode)) {
			ret = PTR_ERR(inode);
			break;
		}

		ret = fixup_inode_link_count(wc, inode);
		iput(&inode->vfs_inode);
		if (ret)
			break;

		/*
		 * fixup on a directory may create new entries,
		 * make sure we always look for the highest possible
		 * offset
		 */
		key.offset = (u64)-1;
	}
	btrfs_release_path(wc->subvol_path);
	return ret;
}


/*
 * record a given inode in the fixup dir so we can check its link
 * count when replay is done.  The link count is incremented here
 * so the inode won't go away until we check it
 */
static noinline int link_to_fixup_dir(struct walk_control *wc, u64 objectid)
{
	struct btrfs_trans_handle *trans = wc->trans;
	struct btrfs_root *root = wc->root;
	struct btrfs_key key;
	int ret = 0;
	struct btrfs_inode *inode;
	struct inode *vfs_inode;

	inode = btrfs_iget_logging(objectid, root);
	if (IS_ERR(inode)) {
		ret = PTR_ERR(inode);
		btrfs_abort_log_replay(wc, ret,
				       "failed to lookup inode %llu root %llu",
				       objectid, btrfs_root_id(root));
		return ret;
	}

	vfs_inode = &inode->vfs_inode;
	key.objectid = BTRFS_TREE_LOG_FIXUP_OBJECTID;
	key.type = BTRFS_ORPHAN_ITEM_KEY;
	key.offset = objectid;

	ret = btrfs_insert_empty_item(trans, root, wc->subvol_path, &key, 0);

	btrfs_release_path(wc->subvol_path);
	if (ret == 0) {
		if (!vfs_inode->i_nlink)
			set_nlink(vfs_inode, 1);
		else
			inc_nlink(vfs_inode);
		ret = btrfs_update_inode(trans, inode);
		if (ret)
			btrfs_abort_log_replay(wc, ret,
				       "failed to update inode %llu root %llu",
					       objectid, btrfs_root_id(root));
	} else if (ret == -EEXIST) {
		ret = 0;
	} else {
		btrfs_abort_log_replay(wc, ret,
		       "failed to insert fixup item for inode %llu root %llu",
				       objectid, btrfs_root_id(root));
	}
	iput(vfs_inode);

	return ret;
}

/*
 * when replaying the log for a directory, we only insert names
 * for inodes that actually exist.  This means an fsync on a directory
 * does not implicitly fsync all the new files in it
 */
static noinline int insert_one_name(struct btrfs_trans_handle *trans,
				    struct btrfs_root *root,
				    u64 dirid, u64 index,
				    const struct fscrypt_str *name,
				    struct btrfs_key *location)
{
	struct btrfs_inode *inode;
	struct btrfs_inode *dir;
	int ret;

	inode = btrfs_iget_logging(location->objectid, root);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	dir = btrfs_iget_logging(dirid, root);
	if (IS_ERR(dir)) {
		iput(&inode->vfs_inode);
		return PTR_ERR(dir);
	}

	ret = btrfs_add_link(trans, dir, inode, name, 1, index);

	/* FIXME, put inode into FIXUP list */

	iput(&inode->vfs_inode);
	iput(&dir->vfs_inode);
	return ret;
}

static int delete_conflicting_dir_entry(struct walk_control *wc,
					struct btrfs_inode *dir,
					struct btrfs_dir_item *dst_di,
					const struct btrfs_key *log_key,
					u8 log_flags,
					bool exists)
{
	struct btrfs_key found_key;

	btrfs_dir_item_key_to_cpu(wc->subvol_path->nodes[0], dst_di, &found_key);
	/* The existing dentry points to the same inode, don't delete it. */
	if (found_key.objectid == log_key->objectid &&
	    found_key.type == log_key->type &&
	    found_key.offset == log_key->offset &&
	    btrfs_dir_flags(wc->subvol_path->nodes[0], dst_di) == log_flags)
		return 1;

	/*
	 * Don't drop the conflicting directory entry if the inode for the new
	 * entry doesn't exist.
	 */
	if (!exists)
		return 0;

	return drop_one_dir_item(wc, dir, dst_di);
}

/*
 * take a single entry in a log directory item and replay it into
 * the subvolume.
 *
 * if a conflicting item exists in the subdirectory already,
 * the inode it points to is unlinked and put into the link count
 * fix up tree.
 *
 * If a name from the log points to a file or directory that does
 * not exist in the FS, it is skipped.  fsyncs on directories
 * do not force down inodes inside that directory, just changes to the
 * names or unlinks in a directory.
 *
 * Returns < 0 on error, 0 if the name wasn't replayed (dentry points to a
 * non-existing inode) and 1 if the name was replayed.
 */
static noinline int replay_one_name(struct walk_control *wc, struct btrfs_dir_item *di)
{
	struct btrfs_trans_handle *trans = wc->trans;
	struct btrfs_root *root = wc->root;
	struct fscrypt_str name = { 0 };
	struct btrfs_dir_item *dir_dst_di;
	struct btrfs_dir_item *index_dst_di;
	bool dir_dst_matches = false;
	bool index_dst_matches = false;
	struct btrfs_key log_key;
	struct btrfs_key search_key;
	struct btrfs_inode *dir;
	u8 log_flags;
	bool exists;
	int ret;
	bool update_size = true;
	bool name_added = false;

	dir = btrfs_iget_logging(wc->log_key.objectid, root);
	if (IS_ERR(dir)) {
		ret = PTR_ERR(dir);
		btrfs_abort_log_replay(wc, ret,
				       "failed to lookup dir inode %llu root %llu",
				       wc->log_key.objectid, btrfs_root_id(root));
		return ret;
	}

	ret = read_alloc_one_name(wc->log_leaf, di + 1,
				  btrfs_dir_name_len(wc->log_leaf, di), &name);
	if (ret) {
		btrfs_abort_log_replay(wc, ret,
			       "failed to allocate name for dir %llu root %llu",
				       btrfs_ino(dir), btrfs_root_id(root));
		goto out;
	}

	log_flags = btrfs_dir_flags(wc->log_leaf, di);
	btrfs_dir_item_key_to_cpu(wc->log_leaf, di, &log_key);
	ret = btrfs_lookup_inode(trans, root, wc->subvol_path, &log_key, 0);
	btrfs_release_path(wc->subvol_path);
	if (ret < 0) {
		btrfs_abort_log_replay(wc, ret,
				       "failed to lookup inode %llu root %llu",
				       log_key.objectid, btrfs_root_id(root));
		goto out;
	}
	exists = (ret == 0);
	ret = 0;

	dir_dst_di = btrfs_lookup_dir_item(trans, root, wc->subvol_path,
					   wc->log_key.objectid, &name, 1);
	if (IS_ERR(dir_dst_di)) {
		ret = PTR_ERR(dir_dst_di);
		btrfs_abort_log_replay(wc, ret,
		       "failed to lookup dir item for dir %llu name %.*s root %llu",
				       wc->log_key.objectid, name.len, name.name,
				       btrfs_root_id(root));
		goto out;
	} else if (dir_dst_di) {
		ret = delete_conflicting_dir_entry(wc, dir, dir_dst_di,
						   &log_key, log_flags, exists);
		if (ret < 0) {
			btrfs_abort_log_replay(wc, ret,
	       "failed to delete conflicting entry for dir %llu name %.*s root %llu",
					       btrfs_ino(dir), name.len, name.name,
					       btrfs_root_id(root));
			goto out;
		}
		dir_dst_matches = (ret == 1);
	}

	btrfs_release_path(wc->subvol_path);

	index_dst_di = btrfs_lookup_dir_index_item(trans, root, wc->subvol_path,
						   wc->log_key.objectid,
						   wc->log_key.offset, &name, 1);
	if (IS_ERR(index_dst_di)) {
		ret = PTR_ERR(index_dst_di);
		btrfs_abort_log_replay(wc, ret,
	       "failed to lookup dir index item for dir %llu name %.*s root %llu",
				       wc->log_key.objectid, name.len, name.name,
				       btrfs_root_id(root));
		goto out;
	} else if (index_dst_di) {
		ret = delete_conflicting_dir_entry(wc, dir, index_dst_di,
						   &log_key, log_flags, exists);
		if (ret < 0) {
			btrfs_abort_log_replay(wc, ret,
	       "failed to delete conflicting entry for dir %llu name %.*s root %llu",
					       btrfs_ino(dir), name.len, name.name,
					       btrfs_root_id(root));
			goto out;
		}
		index_dst_matches = (ret == 1);
	}

	btrfs_release_path(wc->subvol_path);

	if (dir_dst_matches && index_dst_matches) {
		ret = 0;
		update_size = false;
		goto out;
	}

	/*
	 * Check if the inode reference exists in the log for the given name,
	 * inode and parent inode
	 */
	search_key.objectid = log_key.objectid;
	search_key.type = BTRFS_INODE_REF_KEY;
	search_key.offset = wc->log_key.objectid;
	ret = backref_in_log(root->log_root, &search_key, 0, &name);
	if (ret < 0) {
		btrfs_abort_log_replay(wc, ret,
"failed to check if ref item is logged for inode %llu dir %llu name %.*s root %llu",
				       search_key.objectid, btrfs_ino(dir),
				       name.len, name.name, btrfs_root_id(root));
	        goto out;
	} else if (ret) {
	        /* The dentry will be added later. */
	        ret = 0;
	        update_size = false;
	        goto out;
	}

	search_key.objectid = log_key.objectid;
	search_key.type = BTRFS_INODE_EXTREF_KEY;
	search_key.offset = btrfs_extref_hash(wc->log_key.objectid, name.name, name.len);
	ret = backref_in_log(root->log_root, &search_key, wc->log_key.objectid, &name);
	if (ret < 0) {
		btrfs_abort_log_replay(wc, ret,
"failed to check if extref item is logged for inode %llu dir %llu name %.*s root %llu",
				       search_key.objectid, btrfs_ino(dir),
				       name.len, name.name, btrfs_root_id(root));
		goto out;
	} else if (ret) {
		/* The dentry will be added later. */
		ret = 0;
		update_size = false;
		goto out;
	}
	ret = insert_one_name(trans, root, wc->log_key.objectid, wc->log_key.offset,
			      &name, &log_key);
	if (ret && ret != -ENOENT && ret != -EEXIST) {
		btrfs_abort_log_replay(wc, ret,
		       "failed to insert name %.*s for inode %llu dir %llu root %llu",
				       name.len, name.name, log_key.objectid,
				       btrfs_ino(dir), btrfs_root_id(root));
		goto out;
	}
	if (!ret)
		name_added = true;
	update_size = false;
	ret = 0;

out:
	if (!ret && update_size) {
		btrfs_i_size_write(dir, dir->vfs_inode.i_size + name.len * 2);
		ret = btrfs_update_inode(trans, dir);
		if (ret)
			btrfs_abort_log_replay(wc, ret,
				       "failed to update dir inode %llu root %llu",
					       btrfs_ino(dir), btrfs_root_id(root));
	}
	kfree(name.name);
	iput(&dir->vfs_inode);
	if (!ret && name_added)
		ret = 1;
	return ret;
}

/* Replay one dir item from a BTRFS_DIR_INDEX_KEY key. */
static noinline int replay_one_dir_item(struct walk_control *wc)
{
	int ret;
	struct btrfs_dir_item *di;

	/* We only log dir index keys, which only contain a single dir item. */
	ASSERT(wc->log_key.type == BTRFS_DIR_INDEX_KEY);

	di = btrfs_item_ptr(wc->log_leaf, wc->log_slot, struct btrfs_dir_item);
	ret = replay_one_name(wc, di);
	if (ret < 0)
		return ret;

	/*
	 * If this entry refers to a non-directory (directories can not have a
	 * link count > 1) and it was added in the transaction that was not
	 * committed, make sure we fixup the link count of the inode the entry
	 * points to. Otherwise something like the following would result in a
	 * directory pointing to an inode with a wrong link that does not account
	 * for this dir entry:
	 *
	 * mkdir testdir
	 * touch testdir/foo
	 * touch testdir/bar
	 * sync
	 *
	 * ln testdir/bar testdir/bar_link
	 * ln testdir/foo testdir/foo_link
	 * xfs_io -c "fsync" testdir/bar
	 *
	 * <power failure>
	 *
	 * mount fs, log replay happens
	 *
	 * File foo would remain with a link count of 1 when it has two entries
	 * pointing to it in the directory testdir. This would make it impossible
	 * to ever delete the parent directory has it would result in stale
	 * dentries that can never be deleted.
	 */
	if (ret == 1 && btrfs_dir_ftype(wc->log_leaf, di) != BTRFS_FT_DIR) {
		struct btrfs_key di_key;

		btrfs_dir_item_key_to_cpu(wc->log_leaf, di, &di_key);
		ret = link_to_fixup_dir(wc, di_key.objectid);
	}

	return ret;
}

/*
 * directory replay has two parts.  There are the standard directory
 * items in the log copied from the subvolume, and range items
 * created in the log while the subvolume was logged.
 *
 * The range items tell us which parts of the key space the log
 * is authoritative for.  During replay, if a key in the subvolume
 * directory is in a logged range item, but not actually in the log
 * that means it was deleted from the directory before the fsync
 * and should be removed.
 */
static noinline int find_dir_range(struct btrfs_root *root,
				   struct btrfs_path *path,
				   u64 dirid,
				   u64 *start_ret, u64 *end_ret)
{
	struct btrfs_key key;
	u64 found_end;
	struct btrfs_dir_log_item *item;
	int ret;
	int nritems;

	if (*start_ret == (u64)-1)
		return 1;

	key.objectid = dirid;
	key.type = BTRFS_DIR_LOG_INDEX_KEY;
	key.offset = *start_ret;

	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	if (ret < 0)
		goto out;
	if (ret > 0) {
		if (path->slots[0] == 0)
			goto out;
		path->slots[0]--;
	}
	if (ret != 0)
		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);

	if (key.type != BTRFS_DIR_LOG_INDEX_KEY || key.objectid != dirid) {
		ret = 1;
		goto next;
	}
	item = btrfs_item_ptr(path->nodes[0], path->slots[0],
			      struct btrfs_dir_log_item);
	found_end = btrfs_dir_log_end(path->nodes[0], item);

	if (*start_ret >= key.offset && *start_ret <= found_end) {
		ret = 0;
		*start_ret = key.offset;
		*end_ret = found_end;
		goto out;
	}
	ret = 1;
next:
	/* check the next slot in the tree to see if it is a valid item */
	nritems = btrfs_header_nritems(path->nodes[0]);
	path->slots[0]++;
	if (path->slots[0] >= nritems) {
		ret = btrfs_next_leaf(root, path);
		if (ret)
			goto out;
	}

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

	if (key.type != BTRFS_DIR_LOG_INDEX_KEY || key.objectid != dirid) {
		ret = 1;
		goto out;
	}
	item = btrfs_item_ptr(path->nodes[0], path->slots[0],
			      struct btrfs_dir_log_item);
	found_end = btrfs_dir_log_end(path->nodes[0], item);
	*start_ret = key.offset;
	*end_ret = found_end;
	ret = 0;
out:
	btrfs_release_path(path);
	return ret;
}

/*
 * this looks for a given directory item in the log.  If the directory
 * item is not in the log, the item is removed and the inode it points
 * to is unlinked
 */
static noinline int check_item_in_log(struct walk_control *wc,
				      struct btrfs_path *log_path,
				      struct btrfs_inode *dir,
				      struct btrfs_key *dir_key,
				      bool force_remove)
{
	struct btrfs_trans_handle *trans = wc->trans;
	struct btrfs_root *root = dir->root;
	int ret;
	struct extent_buffer *eb;
	int slot;
	struct btrfs_dir_item *di;
	struct fscrypt_str name = { 0 };
	struct btrfs_inode *inode = NULL;
	struct btrfs_key location;

	/*
	 * Currently we only log dir index keys. Even if we replay a log created
	 * by an older kernel that logged both dir index and dir item keys, all
	 * we need to do is process the dir index keys, we (and our caller) can
	 * safely ignore dir item keys (key type BTRFS_DIR_ITEM_KEY).
	 */
	ASSERT(dir_key->type == BTRFS_DIR_INDEX_KEY);

	eb = wc->subvol_path->nodes[0];
	slot = wc->subvol_path->slots[0];
	di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item);
	ret = read_alloc_one_name(eb, di + 1, btrfs_dir_name_len(eb, di), &name);
	if (ret) {
		btrfs_abort_log_replay(wc, ret,
		       "failed to allocate name for dir %llu index %llu root %llu",
				       btrfs_ino(dir), dir_key->offset,
				       btrfs_root_id(root));
		goto out;
	}

	if (!force_remove) {
		struct btrfs_dir_item *log_di;

		log_di = btrfs_lookup_dir_index_item(trans, wc->log, log_path,
						     dir_key->objectid,
						     dir_key->offset, &name, 0);
		if (IS_ERR(log_di)) {
			ret = PTR_ERR(log_di);
			btrfs_abort_log_replay(wc, ret,
	"failed to lookup dir index item for dir %llu index %llu name %.*s root %llu",
					       btrfs_ino(dir), dir_key->offset,
					       name.len, name.name,
					       btrfs_root_id(root));
			goto out;
		} else if (log_di) {
			/* The dentry exists in the log, we have nothing to do. */
			ret = 0;
			goto out;
		}
	}

	btrfs_dir_item_key_to_cpu(eb, di, &location);
	btrfs_release_path(wc->subvol_path);
	btrfs_release_path(log_path);
	inode = btrfs_iget_logging(location.objectid, root);
	if (IS_ERR(inode)) {
		ret = PTR_ERR(inode);
		inode = NULL;
		btrfs_abort_log_replay(wc, ret,
				       "failed to lookup inode %llu root %llu",
				       location.objectid, btrfs_root_id(root));
		goto out;
	}

	ret = link_to_fixup_dir(wc, location.objectid);
	if (ret)
		goto out;

	inc_nlink(&inode->vfs_inode);
	ret = unlink_inode_for_log_replay(wc, dir, inode, &name);
	/*
	 * Unlike dir item keys, dir index keys can only have one name (entry) in
	 * them, as there are no key collisions since each key has a unique offset
	 * (an index number), so we're done.
	 */
out:
	btrfs_release_path(wc->subvol_path);
	btrfs_release_path(log_path);
	kfree(name.name);
	if (inode)
		iput(&inode->vfs_inode);
	return ret;
}

static int replay_xattr_deletes(struct walk_control *wc)
{
	struct btrfs_trans_handle *trans = wc->trans;
	struct btrfs_root *root = wc->root;
	struct btrfs_root *log = wc->log;
	struct btrfs_key search_key;
	BTRFS_PATH_AUTO_FREE(log_path);
	const u64 ino = wc->log_key.objectid;
	int nritems;
	int ret;

	log_path = btrfs_alloc_path();
	if (!log_path) {
		btrfs_abort_log_replay(wc, -ENOMEM, "failed to allocate path");
		return -ENOMEM;
	}

	search_key.objectid = ino;
	search_key.type = BTRFS_XATTR_ITEM_KEY;
	search_key.offset = 0;
again:
	ret = btrfs_search_slot(NULL, root, &search_key, wc->subvol_path, 0, 0);
	if (ret < 0) {
		btrfs_abort_log_replay(wc, ret,
			       "failed to search xattrs for inode %llu root %llu",
				       ino, btrfs_root_id(root));
		goto out;
	}
process_leaf:
	nritems = btrfs_header_nritems(wc->subvol_path->nodes[0]);
	for (int i = wc->subvol_path->slots[0]; i < nritems; i++) {
		struct btrfs_key key;
		struct btrfs_dir_item *di;
		struct btrfs_dir_item *log_di;
		u32 total_size;
		u32 cur;

		btrfs_item_key_to_cpu(wc->subvol_path->nodes[0], &key, i);
		if (key.objectid != ino || key.type != BTRFS_XATTR_ITEM_KEY) {
			ret = 0;
			goto out;
		}

		di = btrfs_item_ptr(wc->subvol_path->nodes[0], i, struct btrfs_dir_item);
		total_size = btrfs_item_size(wc->subvol_path->nodes[0], i);
		cur = 0;
		while (cur < total_size) {
			u16 name_len = btrfs_dir_name_len(wc->subvol_path->nodes[0], di);
			u16 data_len = btrfs_dir_data_len(wc->subvol_path->nodes[0], di);
			u32 this_len = sizeof(*di) + name_len + data_len;
			char *name;

			name = kmalloc(name_len, GFP_NOFS);
			if (!name) {
				ret = -ENOMEM;
				btrfs_abort_log_replay(wc, ret,
				       "failed to allocate memory for name of length %u",
						       name_len);
				goto out;
			}
			read_extent_buffer(wc->subvol_path->nodes[0], name,
					   (unsigned long)(di + 1), name_len);

			log_di = btrfs_lookup_xattr(NULL, log, log_path, ino,
						    name, name_len, 0);
			btrfs_release_path(log_path);
			if (!log_di) {
				/* Doesn't exist in log tree, so delete it. */
				btrfs_release_path(wc->subvol_path);
				di = btrfs_lookup_xattr(trans, root, wc->subvol_path, ino,
							name, name_len, -1);
				if (IS_ERR(di)) {
					ret = PTR_ERR(di);
					btrfs_abort_log_replay(wc, ret,
		       "failed to lookup xattr with name %.*s for inode %llu root %llu",
							       name_len, name, ino,
							       btrfs_root_id(root));
					kfree(name);
					goto out;
				}
				ASSERT(di);
				ret = btrfs_delete_one_dir_name(trans, root,
								wc->subvol_path, di);
				if (ret) {
					btrfs_abort_log_replay(wc, ret,
		       "failed to delete xattr with name %.*s for inode %llu root %llu",
							       name_len, name, ino,
							       btrfs_root_id(root));
					kfree(name);
					goto out;
				}
				btrfs_release_path(wc->subvol_path);
				kfree(name);
				search_key = key;
				goto again;
			}
			if (IS_ERR(log_di)) {
				ret = PTR_ERR(log_di);
				btrfs_abort_log_replay(wc, ret,
	"failed to lookup xattr in log tree with name %.*s for inode %llu root %llu",
						       name_len, name, ino,
						       btrfs_root_id(root));
				kfree(name);
				goto out;
			}
			kfree(name);
			cur += this_len;
			di = (struct btrfs_dir_item *)((char *)di + this_len);
		}
	}
	ret = btrfs_next_leaf(root, wc->subvol_path);
	if (ret > 0)
		ret = 0;
	else if (ret == 0)
		goto process_leaf;
	else
		btrfs_abort_log_replay(wc, ret,
			       "failed to get next leaf in subvolume root %llu",
				       btrfs_root_id(root));
out:
	btrfs_release_path(wc->subvol_path);
	return ret;
}


/*
 * deletion replay happens before we copy any new directory items
 * out of the log or out of backreferences from inodes.  It
 * scans the log to find ranges of keys that log is authoritative for,
 * and then scans the directory to find items in those ranges that are
 * not present in the log.
 *
 * Anything we don't find in the log is unlinked and removed from the
 * directory.
 */
static noinline int replay_dir_deletes(struct walk_control *wc,
				       u64 dirid, bool del_all)
{
	struct btrfs_root *root = wc->root;
	struct btrfs_root *log = (del_all ? NULL : wc->log);
	u64 range_start;
	u64 range_end;
	int ret = 0;
	struct btrfs_key dir_key;
	struct btrfs_key found_key;
	struct btrfs_path *log_path;
	struct btrfs_inode *dir;

	dir_key.objectid = dirid;
	dir_key.type = BTRFS_DIR_INDEX_KEY;
	log_path = btrfs_alloc_path();
	if (!log_path) {
		btrfs_abort_log_replay(wc, -ENOMEM, "failed to allocate path");
		return -ENOMEM;
	}

	dir = btrfs_iget_logging(dirid, root);
	/*
	 * It isn't an error if the inode isn't there, that can happen because
	 * we replay the deletes before we copy in the inode item from the log.
	 */
	if (IS_ERR(dir)) {
		btrfs_free_path(log_path);
		ret = PTR_ERR(dir);
		if (ret == -ENOENT)
			ret = 0;
		else
			btrfs_abort_log_replay(wc, ret,
			       "failed to lookup dir inode %llu root %llu",
					       dirid, btrfs_root_id(root));
		return ret;
	}

	range_start = 0;
	range_end = 0;
	while (1) {
		if (del_all)
			range_end = (u64)-1;
		else {
			ret = find_dir_range(log, wc->subvol_path, dirid,
					     &range_start, &range_end);
			if (ret < 0) {
				btrfs_abort_log_replay(wc, ret,
			       "failed to find range for dir %llu in log tree root %llu",
						       dirid, btrfs_root_id(root));
				goto out;
			} else if (ret > 0) {
				break;
			}
		}

		dir_key.offset = range_start;
		while (1) {
			int nritems;
			ret = btrfs_search_slot(NULL, root, &dir_key,
						wc->subvol_path, 0, 0);
			if (ret < 0) {
				btrfs_abort_log_replay(wc, ret,
			       "failed to search root %llu for key (%llu %u %llu)",
						       btrfs_root_id(root),
						       dir_key.objectid, dir_key.type,
						       dir_key.offset);
				goto out;
			}

			nritems = btrfs_header_nritems(wc->subvol_path->nodes[0]);
			if (wc->subvol_path->slots[0] >= nritems) {
				ret = btrfs_next_leaf(root, wc->subvol_path);
				if (ret == 1) {
					break;
				} else if (ret < 0) {
					btrfs_abort_log_replay(wc, ret,
				       "failed to get next leaf in subvolume root %llu",
							       btrfs_root_id(root));
					goto out;
				}
			}
			btrfs_item_key_to_cpu(wc->subvol_path->nodes[0], &found_key,
					      wc->subvol_path->slots[0]);
			if (found_key.objectid != dirid ||
			    found_key.type != dir_key.type) {
				ret = 0;
				goto out;
			}

			if (found_key.offset > range_end)
				break;

			ret = check_item_in_log(wc, log_path, dir, &found_key, del_all);
			if (ret)
				goto out;
			if (found_key.offset == (u64)-1)
				break;
			dir_key.offset = found_key.offset + 1;
		}
		btrfs_release_path(wc->subvol_path);
		if (range_end == (u64)-1)
			break;
		range_start = range_end + 1;
	}
	ret = 0;
out:
	btrfs_release_path(wc->subvol_path);
	btrfs_free_path(log_path);
	iput(&dir->vfs_inode);
	return ret;
}

/*
 * the process_func used to replay items from the log tree.  This
 * gets called in two different stages.  The first stage just looks
 * for inodes and makes sure they are all copied into the subvolume.
 *
 * The second stage copies all the other item types from the log into
 * the subvolume.  The two stage approach is slower, but gets rid of
 * lots of complexity around inodes referencing other inodes that exist
 * only in the log (references come from either directory items or inode
 * back refs).
 */
static int replay_one_buffer(struct extent_buffer *eb,
			     struct walk_control *wc, u64 gen, int level)
{
	int nritems;
	struct btrfs_tree_parent_check check = {
		.transid = gen,
		.level = level
	};
	struct btrfs_root *root = wc->root;
	struct btrfs_trans_handle *trans = wc->trans;
	int ret;

	if (level != 0)
		return 0;

	/*
	 * Set to NULL since it was not yet read and in case we abort log replay
	 * on error, we have no valid log tree leaf to dump.
	 */
	wc->log_leaf = NULL;
	ret = btrfs_read_extent_buffer(eb, &check);
	if (ret) {
		btrfs_abort_log_replay(wc, ret,
		       "failed to read log tree leaf %llu for root %llu",
				       eb->start, btrfs_root_id(root));
		return ret;
	}

	ASSERT(wc->subvol_path == NULL);
	wc->subvol_path = btrfs_alloc_path();
	if (!wc->subvol_path) {
		btrfs_abort_log_replay(wc, -ENOMEM, "failed to allocate path");
		return -ENOMEM;
	}

	wc->log_leaf = eb;

	nritems = btrfs_header_nritems(eb);
	for (wc->log_slot = 0; wc->log_slot < nritems; wc->log_slot++) {
		struct btrfs_inode_item *inode_item = NULL;

		btrfs_item_key_to_cpu(eb, &wc->log_key, wc->log_slot);

		if (wc->log_key.type == BTRFS_INODE_ITEM_KEY) {
			inode_item = btrfs_item_ptr(eb, wc->log_slot,
						    struct btrfs_inode_item);
			/*
			 * An inode with no links is either:
			 *
			 * 1) A tmpfile (O_TMPFILE) that got fsync'ed and never
			 *    got linked before the fsync, skip it, as replaying
			 *    it is pointless since it would be deleted later.
			 *    We skip logging tmpfiles, but it's always possible
			 *    we are replaying a log created with a kernel that
			 *    used to log tmpfiles;
			 *
			 * 2) A non-tmpfile which got its last link deleted
			 *    while holding an open fd on it and later got
			 *    fsynced through that fd. We always log the
			 *    parent inodes when inode->last_unlink_trans is
			 *    set to the current transaction, so ignore all the
			 *    inode items for this inode. We will delete the
			 *    inode when processing the parent directory with
			 *    replay_dir_deletes().
			 */
			if (btrfs_inode_nlink(eb, inode_item) == 0) {
				wc->ignore_cur_inode = true;
				continue;
			} else {
				wc->ignore_cur_inode = false;
			}
		}

		/* Inode keys are done during the first stage. */
		if (wc->log_key.type == BTRFS_INODE_ITEM_KEY &&
		    wc->stage == LOG_WALK_REPLAY_INODES) {
			u32 mode;

			ret = replay_xattr_deletes(wc);
			if (ret)
				break;
			mode = btrfs_inode_mode(eb, inode_item);
			if (S_ISDIR(mode)) {
				ret = replay_dir_deletes(wc, wc->log_key.objectid, false);
				if (ret)
					break;
			}
			ret = overwrite_item(wc);
			if (ret)
				break;

			/*
			 * Before replaying extents, truncate the inode to its
			 * size. We need to do it now and not after log replay
			 * because before an fsync we can have prealloc extents
			 * added beyond the inode's i_size. If we did it after,
			 * through orphan cleanup for example, we would drop
			 * those prealloc extents just after replaying them.
			 */
			if (S_ISREG(mode)) {
				struct btrfs_drop_extents_args drop_args = { 0 };
				struct btrfs_inode *inode;
				u64 from;

				inode = btrfs_iget_logging(wc->log_key.objectid, root);
				if (IS_ERR(inode)) {
					ret = PTR_ERR(inode);
					btrfs_abort_log_replay(wc, ret,
					       "failed to lookup inode %llu root %llu",
							       wc->log_key.objectid,
							       btrfs_root_id(root));
					break;
				}
				from = ALIGN(i_size_read(&inode->vfs_inode),
					     root->fs_info->sectorsize);
				drop_args.start = from;
				drop_args.end = (u64)-1;
				drop_args.drop_cache = true;
				drop_args.path = wc->subvol_path;
				ret = btrfs_drop_extents(trans, root, inode,  &drop_args);
				if (ret) {
					btrfs_abort_log_replay(wc, ret,
		       "failed to drop extents for inode %llu root %llu offset %llu",
							       btrfs_ino(inode),
							       btrfs_root_id(root),
							       from);
				} else {
					inode_sub_bytes(&inode->vfs_inode,
							drop_args.bytes_found);
					/* Update the inode's nbytes. */
					ret = btrfs_update_inode(trans, inode);
					if (ret)
						btrfs_abort_log_replay(wc, ret,
					       "failed to update inode %llu root %llu",
								       btrfs_ino(inode),
								       btrfs_root_id(root));
				}
				iput(&inode->vfs_inode);
				if (ret)
					break;
			}

			ret = link_to_fixup_dir(wc, wc->log_key.objectid);
			if (ret)
				break;
		}

		if (wc->ignore_cur_inode)
			continue;

		if (wc->log_key.type == BTRFS_DIR_INDEX_KEY &&
		    wc->stage == LOG_WALK_REPLAY_DIR_INDEX) {
			ret = replay_one_dir_item(wc);
			if (ret)
				break;
		}

		if (wc->stage < LOG_WALK_REPLAY_ALL)
			continue;

		/* these keys are simply copied */
		if (wc->log_key.type == BTRFS_XATTR_ITEM_KEY) {
			ret = overwrite_item(wc);
			if (ret)
				break;
		} else if (wc->log_key.type == BTRFS_INODE_REF_KEY ||
			   wc->log_key.type == BTRFS_INODE_EXTREF_KEY) {
			ret = add_inode_ref(wc);
			if (ret)
				break;
		} else if (wc->log_key.type == BTRFS_EXTENT_DATA_KEY) {
			ret = replay_one_extent(wc);
			if (ret)
				break;
		}
		/*
		 * We don't log BTRFS_DIR_ITEM_KEY keys anymore, only the
		 * BTRFS_DIR_INDEX_KEY items which we use to derive the
		 * BTRFS_DIR_ITEM_KEY items. If we are replaying a log from an
		 * older kernel with such keys, ignore them.
		 */
	}
	btrfs_free_path(wc->subvol_path);
	wc->subvol_path = NULL;
	return ret;
}

static int clean_log_buffer(struct btrfs_trans_handle *trans,
			    struct extent_buffer *eb)
{
	struct btrfs_fs_info *fs_info = eb->fs_info;
	struct btrfs_block_group *bg;

	btrfs_tree_lock(eb);
	btrfs_clear_buffer_dirty(trans, eb);
	wait_on_extent_buffer_writeback(eb);
	btrfs_tree_unlock(eb);

	if (trans) {
		int ret;

		ret = btrfs_pin_reserved_extent(trans, eb);
		if (ret)
			btrfs_abort_transaction(trans, ret);
		return ret;
	}

	bg = btrfs_lookup_block_group(fs_info, eb->start);
	if (!bg) {
		btrfs_err(fs_info, "unable to find block group for %llu", eb->start);
		btrfs_handle_fs_error(fs_info, -ENOENT, NULL);
		return -ENOENT;
	}

	spin_lock(&bg->space_info->lock);
	spin_lock(&bg->lock);
	bg->reserved -= fs_info->nodesize;
	bg->space_info->bytes_reserved -= fs_info->nodesize;
	spin_unlock(&bg->lock);
	spin_unlock(&bg->space_info->lock);

	btrfs_put_block_group(bg);

	return 0;
}

static noinline int walk_down_log_tree(struct btrfs_path *path, int *level,
				       struct walk_control *wc)
{
	struct btrfs_trans_handle *trans = wc->trans;
	struct btrfs_fs_info *fs_info = wc->log->fs_info;
	u64 bytenr;
	u64 ptr_gen;
	struct extent_buffer *next;
	struct extent_buffer *cur;
	int ret = 0;

	while (*level > 0) {
		struct btrfs_tree_parent_check check = { 0 };

		cur = path->nodes[*level];

		WARN_ON(btrfs_header_level(cur) != *level);

		if (path->slots[*level] >=
		    btrfs_header_nritems(cur))
			break;

		bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
		ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]);
		check.transid = ptr_gen;
		check.level = *level - 1;
		check.has_first_key = true;
		btrfs_node_key_to_cpu(cur, &check.first_key, path->slots[*level]);

		next = btrfs_find_create_tree_block(fs_info, bytenr,
						    btrfs_header_owner(cur),
						    *level - 1);
		if (IS_ERR(next)) {
			ret = PTR_ERR(next);
			if (trans)
				btrfs_abort_transaction(trans, ret);
			else
				btrfs_handle_fs_error(fs_info, ret, NULL);
			return ret;
		}

		if (*level == 1) {
			ret = wc->process_func(next, wc, ptr_gen, *level - 1);
			if (ret) {
				free_extent_buffer(next);
				return ret;
			}

			path->slots[*level]++;
			if (wc->free) {
				ret = btrfs_read_extent_buffer(next, &check);
				if (ret) {
					free_extent_buffer(next);
					if (trans)
						btrfs_abort_transaction(trans, ret);
					else
						btrfs_handle_fs_error(fs_info, ret, NULL);
					return ret;
				}

				ret = clean_log_buffer(trans, next);
				if (ret) {
					free_extent_buffer(next);
					return ret;
				}
			}
			free_extent_buffer(next);
			continue;
		}
		ret = btrfs_read_extent_buffer(next, &check);
		if (ret) {
			free_extent_buffer(next);
			if (trans)
				btrfs_abort_transaction(trans, ret);
			else
				btrfs_handle_fs_error(fs_info, ret, NULL);
			return ret;
		}

		if (path->nodes[*level-1])
			free_extent_buffer(path->nodes[*level-1]);
		path->nodes[*level-1] = next;
		*level = btrfs_header_level(next);
		path->slots[*level] = 0;
		cond_resched();
	}
	path->slots[*level] = btrfs_header_nritems(path->nodes[*level]);

	cond_resched();
	return 0;
}

static noinline int walk_up_log_tree(struct btrfs_path *path, int *level,
				     struct walk_control *wc)
{
	int i;
	int slot;
	int ret;

	for (i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) {
		slot = path->slots[i];
		if (slot + 1 < btrfs_header_nritems(path->nodes[i])) {
			path->slots[i]++;
			*level = i;
			WARN_ON(*level == 0);
			return 0;
		} else {
			ret = wc->process_func(path->nodes[*level], wc,
				 btrfs_header_generation(path->nodes[*level]),
				 *level);
			if (ret)
				return ret;

			if (wc->free) {
				ret = clean_log_buffer(wc->trans, path->nodes[*level]);
				if (ret)
					return ret;
			}
			free_extent_buffer(path->nodes[*level]);
			path->nodes[*level] = NULL;
			*level = i + 1;
		}
	}
	return 1;
}

/*
 * drop the reference count on the tree rooted at 'snap'.  This traverses
 * the tree freeing any blocks that have a ref count of zero after being
 * decremented.
 */
static int walk_log_tree(struct walk_control *wc)
{
	struct btrfs_root *log = wc->log;
	int ret = 0;
	int wret;
	int level;
	BTRFS_PATH_AUTO_FREE(path);
	int orig_level;

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

	level = btrfs_header_level(log->node);
	orig_level = level;
	path->nodes[level] = log->node;
	refcount_inc(&log->node->refs);
	path->slots[level] = 0;

	while (1) {
		wret = walk_down_log_tree(path, &level, wc);
		if (wret > 0)
			break;
		if (wret < 0)
			return wret;

		wret = walk_up_log_tree(path, &level, wc);
		if (wret > 0)
			break;
		if (wret < 0)
			return wret;
	}

	/* was the root node processed? if not, catch it here */
	if (path->nodes[orig_level]) {
		ret = wc->process_func(path->nodes[orig_level], wc,
			 btrfs_header_generation(path->nodes[orig_level]),
			 orig_level);
		if (ret)
			return ret;
		if (wc->free)
			ret = clean_log_buffer(wc->trans, path->nodes[orig_level]);
	}

	return ret;
}

/*
 * helper function to update the item for a given subvolumes log root
 * in the tree of log roots
 */
static int update_log_root(struct btrfs_trans_handle *trans,
			   struct btrfs_root *log,
			   struct btrfs_root_item *root_item)
{
	struct btrfs_fs_info *fs_info = log->fs_info;
	int ret;

	if (log->log_transid == 1) {
		/* insert root item on the first sync */
		ret = btrfs_insert_root(trans, fs_info->log_root_tree,
				&log->root_key, root_item);
	} else {
		ret = btrfs_update_root(trans, fs_info->log_root_tree,
				&log->root_key, root_item);
	}
	return ret;
}

static void wait_log_commit(struct btrfs_root *root, int transid)
{
	DEFINE_WAIT(wait);
	int index = transid % 2;

	/*
	 * we only allow two pending log transactions at a time,
	 * so we know that if ours is more than 2 older than the
	 * current transaction, we're done
	 */
	for (;;) {
		prepare_to_wait(&root->log_commit_wait[index],
				&wait, TASK_UNINTERRUPTIBLE);

		if (!(root->log_transid_committed < transid &&
		      atomic_read(&root->log_commit[index])))
			break;

		mutex_unlock(&root->log_mutex);
		schedule();
		mutex_lock(&root->log_mutex);
	}
	finish_wait(&root->log_commit_wait[index], &wait);
}

static void wait_for_writer(struct btrfs_root *root)
{
	DEFINE_WAIT(wait);

	for (;;) {
		prepare_to_wait(&root->log_writer_wait, &wait,
				TASK_UNINTERRUPTIBLE);
		if (!atomic_read(&root->log_writers))
			break;

		mutex_unlock(&root->log_mutex);
		schedule();
		mutex_lock(&root->log_mutex);
	}
	finish_wait(&root->log_writer_wait, &wait);
}

void btrfs_init_log_ctx(struct btrfs_log_ctx *ctx, struct btrfs_inode *inode)
{
	ctx->log_ret = 0;
	ctx->log_transid = 0;
	ctx->log_new_dentries = false;
	ctx->logging_new_name = false;
	ctx->logging_new_delayed_dentries = false;
	ctx->logged_before = false;
	ctx->inode = inode;
	INIT_LIST_HEAD(&ctx->list);
	INIT_LIST_HEAD(&ctx->ordered_extents);
	INIT_LIST_HEAD(&ctx->conflict_inodes);
	ctx->num_conflict_inodes = 0;
	ctx->logging_conflict_inodes = false;
	ctx->scratch_eb = NULL;
}

void btrfs_init_log_ctx_scratch_eb(struct btrfs_log_ctx *ctx)
{
	struct btrfs_inode *inode = ctx->inode;

	if (!test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags) &&
	    !test_bit(BTRFS_INODE_COPY_EVERYTHING, &inode->runtime_flags))
		return;

	/*
	 * Don't care about allocation failure. This is just for optimization,
	 * if we fail to allocate here, we will try again later if needed.
	 */
	ctx->scratch_eb = alloc_dummy_extent_buffer(inode->root->fs_info, 0);
}

void btrfs_release_log_ctx_extents(struct btrfs_log_ctx *ctx)
{
	struct btrfs_ordered_extent *ordered;
	struct btrfs_ordered_extent *tmp;

	btrfs_assert_inode_locked(ctx->inode);

	list_for_each_entry_safe(ordered, tmp, &ctx->ordered_extents, log_list) {
		list_del_init(&ordered->log_list);
		btrfs_put_ordered_extent(ordered);
	}
}


static inline void btrfs_remove_log_ctx(struct btrfs_root *root,
					struct btrfs_log_ctx *ctx)
{
	mutex_lock(&root->log_mutex);
	list_del_init(&ctx->list);
	mutex_unlock(&root->log_mutex);
}

/* 
 * Invoked in log mutex context, or be sure there is no other task which
 * can access the list.
 */
static inline void btrfs_remove_all_log_ctxs(struct btrfs_root *root,
					     int index, int error)
{
	struct btrfs_log_ctx *ctx;
	struct btrfs_log_ctx *safe;

	list_for_each_entry_safe(ctx, safe, &root->log_ctxs[index], list) {
		list_del_init(&ctx->list);
		ctx->log_ret = error;
	}
}

/*
 * Sends a given tree log down to the disk and updates the super blocks to
 * record it.  When this call is done, you know that any inodes previously
 * logged are safely on disk only if it returns 0.
 *
 * Any other return value means you need to call btrfs_commit_transaction.
 * Some of the edge cases for fsyncing directories that have had unlinks
 * or renames done in the past mean that sometimes the only safe
 * fsync is to commit the whole FS.  When btrfs_sync_log returns -EAGAIN,
 * that has happened.
 */
int btrfs_sync_log(struct btrfs_trans_handle *trans,
		   struct btrfs_root *root, struct btrfs_log_ctx *ctx)
{
	int index1;
	int index2;
	int mark;
	int ret;
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_root *log = root->log_root;
	struct btrfs_root *log_root_tree = fs_info->log_root_tree;
	struct btrfs_root_item new_root_item;
	int log_transid = 0;
	struct btrfs_log_ctx root_log_ctx;
	struct blk_plug plug;
	u64 log_root_start;
	u64 log_root_level;

	mutex_lock(&root->log_mutex);
	log_transid = ctx->log_transid;
	if (root->log_transid_committed >= log_transid) {
		mutex_unlock(&root->log_mutex);
		return ctx->log_ret;
	}

	index1 = log_transid % 2;
	if (atomic_read(&root->log_commit[index1])) {
		wait_log_commit(root, log_transid);
		mutex_unlock(&root->log_mutex);
		return ctx->log_ret;
	}
	ASSERT(log_transid == root->log_transid);
	atomic_set(&root->log_commit[index1], 1);

	/* wait for previous tree log sync to complete */
	if (atomic_read(&root->log_commit[(index1 + 1) % 2]))
		wait_log_commit(root, log_transid - 1);

	while (1) {
		int batch = atomic_read(&root->log_batch);
		/* when we're on an ssd, just kick the log commit out */
		if (!btrfs_test_opt(fs_info, SSD) &&
		    test_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state)) {
			mutex_unlock(&root->log_mutex);
			schedule_timeout_uninterruptible(1);
			mutex_lock(&root->log_mutex);
		}
		wait_for_writer(root);
		if (batch == atomic_read(&root->log_batch))
			break;
	}

	/* bail out if we need to do a full commit */
	if (btrfs_need_log_full_commit(trans)) {
		ret = BTRFS_LOG_FORCE_COMMIT;
		mutex_unlock(&root->log_mutex);
		goto out;
	}

	if (log_transid % 2 == 0)
		mark = EXTENT_DIRTY_LOG1;
	else
		mark = EXTENT_DIRTY_LOG2;

	/* we start IO on  all the marked extents here, but we don't actually
	 * wait for them until later.
	 */
	blk_start_plug(&plug);
	ret = btrfs_write_marked_extents(fs_info, &log->dirty_log_pages, mark);
	/*
	 * -EAGAIN happens when someone, e.g., a concurrent transaction
	 *  commit, writes a dirty extent in this tree-log commit. This
	 *  concurrent write will create a hole writing out the extents,
	 *  and we cannot proceed on a zoned filesystem, requiring
	 *  sequential writing. While we can bail out to a full commit
	 *  here, but we can continue hoping the concurrent writing fills
	 *  the hole.
	 */
	if (ret == -EAGAIN && btrfs_is_zoned(fs_info))
		ret = 0;
	if (ret) {
		blk_finish_plug(&plug);
		btrfs_set_log_full_commit(trans);
		mutex_unlock(&root->log_mutex);
		goto out;
	}

	/*
	 * We _must_ update under the root->log_mutex in order to make sure we
	 * have a consistent view of the log root we are trying to commit at
	 * this moment.
	 *
	 * We _must_ copy this into a local copy, because we are not holding the
	 * log_root_tree->log_mutex yet.  This is important because when we
	 * commit the log_root_tree we must have a consistent view of the
	 * log_root_tree when we update the super block to point at the
	 * log_root_tree bytenr.  If we update the log_root_tree here we'll race
	 * with the commit and possibly point at the new block which we may not
	 * have written out.
	 */
	btrfs_set_root_node(&log->root_item, log->node);
	memcpy(&new_root_item, &log->root_item, sizeof(new_root_item));

	btrfs_set_root_log_transid(root, root->log_transid + 1);
	log->log_transid = root->log_transid;
	root->log_start_pid = 0;
	/*
	 * IO has been started, blocks of the log tree have WRITTEN flag set
	 * in their headers. new modifications of the log will be written to
	 * new positions. so it's safe to allow log writers to go in.
	 */
	mutex_unlock(&root->log_mutex);

	if (btrfs_is_zoned(fs_info)) {
		mutex_lock(&fs_info->tree_root->log_mutex);
		if (!log_root_tree->node) {
			ret = btrfs_alloc_log_tree_node(trans, log_root_tree);
			if (ret) {
				mutex_unlock(&fs_info->tree_root->log_mutex);
				blk_finish_plug(&plug);
				goto out;
			}
		}
		mutex_unlock(&fs_info->tree_root->log_mutex);
	}

	btrfs_init_log_ctx(&root_log_ctx, NULL);

	mutex_lock(&log_root_tree->log_mutex);

	index2 = log_root_tree->log_transid % 2;
	list_add_tail(&root_log_ctx.list, &log_root_tree->log_ctxs[index2]);
	root_log_ctx.log_transid = log_root_tree->log_transid;

	/*
	 * Now we are safe to update the log_root_tree because we're under the
	 * log_mutex, and we're a current writer so we're holding the commit
	 * open until we drop the log_mutex.
	 */
	ret = update_log_root(trans, log, &new_root_item);
	if (ret) {
		list_del_init(&root_log_ctx.list);
		blk_finish_plug(&plug);
		btrfs_set_log_full_commit(trans);
		if (ret != -ENOSPC)
			btrfs_err(fs_info,
				  "failed to update log for root %llu ret %d",
				  btrfs_root_id(root), ret);
		btrfs_wait_tree_log_extents(log, mark);
		mutex_unlock(&log_root_tree->log_mutex);
		goto out;
	}

	if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) {
		blk_finish_plug(&plug);
		list_del_init(&root_log_ctx.list);
		mutex_unlock(&log_root_tree->log_mutex);
		ret = root_log_ctx.log_ret;
		goto out;
	}

	if (atomic_read(&log_root_tree->log_commit[index2])) {
		blk_finish_plug(&plug);
		ret = btrfs_wait_tree_log_extents(log, mark);
		wait_log_commit(log_root_tree,
				root_log_ctx.log_transid);
		mutex_unlock(&log_root_tree->log_mutex);
		if (!ret)
			ret = root_log_ctx.log_ret;
		goto out;
	}
	ASSERT(root_log_ctx.log_transid == log_root_tree->log_transid);
	atomic_set(&log_root_tree->log_commit[index2], 1);

	if (atomic_read(&log_root_tree->log_commit[(index2 + 1) % 2])) {
		wait_log_commit(log_root_tree,
				root_log_ctx.log_transid - 1);
	}

	/*
	 * now that we've moved on to the tree of log tree roots,
	 * check the full commit flag again
	 */
	if (btrfs_need_log_full_commit(trans)) {
		blk_finish_plug(&plug);
		btrfs_wait_tree_log_extents(log, mark);
		mutex_unlock(&log_root_tree->log_mutex);
		ret = BTRFS_LOG_FORCE_COMMIT;
		goto out_wake_log_root;
	}

	ret = btrfs_write_marked_extents(fs_info,
					 &log_root_tree->dirty_log_pages,
					 EXTENT_DIRTY_LOG1 | EXTENT_DIRTY_LOG2);
	blk_finish_plug(&plug);
	/*
	 * As described above, -EAGAIN indicates a hole in the extents. We
	 * cannot wait for these write outs since the waiting cause a
	 * deadlock. Bail out to the full commit instead.
	 */
	if (ret == -EAGAIN && btrfs_is_zoned(fs_info)) {
		btrfs_set_log_full_commit(trans);
		btrfs_wait_tree_log_extents(log, mark);
		mutex_unlock(&log_root_tree->log_mutex);
		goto out_wake_log_root;
	} else if (ret) {
		btrfs_set_log_full_commit(trans);
		mutex_unlock(&log_root_tree->log_mutex);
		goto out_wake_log_root;
	}
	ret = btrfs_wait_tree_log_extents(log, mark);
	if (!ret)
		ret = btrfs_wait_tree_log_extents(log_root_tree,
						  EXTENT_DIRTY_LOG1 | EXTENT_DIRTY_LOG2);
	if (ret) {
		btrfs_set_log_full_commit(trans);
		mutex_unlock(&log_root_tree->log_mutex);
		goto out_wake_log_root;
	}

	log_root_start = log_root_tree->node->start;
	log_root_level = btrfs_header_level(log_root_tree->node);
	log_root_tree->log_transid++;
	mutex_unlock(&log_root_tree->log_mutex);

	/*
	 * Here we are guaranteed that nobody is going to write the superblock
	 * for the current transaction before us and that neither we do write
	 * our superblock before the previous transaction finishes its commit
	 * and writes its superblock, because:
	 *
	 * 1) We are holding a handle on the current transaction, so no body
	 *    can commit it until we release the handle;
	 *
	 * 2) Before writing our superblock we acquire the tree_log_mutex, so
	 *    if the previous transaction is still committing, and hasn't yet
	 *    written its superblock, we wait for it to do it, because a
	 *    transaction commit acquires the tree_log_mutex when the commit
	 *    begins and releases it only after writing its superblock.
	 */
	mutex_lock(&fs_info->tree_log_mutex);

	/*
	 * The previous transaction writeout phase could have failed, and thus
	 * marked the fs in an error state.  We must not commit here, as we
	 * could have updated our generation in the super_for_commit and
	 * writing the super here would result in transid mismatches.  If there
	 * is an error here just bail.
	 */
	if (BTRFS_FS_ERROR(fs_info)) {
		ret = -EIO;
		btrfs_set_log_full_commit(trans);
		btrfs_abort_transaction(trans, ret);
		mutex_unlock(&fs_info->tree_log_mutex);
		goto out_wake_log_root;
	}

	btrfs_set_super_log_root(fs_info->super_for_commit, log_root_start);
	btrfs_set_super_log_root_level(fs_info->super_for_commit, log_root_level);
	ret = write_all_supers(fs_info, 1);
	mutex_unlock(&fs_info->tree_log_mutex);
	if (unlikely(ret)) {
		btrfs_set_log_full_commit(trans);
		btrfs_abort_transaction(trans, ret);
		goto out_wake_log_root;
	}

	/*
	 * We know there can only be one task here, since we have not yet set
	 * root->log_commit[index1] to 0 and any task attempting to sync the
	 * log must wait for the previous log transaction to commit if it's
	 * still in progress or wait for the current log transaction commit if
	 * someone else already started it. We use <= and not < because the
	 * first log transaction has an ID of 0.
	 */
	ASSERT(btrfs_get_root_last_log_commit(root) <= log_transid);
	btrfs_set_root_last_log_commit(root, log_transid);

out_wake_log_root:
	mutex_lock(&log_root_tree->log_mutex);
	btrfs_remove_all_log_ctxs(log_root_tree, index2, ret);

	log_root_tree->log_transid_committed++;
	atomic_set(&log_root_tree->log_commit[index2], 0);
	mutex_unlock(&log_root_tree->log_mutex);

	/*
	 * The barrier before waitqueue_active (in cond_wake_up) is needed so
	 * all the updates above are seen by the woken threads. It might not be
	 * necessary, but proving that seems to be hard.
	 */
	cond_wake_up(&log_root_tree->log_commit_wait[index2]);
out:
	mutex_lock(&root->log_mutex);
	btrfs_remove_all_log_ctxs(root, index1, ret);
	root->log_transid_committed++;
	atomic_set(&root->log_commit[index1], 0);
	mutex_unlock(&root->log_mutex);

	/*
	 * The barrier before waitqueue_active (in cond_wake_up) is needed so
	 * all the updates above are seen by the woken threads. It might not be
	 * necessary, but proving that seems to be hard.
	 */
	cond_wake_up(&root->log_commit_wait[index1]);
	return ret;
}

static void free_log_tree(struct btrfs_trans_handle *trans,
			  struct btrfs_root *log)
{
	int ret;
	struct walk_control wc = {
		.free = true,
		.process_func = process_one_buffer,
		.log = log,
		.trans = trans,
	};

	if (log->node) {
		ret = walk_log_tree(&wc);
		if (ret) {
			/*
			 * We weren't able to traverse the entire log tree, the
			 * typical scenario is getting an -EIO when reading an
			 * extent buffer of the tree, due to a previous writeback
			 * failure of it.
			 */
			set_bit(BTRFS_FS_STATE_LOG_CLEANUP_ERROR,
				&log->fs_info->fs_state);

			/*
			 * Some extent buffers of the log tree may still be dirty
			 * and not yet written back to storage, because we may
			 * have updates to a log tree without syncing a log tree,
			 * such as during rename and link operations. So flush
			 * them out and wait for their writeback to complete, so
			 * that we properly cleanup their state and pages.
			 */
			btrfs_write_marked_extents(log->fs_info,
						   &log->dirty_log_pages,
						   EXTENT_DIRTY_LOG1 | EXTENT_DIRTY_LOG2);
			btrfs_wait_tree_log_extents(log,
						    EXTENT_DIRTY_LOG1 | EXTENT_DIRTY_LOG2);

			if (trans)
				btrfs_abort_transaction(trans, ret);
			else
				btrfs_handle_fs_error(log->fs_info, ret, NULL);
		}
	}

	btrfs_extent_io_tree_release(&log->dirty_log_pages);
	btrfs_extent_io_tree_release(&log->log_csum_range);

	btrfs_put_root(log);
}

/*
 * free all the extents used by the tree log.  This should be called
 * at commit time of the full transaction
 */
int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root)
{
	if (root->log_root) {
		free_log_tree(trans, root->log_root);
		root->log_root = NULL;
		clear_bit(BTRFS_ROOT_HAS_LOG_TREE, &root->state);
	}
	return 0;
}

int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans,
			     struct btrfs_fs_info *fs_info)
{
	if (fs_info->log_root_tree) {
		free_log_tree(trans, fs_info->log_root_tree);
		fs_info->log_root_tree = NULL;
		clear_bit(BTRFS_ROOT_HAS_LOG_TREE, &fs_info->tree_root->state);
	}
	return 0;
}

static bool mark_inode_as_not_logged(const struct btrfs_trans_handle *trans,
				     struct btrfs_inode *inode)
{
	bool ret = false;

	/*
	 * Do this only if ->logged_trans is still 0 to prevent races with
	 * concurrent logging as we may see the inode not logged when
	 * inode_logged() is called but it gets logged after inode_logged() did
	 * not find it in the log tree and we end up setting ->logged_trans to a
	 * value less than trans->transid after the concurrent logging task has
	 * set it to trans->transid. As a consequence, subsequent rename, unlink
	 * and link operations may end up not logging new names and removing old
	 * names from the log.
	 */
	spin_lock(&inode->lock);
	if (inode->logged_trans == 0)
		inode->logged_trans = trans->transid - 1;
	else if (inode->logged_trans == trans->transid)
		ret = true;
	spin_unlock(&inode->lock);

	return ret;
}

/*
 * Check if an inode was logged in the current transaction. This correctly deals
 * with the case where the inode was logged but has a logged_trans of 0, which
 * happens if the inode is evicted and loaded again, as logged_trans is an in
 * memory only field (not persisted).
 *
 * Returns 1 if the inode was logged before in the transaction, 0 if it was not,
 * and < 0 on error.
 */
static int inode_logged(const struct btrfs_trans_handle *trans,
			struct btrfs_inode *inode,
			struct btrfs_path *path_in)
{
	struct btrfs_path *path = path_in;
	struct btrfs_key key;
	int ret;

	/*
	 * Quick lockless call, since once ->logged_trans is set to the current
	 * transaction, we never set it to a lower value anywhere else.
	 */
	if (data_race(inode->logged_trans) == trans->transid)
		return 1;

	/*
	 * If logged_trans is not 0 and not trans->transid, then we know the
	 * inode was not logged in this transaction, so we can return false
	 * right away. We take the lock to avoid a race caused by load/store
	 * tearing with a concurrent btrfs_log_inode() call or a concurrent task
	 * in this function further below - an update to trans->transid can be
	 * teared into two 32 bits updates for example, in which case we could
	 * see a positive value that is not trans->transid and assume the inode
	 * was not logged when it was.
	 */
	spin_lock(&inode->lock);
	if (inode->logged_trans == trans->transid) {
		spin_unlock(&inode->lock);
		return 1;
	} else if (inode->logged_trans > 0) {
		spin_unlock(&inode->lock);
		return 0;
	}
	spin_unlock(&inode->lock);

	/*
	 * If no log tree was created for this root in this transaction, then
	 * the inode can not have been logged in this transaction. In that case
	 * set logged_trans to anything greater than 0 and less than the current
	 * transaction's ID, to avoid the search below in a future call in case
	 * a log tree gets created after this.
	 */
	if (!test_bit(BTRFS_ROOT_HAS_LOG_TREE, &inode->root->state))
		return mark_inode_as_not_logged(trans, inode);

	/*
	 * We have a log tree and the inode's logged_trans is 0. We can't tell
	 * for sure if the inode was logged before in this transaction by looking
	 * only at logged_trans. We could be pessimistic and assume it was, but
	 * that can lead to unnecessarily logging an inode during rename and link
	 * operations, and then further updating the log in followup rename and
	 * link operations, specially if it's a directory, which adds latency
	 * visible to applications doing a series of rename or link operations.
	 *
	 * A logged_trans of 0 here can mean several things:
	 *
	 * 1) The inode was never logged since the filesystem was mounted, and may
	 *    or may have not been evicted and loaded again;
	 *
	 * 2) The inode was logged in a previous transaction, then evicted and
	 *    then loaded again;
	 *
	 * 3) The inode was logged in the current transaction, then evicted and
	 *    then loaded again.
	 *
	 * For cases 1) and 2) we don't want to return true, but we need to detect
	 * case 3) and return true. So we do a search in the log root for the inode
	 * item.
	 */
	key.objectid = btrfs_ino(inode);
	key.type = BTRFS_INODE_ITEM_KEY;
	key.offset = 0;

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

	ret = btrfs_search_slot(NULL, inode->root->log_root, &key, path, 0, 0);

	if (path_in)
		btrfs_release_path(path);
	else
		btrfs_free_path(path);

	/*
	 * Logging an inode always results in logging its inode item. So if we
	 * did not find the item we know the inode was not logged for sure.
	 */
	if (ret < 0) {
		return ret;
	} else if (ret > 0) {
		/*
		 * Set logged_trans to a value greater than 0 and less then the
		 * current transaction to avoid doing the search in future calls.
		 */
		return mark_inode_as_not_logged(trans, inode);
	}

	/*
	 * The inode was previously logged and then evicted, set logged_trans to
	 * the current transaction's ID, to avoid future tree searches as long as
	 * the inode is not evicted again.
	 */
	spin_lock(&inode->lock);
	inode->logged_trans = trans->transid;
	spin_unlock(&inode->lock);

	return 1;
}

/*
 * Delete a directory entry from the log if it exists.
 *
 * Returns < 0 on error
 *           1 if the entry does not exists
 *           0 if the entry existed and was successfully deleted
 */
static int del_logged_dentry(struct btrfs_trans_handle *trans,
			     struct btrfs_root *log,
			     struct btrfs_path *path,
			     u64 dir_ino,
			     const struct fscrypt_str *name,
			     u64 index)
{
	struct btrfs_dir_item *di;

	/*
	 * We only log dir index items of a directory, so we don't need to look
	 * for dir item keys.
	 */
	di = btrfs_lookup_dir_index_item(trans, log, path, dir_ino,
					 index, name, -1);
	if (IS_ERR(di))
		return PTR_ERR(di);
	else if (!di)
		return 1;

	/*
	 * We do not need to update the size field of the directory's
	 * inode item because on log replay we update the field to reflect
	 * all existing entries in the directory (see overwrite_item()).
	 */
	return btrfs_del_item(trans, log, path);
}

/*
 * If both a file and directory are logged, and unlinks or renames are
 * mixed in, we have a few interesting corners:
 *
 * create file X in dir Y
 * link file X to X.link in dir Y
 * fsync file X
 * unlink file X but leave X.link
 * fsync dir Y
 *
 * After a crash we would expect only X.link to exist.  But file X
 * didn't get fsync'd again so the log has back refs for X and X.link.
 *
 * We solve this by removing directory entries and inode backrefs from the
 * log when a file that was logged in the current transaction is
 * unlinked.  Any later fsync will include the updated log entries, and
 * we'll be able to reconstruct the proper directory items from backrefs.
 *
 * This optimizations allows us to avoid relogging the entire inode
 * or the entire directory.
 */
void btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
				  struct btrfs_root *root,
				  const struct fscrypt_str *name,
				  struct btrfs_inode *dir, u64 index)
{
	BTRFS_PATH_AUTO_FREE(path);
	int ret;

	ret = inode_logged(trans, dir, NULL);
	if (ret == 0)
		return;
	if (ret < 0) {
		btrfs_set_log_full_commit(trans);
		return;
	}

	path = btrfs_alloc_path();
	if (!path) {
		btrfs_set_log_full_commit(trans);
		return;
	}

	ret = join_running_log_trans(root);
	ASSERT(ret == 0, "join_running_log_trans() ret=%d", ret);
	if (WARN_ON(ret))
		return;

	mutex_lock(&dir->log_mutex);

	ret = del_logged_dentry(trans, root->log_root, path, btrfs_ino(dir),
				name, index);
	mutex_unlock(&dir->log_mutex);
	if (ret < 0)
		btrfs_set_log_full_commit(trans);
	btrfs_end_log_trans(root);
}

/* see comments for btrfs_del_dir_entries_in_log */
void btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans,
				struct btrfs_root *root,
				const struct fscrypt_str *name,
				struct btrfs_inode *inode, u64 dirid)
{
	struct btrfs_root *log;
	int ret;

	ret = inode_logged(trans, inode, NULL);
	if (ret == 0)
		return;
	else if (ret < 0) {
		btrfs_set_log_full_commit(trans);
		return;
	}

	ret = join_running_log_trans(root);
	ASSERT(ret == 0, "join_running_log_trans() ret=%d", ret);
	if (WARN_ON(ret))
		return;
	log = root->log_root;
	mutex_lock(&inode->log_mutex);

	ret = btrfs_del_inode_ref(trans, log, name, btrfs_ino(inode), dirid, NULL);
	mutex_unlock(&inode->log_mutex);
	if (ret < 0 && ret != -ENOENT)
		btrfs_set_log_full_commit(trans);
	btrfs_end_log_trans(root);
}

/*
 * creates a range item in the log for 'dirid'.  first_offset and
 * last_offset tell us which parts of the key space the log should
 * be considered authoritative for.
 */
static noinline int insert_dir_log_key(struct btrfs_trans_handle *trans,
				       struct btrfs_root *log,
				       struct btrfs_path *path,
				       u64 dirid,
				       u64 first_offset, u64 last_offset)
{
	int ret;
	struct btrfs_key key;
	struct btrfs_dir_log_item *item;

	key.objectid = dirid;
	key.type = BTRFS_DIR_LOG_INDEX_KEY;
	key.offset = first_offset;
	ret = btrfs_insert_empty_item(trans, log, path, &key, sizeof(*item));
	/*
	 * -EEXIST is fine and can happen sporadically when we are logging a
	 * directory and have concurrent insertions in the subvolume's tree for
	 * items from other inodes and that result in pushing off some dir items
	 * from one leaf to another in order to accommodate for the new items.
	 * This results in logging the same dir index range key.
	 */
	if (ret && ret != -EEXIST)
		return ret;

	item = btrfs_item_ptr(path->nodes[0], path->slots[0],
			      struct btrfs_dir_log_item);
	if (ret == -EEXIST) {
		const u64 curr_end = btrfs_dir_log_end(path->nodes[0], item);

		/*
		 * btrfs_del_dir_entries_in_log() might have been called during
		 * an unlink between the initial insertion of this key and the
		 * current update, or we might be logging a single entry deletion
		 * during a rename, so set the new last_offset to the max value.
		 */
		last_offset = max(last_offset, curr_end);
	}
	btrfs_set_dir_log_end(path->nodes[0], item, last_offset);
	btrfs_release_path(path);
	return 0;
}

static int flush_dir_items_batch(struct btrfs_trans_handle *trans,
				 struct btrfs_inode *inode,
				 struct extent_buffer *src,
				 struct btrfs_path *dst_path,
				 int start_slot,
				 int count)
{
	struct btrfs_root *log = inode->root->log_root;
	char *ins_data = NULL;
	struct btrfs_item_batch batch;
	struct extent_buffer *dst;
	unsigned long src_offset;
	unsigned long dst_offset;
	u64 last_index;
	struct btrfs_key key;
	u32 item_size;
	int ret;
	int i;

	ASSERT(count > 0);
	batch.nr = count;

	if (count == 1) {
		btrfs_item_key_to_cpu(src, &key, start_slot);
		item_size = btrfs_item_size(src, start_slot);
		batch.keys = &key;
		batch.data_sizes = &item_size;
		batch.total_data_size = item_size;
	} else {
		struct btrfs_key *ins_keys;
		u32 *ins_sizes;

		ins_data = kmalloc_array(count, sizeof(u32) + sizeof(struct btrfs_key), GFP_NOFS);
		if (!ins_data)
			return -ENOMEM;

		ins_sizes = (u32 *)ins_data;
		ins_keys = (struct btrfs_key *)(ins_data + count * sizeof(u32));
		batch.keys = ins_keys;
		batch.data_sizes = ins_sizes;
		batch.total_data_size = 0;

		for (i = 0; i < count; i++) {
			const int slot = start_slot + i;

			btrfs_item_key_to_cpu(src, &ins_keys[i], slot);
			ins_sizes[i] = btrfs_item_size(src, slot);
			batch.total_data_size += ins_sizes[i];
		}
	}

	ret = btrfs_insert_empty_items(trans, log, dst_path, &batch);
	if (ret)
		goto out;

	dst = dst_path->nodes[0];
	/*
	 * Copy all the items in bulk, in a single copy operation. Item data is
	 * organized such that it's placed at the end of a leaf and from right
	 * to left. For example, the data for the second item ends at an offset
	 * that matches the offset where the data for the first item starts, the
	 * data for the third item ends at an offset that matches the offset
	 * where the data of the second items starts, and so on.
	 * Therefore our source and destination start offsets for copy match the
	 * offsets of the last items (highest slots).
	 */
	dst_offset = btrfs_item_ptr_offset(dst, dst_path->slots[0] + count - 1);
	src_offset = btrfs_item_ptr_offset(src, start_slot + count - 1);
	copy_extent_buffer(dst, src, dst_offset, src_offset, batch.total_data_size);
	btrfs_release_path(dst_path);

	last_index = batch.keys[count - 1].offset;
	ASSERT(last_index > inode->last_dir_index_offset);

	/*
	 * If for some unexpected reason the last item's index is not greater
	 * than the last index we logged, warn and force a transaction commit.
	 */
	if (WARN_ON(last_index <= inode->last_dir_index_offset))
		ret = BTRFS_LOG_FORCE_COMMIT;
	else
		inode->last_dir_index_offset = last_index;

	if (btrfs_get_first_dir_index_to_log(inode) == 0)
		btrfs_set_first_dir_index_to_log(inode, batch.keys[0].offset);
out:
	kfree(ins_data);

	return ret;
}

static int clone_leaf(struct btrfs_path *path, struct btrfs_log_ctx *ctx)
{
	const int slot = path->slots[0];

	if (ctx->scratch_eb) {
		copy_extent_buffer_full(ctx->scratch_eb, path->nodes[0]);
	} else {
		ctx->scratch_eb = btrfs_clone_extent_buffer(path->nodes[0]);
		if (!ctx->scratch_eb)
			return -ENOMEM;
	}

	btrfs_release_path(path);
	path->nodes[0] = ctx->scratch_eb;
	path->slots[0] = slot;
	/*
	 * Add extra ref to scratch eb so that it is not freed when callers
	 * release the path, so we can reuse it later if needed.
	 */
	refcount_inc(&ctx->scratch_eb->refs);

	return 0;
}

static int process_dir_items_leaf(struct btrfs_trans_handle *trans,
				  struct btrfs_inode *inode,
				  struct btrfs_path *path,
				  struct btrfs_path *dst_path,
				  struct btrfs_log_ctx *ctx,
				  u64 *last_old_dentry_offset)
{
	struct btrfs_root *log = inode->root->log_root;
	struct extent_buffer *src;
	const int nritems = btrfs_header_nritems(path->nodes[0]);
	const u64 ino = btrfs_ino(inode);
	bool last_found = false;
	int batch_start = 0;
	int batch_size = 0;
	int ret;

	/*
	 * We need to clone the leaf, release the read lock on it, and use the
	 * clone before modifying the log tree. See the comment at copy_items()
	 * about why we need to do this.
	 */
	ret = clone_leaf(path, ctx);
	if (ret < 0)
		return ret;

	src = path->nodes[0];

	for (int i = path->slots[0]; i < nritems; i++) {
		struct btrfs_dir_item *di;
		struct btrfs_key key;
		int ret;

		btrfs_item_key_to_cpu(src, &key, i);

		if (key.objectid != ino || key.type != BTRFS_DIR_INDEX_KEY) {
			last_found = true;
			break;
		}

		di = btrfs_item_ptr(src, i, struct btrfs_dir_item);

		/*
		 * Skip ranges of items that consist only of dir item keys created
		 * in past transactions. However if we find a gap, we must log a
		 * dir index range item for that gap, so that index keys in that
		 * gap are deleted during log replay.
		 */
		if (btrfs_dir_transid(src, di) < trans->transid) {
			if (key.offset > *last_old_dentry_offset + 1) {
				ret = insert_dir_log_key(trans, log, dst_path,
						 ino, *last_old_dentry_offset + 1,
						 key.offset - 1);
				if (ret < 0)
					return ret;
			}

			*last_old_dentry_offset = key.offset;
			continue;
		}

		/* If we logged this dir index item before, we can skip it. */
		if (key.offset <= inode->last_dir_index_offset)
			continue;

		/*
		 * We must make sure that when we log a directory entry, the
		 * corresponding inode, after log replay, has a matching link
		 * count. For example:
		 *
		 * touch foo
		 * mkdir mydir
		 * sync
		 * ln foo mydir/bar
		 * xfs_io -c "fsync" mydir
		 * <crash>
		 * <mount fs and log replay>
		 *
		 * Would result in a fsync log that when replayed, our file inode
		 * would have a link count of 1, but we get two directory entries
		 * pointing to the same inode. After removing one of the names,
		 * it would not be possible to remove the other name, which
		 * resulted always in stale file handle errors, and would not be
		 * possible to rmdir the parent directory, since its i_size could
		 * never be decremented to the value BTRFS_EMPTY_DIR_SIZE,
		 * resulting in -ENOTEMPTY errors.
		 */
		if (!ctx->log_new_dentries) {
			struct btrfs_key di_key;

			btrfs_dir_item_key_to_cpu(src, di, &di_key);
			if (di_key.type != BTRFS_ROOT_ITEM_KEY)
				ctx->log_new_dentries = true;
		}

		if (batch_size == 0)
			batch_start = i;
		batch_size++;
	}

	if (batch_size > 0) {
		int ret;

		ret = flush_dir_items_batch(trans, inode, src, dst_path,
					    batch_start, batch_size);
		if (ret < 0)
			return ret;
	}

	return last_found ? 1 : 0;
}

/*
 * log all the items included in the current transaction for a given
 * directory.  This also creates the range items in the log tree required
 * to replay anything deleted before the fsync
 */
static noinline int log_dir_items(struct btrfs_trans_handle *trans,
			  struct btrfs_inode *inode,
			  struct btrfs_path *path,
			  struct btrfs_path *dst_path,
			  struct btrfs_log_ctx *ctx,
			  u64 min_offset, u64 *last_offset_ret)
{
	struct btrfs_key min_key;
	struct btrfs_root *root = inode->root;
	struct btrfs_root *log = root->log_root;
	int ret;
	u64 last_old_dentry_offset = min_offset - 1;
	u64 last_offset = (u64)-1;
	u64 ino = btrfs_ino(inode);

	min_key.objectid = ino;
	min_key.type = BTRFS_DIR_INDEX_KEY;
	min_key.offset = min_offset;

	ret = btrfs_search_forward(root, &min_key, path, trans->transid);

	/*
	 * we didn't find anything from this transaction, see if there
	 * is anything at all
	 */
	if (ret != 0 || min_key.objectid != ino ||
	    min_key.type != BTRFS_DIR_INDEX_KEY) {
		min_key.objectid = ino;
		min_key.type = BTRFS_DIR_INDEX_KEY;
		min_key.offset = (u64)-1;
		btrfs_release_path(path);
		ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0);
		if (ret < 0) {
			btrfs_release_path(path);
			return ret;
		}
		ret = btrfs_previous_item(root, path, ino, BTRFS_DIR_INDEX_KEY);

		/* if ret == 0 there are items for this type,
		 * create a range to tell us the last key of this type.
		 * otherwise, there are no items in this directory after
		 * *min_offset, and we create a range to indicate that.
		 */
		if (ret == 0) {
			struct btrfs_key tmp;

			btrfs_item_key_to_cpu(path->nodes[0], &tmp,
					      path->slots[0]);
			if (tmp.type == BTRFS_DIR_INDEX_KEY)
				last_old_dentry_offset = tmp.offset;
		} else if (ret > 0) {
			ret = 0;
		}

		goto done;
	}

	/* go backward to find any previous key */
	ret = btrfs_previous_item(root, path, ino, BTRFS_DIR_INDEX_KEY);
	if (ret == 0) {
		struct btrfs_key tmp;

		btrfs_item_key_to_cpu(path->nodes[0], &tmp, path->slots[0]);
		/*
		 * The dir index key before the first one we found that needs to
		 * be logged might be in a previous leaf, and there might be a
		 * gap between these keys, meaning that we had deletions that
		 * happened. So the key range item we log (key type
		 * BTRFS_DIR_LOG_INDEX_KEY) must cover a range that starts at the
		 * previous key's offset plus 1, so that those deletes are replayed.
		 */
		if (tmp.type == BTRFS_DIR_INDEX_KEY)
			last_old_dentry_offset = tmp.offset;
	} else if (ret < 0) {
		goto done;
	}

	btrfs_release_path(path);

	/*
	 * Find the first key from this transaction again or the one we were at
	 * in the loop below in case we had to reschedule. We may be logging the
	 * directory without holding its VFS lock, which happen when logging new
	 * dentries (through log_new_dir_dentries()) or in some cases when we
	 * need to log the parent directory of an inode. This means a dir index
	 * key might be deleted from the inode's root, and therefore we may not
	 * find it anymore. If we can't find it, just move to the next key. We
	 * can not bail out and ignore, because if we do that we will simply
	 * not log dir index keys that come after the one that was just deleted
	 * and we can end up logging a dir index range that ends at (u64)-1
	 * (@last_offset is initialized to that), resulting in removing dir
	 * entries we should not remove at log replay time.
	 */
search:
	ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0);
	if (ret > 0) {
		ret = btrfs_next_item(root, path);
		if (ret > 0) {
			/* There are no more keys in the inode's root. */
			ret = 0;
			goto done;
		}
	}
	if (ret < 0)
		goto done;

	/*
	 * we have a block from this transaction, log every item in it
	 * from our directory
	 */
	while (1) {
		ret = process_dir_items_leaf(trans, inode, path, dst_path, ctx,
					     &last_old_dentry_offset);
		if (ret != 0) {
			if (ret > 0)
				ret = 0;
			goto done;
		}
		path->slots[0] = btrfs_header_nritems(path->nodes[0]);

		/*
		 * look ahead to the next item and see if it is also
		 * from this directory and from this transaction
		 */
		ret = btrfs_next_leaf(root, path);
		if (ret) {
			if (ret == 1) {
				last_offset = (u64)-1;
				ret = 0;
			}
			goto done;
		}
		btrfs_item_key_to_cpu(path->nodes[0], &min_key, path->slots[0]);
		if (min_key.objectid != ino || min_key.type != BTRFS_DIR_INDEX_KEY) {
			last_offset = (u64)-1;
			goto done;
		}
		if (btrfs_header_generation(path->nodes[0]) != trans->transid) {
			/*
			 * The next leaf was not changed in the current transaction
			 * and has at least one dir index key.
			 * We check for the next key because there might have been
			 * one or more deletions between the last key we logged and
			 * that next key. So the key range item we log (key type
			 * BTRFS_DIR_LOG_INDEX_KEY) must end at the next key's
			 * offset minus 1, so that those deletes are replayed.
			 */
			last_offset = min_key.offset - 1;
			goto done;
		}
		if (need_resched()) {
			btrfs_release_path(path);
			cond_resched();
			goto search;
		}
	}
done:
	btrfs_release_path(path);
	btrfs_release_path(dst_path);

	if (ret == 0) {
		*last_offset_ret = last_offset;
		/*
		 * In case the leaf was changed in the current transaction but
		 * all its dir items are from a past transaction, the last item
		 * in the leaf is a dir item and there's no gap between that last
		 * dir item and the first one on the next leaf (which did not
		 * change in the current transaction), then we don't need to log
		 * a range, last_old_dentry_offset is == to last_offset.
		 */
		ASSERT(last_old_dentry_offset <= last_offset);
		if (last_old_dentry_offset < last_offset)
			ret = insert_dir_log_key(trans, log, path, ino,
						 last_old_dentry_offset + 1,
						 last_offset);
	}

	return ret;
}

/*
 * If the inode was logged before and it was evicted, then its
 * last_dir_index_offset is 0, so we don't know the value of the last index
 * key offset. If that's the case, search for it and update the inode. This
 * is to avoid lookups in the log tree every time we try to insert a dir index
 * key from a leaf changed in the current transaction, and to allow us to always
 * do batch insertions of dir index keys.
 */
static int update_last_dir_index_offset(struct btrfs_inode *inode,
					struct btrfs_path *path,
					const struct btrfs_log_ctx *ctx)
{
	const u64 ino = btrfs_ino(inode);
	struct btrfs_key key;
	int ret;

	lockdep_assert_held(&inode->log_mutex);

	if (inode->last_dir_index_offset != 0)
		return 0;

	if (!ctx->logged_before) {
		inode->last_dir_index_offset = BTRFS_DIR_START_INDEX - 1;
		return 0;
	}

	key.objectid = ino;
	key.type = BTRFS_DIR_INDEX_KEY;
	key.offset = (u64)-1;

	ret = btrfs_search_slot(NULL, inode->root->log_root, &key, path, 0, 0);
	/*
	 * An error happened or we actually have an index key with an offset
	 * value of (u64)-1. Bail out, we're done.
	 */
	if (ret <= 0)
		goto out;

	ret = 0;
	inode->last_dir_index_offset = BTRFS_DIR_START_INDEX - 1;

	/*
	 * No dir index items, bail out and leave last_dir_index_offset with
	 * the value right before the first valid index value.
	 */
	if (path->slots[0] == 0)
		goto out;

	/*
	 * btrfs_search_slot() left us at one slot beyond the slot with the last
	 * index key, or beyond the last key of the directory that is not an
	 * index key. If we have an index key before, set last_dir_index_offset
	 * to its offset value, otherwise leave it with a value right before the
	 * first valid index value, as it means we have an empty directory.
	 */
	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0] - 1);
	if (key.objectid == ino && key.type == BTRFS_DIR_INDEX_KEY)
		inode->last_dir_index_offset = key.offset;

out:
	btrfs_release_path(path);

	return ret;
}

/*
 * logging directories is very similar to logging inodes, We find all the items
 * from the current transaction and write them to the log.
 *
 * The recovery code scans the directory in the subvolume, and if it finds a
 * key in the range logged that is not present in the log tree, then it means
 * that dir entry was unlinked during the transaction.
 *
 * In order for that scan to work, we must include one key smaller than
 * the smallest logged by this transaction and one key larger than the largest
 * key logged by this transaction.
 */
static noinline int log_directory_changes(struct btrfs_trans_handle *trans,
			  struct btrfs_inode *inode,
			  struct btrfs_path *path,
			  struct btrfs_path *dst_path,
			  struct btrfs_log_ctx *ctx)
{
	u64 min_key;
	u64 max_key;
	int ret;

	ret = update_last_dir_index_offset(inode, path, ctx);
	if (ret)
		return ret;

	min_key = BTRFS_DIR_START_INDEX;
	max_key = 0;

	while (1) {
		ret = log_dir_items(trans, inode, path, dst_path,
				ctx, min_key, &max_key);
		if (ret)
			return ret;
		if (max_key == (u64)-1)
			break;
		min_key = max_key + 1;
	}

	return 0;
}

/*
 * a helper function to drop items from the log before we relog an
 * inode.  max_key_type indicates the highest item type to remove.
 * This cannot be run for file data extents because it does not
 * free the extents they point to.
 */
static int drop_inode_items(struct btrfs_trans_handle *trans,
				  struct btrfs_root *log,
				  struct btrfs_path *path,
				  struct btrfs_inode *inode,
				  int max_key_type)
{
	int ret;
	struct btrfs_key key;
	struct btrfs_key found_key;
	int start_slot;

	key.objectid = btrfs_ino(inode);
	key.type = max_key_type;
	key.offset = (u64)-1;

	while (1) {
		ret = btrfs_search_slot(trans, log, &key, path, -1, 1);
		if (ret < 0) {
			break;
		} else if (ret > 0) {
			if (path->slots[0] == 0)
				break;
			path->slots[0]--;
		}

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

		if (found_key.objectid != key.objectid)
			break;

		found_key.offset = 0;
		found_key.type = 0;
		ret = btrfs_bin_search(path->nodes[0], 0, &found_key, &start_slot);
		if (ret < 0)
			break;

		ret = btrfs_del_items(trans, log, path, start_slot,
				      path->slots[0] - start_slot + 1);
		/*
		 * If start slot isn't 0 then we don't need to re-search, we've
		 * found the last guy with the objectid in this tree.
		 */
		if (ret || start_slot != 0)
			break;
		btrfs_release_path(path);
	}
	btrfs_release_path(path);
	if (ret > 0)
		ret = 0;
	return ret;
}

static int truncate_inode_items(struct btrfs_trans_handle *trans,
				struct btrfs_root *log_root,
				struct btrfs_inode *inode,
				u64 new_size, u32 min_type)
{
	struct btrfs_truncate_control control = {
		.new_size = new_size,
		.ino = btrfs_ino(inode),
		.min_type = min_type,
		.skip_ref_updates = true,
	};

	return btrfs_truncate_inode_items(trans, log_root, &control);
}

static void fill_inode_item(struct btrfs_trans_handle *trans,
			    struct extent_buffer *leaf,
			    struct btrfs_inode_item *item,
			    struct inode *inode, bool log_inode_only,
			    u64 logged_isize)
{
	u64 gen = BTRFS_I(inode)->generation;
	u64 flags;

	if (log_inode_only) {
		/*
		 * Set the generation to zero so the recover code can tell the
		 * difference between a logging just to say 'this inode exists'
		 * and a logging to say 'update this inode with these values'.
		 * But only if the inode was not already logged before.
		 * We access ->logged_trans directly since it was already set
		 * up in the call chain by btrfs_log_inode(), and data_race()
		 * to avoid false alerts from KCSAN and since it was set already
		 * and one can set it to 0 since that only happens on eviction
		 * and we are holding a ref on the inode.
		 */
		ASSERT(data_race(BTRFS_I(inode)->logged_trans) > 0);
		if (data_race(BTRFS_I(inode)->logged_trans) < trans->transid)
			gen = 0;

		btrfs_set_inode_size(leaf, item, logged_isize);
	} else {
		btrfs_set_inode_size(leaf, item, inode->i_size);
	}

	btrfs_set_inode_generation(leaf, item, gen);

	btrfs_set_inode_uid(leaf, item, i_uid_read(inode));
	btrfs_set_inode_gid(leaf, item, i_gid_read(inode));
	btrfs_set_inode_mode(leaf, item, inode->i_mode);
	btrfs_set_inode_nlink(leaf, item, inode->i_nlink);

	btrfs_set_timespec_sec(leaf, &item->atime, inode_get_atime_sec(inode));
	btrfs_set_timespec_nsec(leaf, &item->atime, inode_get_atime_nsec(inode));

	btrfs_set_timespec_sec(leaf, &item->mtime, inode_get_mtime_sec(inode));
	btrfs_set_timespec_nsec(leaf, &item->mtime, inode_get_mtime_nsec(inode));

	btrfs_set_timespec_sec(leaf, &item->ctime, inode_get_ctime_sec(inode));
	btrfs_set_timespec_nsec(leaf, &item->ctime, inode_get_ctime_nsec(inode));

	btrfs_set_timespec_sec(leaf, &item->otime, BTRFS_I(inode)->i_otime_sec);
	btrfs_set_timespec_nsec(leaf, &item->otime, BTRFS_I(inode)->i_otime_nsec);

	/*
	 * We do not need to set the nbytes field, in fact during a fast fsync
	 * its value may not even be correct, since a fast fsync does not wait
	 * for ordered extent completion, which is where we update nbytes, it
	 * only waits for writeback to complete. During log replay as we find
	 * file extent items and replay them, we adjust the nbytes field of the
	 * inode item in subvolume tree as needed (see overwrite_item()).
	 */

	btrfs_set_inode_sequence(leaf, item, inode_peek_iversion(inode));
	btrfs_set_inode_transid(leaf, item, trans->transid);
	btrfs_set_inode_rdev(leaf, item, inode->i_rdev);
	flags = btrfs_inode_combine_flags(BTRFS_I(inode)->flags,
					  BTRFS_I(inode)->ro_flags);
	btrfs_set_inode_flags(leaf, item, flags);
	btrfs_set_inode_block_group(leaf, item, 0);
}

static int log_inode_item(struct btrfs_trans_handle *trans,
			  struct btrfs_root *log, struct btrfs_path *path,
			  struct btrfs_inode *inode, bool inode_item_dropped)
{
	struct btrfs_inode_item *inode_item;
	struct btrfs_key key;
	int ret;

	btrfs_get_inode_key(inode, &key);
	/*
	 * If we are doing a fast fsync and the inode was logged before in the
	 * current transaction, then we know the inode was previously logged and
	 * it exists in the log tree. For performance reasons, in this case use
	 * btrfs_search_slot() directly with ins_len set to 0 so that we never
	 * attempt a write lock on the leaf's parent, which adds unnecessary lock
	 * contention in case there are concurrent fsyncs for other inodes of the
	 * same subvolume. Using btrfs_insert_empty_item() when the inode item
	 * already exists can also result in unnecessarily splitting a leaf.
	 */
	if (!inode_item_dropped && inode->logged_trans == trans->transid) {
		ret = btrfs_search_slot(trans, log, &key, path, 0, 1);
		ASSERT(ret <= 0);
		if (ret > 0)
			ret = -ENOENT;
	} else {
		/*
		 * This means it is the first fsync in the current transaction,
		 * so the inode item is not in the log and we need to insert it.
		 * We can never get -EEXIST because we are only called for a fast
		 * fsync and in case an inode eviction happens after the inode was
		 * logged before in the current transaction, when we load again
		 * the inode, we set BTRFS_INODE_NEEDS_FULL_SYNC on its runtime
		 * flags and set ->logged_trans to 0.
		 */
		ret = btrfs_insert_empty_item(trans, log, path, &key,
					      sizeof(*inode_item));
		ASSERT(ret != -EEXIST);
	}
	if (ret)
		return ret;
	inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
				    struct btrfs_inode_item);
	fill_inode_item(trans, path->nodes[0], inode_item, &inode->vfs_inode,
			false, 0);
	btrfs_release_path(path);
	return 0;
}

static int log_csums(struct btrfs_trans_handle *trans,
		     struct btrfs_inode *inode,
		     struct btrfs_root *log_root,
		     struct btrfs_ordered_sum *sums)
{
	const u64 lock_end = sums->logical + sums->len - 1;
	struct extent_state *cached_state = NULL;
	int ret;

	/*
	 * If this inode was not used for reflink operations in the current
	 * transaction with new extents, then do the fast path, no need to
	 * worry about logging checksum items with overlapping ranges.
	 */
	if (inode->last_reflink_trans < trans->transid)
		return btrfs_csum_file_blocks(trans, log_root, sums);

	/*
	 * Serialize logging for checksums. This is to avoid racing with the
	 * same checksum being logged by another task that is logging another
	 * file which happens to refer to the same extent as well. Such races
	 * can leave checksum items in the log with overlapping ranges.
	 */
	ret = btrfs_lock_extent(&log_root->log_csum_range, sums->logical, lock_end,
				&cached_state);
	if (ret)
		return ret;
	/*
	 * Due to extent cloning, we might have logged a csum item that covers a
	 * subrange of a cloned extent, and later we can end up logging a csum
	 * item for a larger subrange of the same extent or the entire range.
	 * This would leave csum items in the log tree that cover the same range
	 * and break the searches for checksums in the log tree, resulting in
	 * some checksums missing in the fs/subvolume tree. So just delete (or
	 * trim and adjust) any existing csum items in the log for this range.
	 */
	ret = btrfs_del_csums(trans, log_root, sums->logical, sums->len);
	if (!ret)
		ret = btrfs_csum_file_blocks(trans, log_root, sums);

	btrfs_unlock_extent(&log_root->log_csum_range, sums->logical, lock_end,
			    &cached_state);

	return ret;
}

static noinline int copy_items(struct btrfs_trans_handle *trans,
			       struct btrfs_inode *inode,
			       struct btrfs_path *dst_path,
			       struct btrfs_path *src_path,
			       int start_slot, int nr, int inode_only,
			       u64 logged_isize, struct btrfs_log_ctx *ctx)
{
	struct btrfs_root *log = inode->root->log_root;
	struct btrfs_file_extent_item *extent;
	struct extent_buffer *src;
	int ret;
	struct btrfs_key *ins_keys;
	u32 *ins_sizes;
	struct btrfs_item_batch batch;
	char *ins_data;
	int dst_index;
	const bool skip_csum = (inode->flags & BTRFS_INODE_NODATASUM);
	const u64 i_size = i_size_read(&inode->vfs_inode);

	/*
	 * To keep lockdep happy and avoid deadlocks, clone the source leaf and
	 * use the clone. This is because otherwise we would be changing the log
	 * tree, to insert items from the subvolume tree or insert csum items,
	 * while holding a read lock on a leaf from the subvolume tree, which
	 * creates a nasty lock dependency when COWing log tree nodes/leaves:
	 *
	 * 1) Modifying the log tree triggers an extent buffer allocation while
	 *    holding a write lock on a parent extent buffer from the log tree.
	 *    Allocating the pages for an extent buffer, or the extent buffer
	 *    struct, can trigger inode eviction and finally the inode eviction
	 *    will trigger a release/remove of a delayed node, which requires
	 *    taking the delayed node's mutex;
	 *
	 * 2) Allocating a metadata extent for a log tree can trigger the async
	 *    reclaim thread and make us wait for it to release enough space and
	 *    unblock our reservation ticket. The reclaim thread can start
	 *    flushing delayed items, and that in turn results in the need to
	 *    lock delayed node mutexes and in the need to write lock extent
	 *    buffers of a subvolume tree - all this while holding a write lock
	 *    on the parent extent buffer in the log tree.
	 *
	 * So one task in scenario 1) running in parallel with another task in
	 * scenario 2) could lead to a deadlock, one wanting to lock a delayed
	 * node mutex while having a read lock on a leaf from the subvolume,
	 * while the other is holding the delayed node's mutex and wants to
	 * write lock the same subvolume leaf for flushing delayed items.
	 */
	ret = clone_leaf(src_path, ctx);
	if (ret < 0)
		return ret;

	src = src_path->nodes[0];

	ins_data = kmalloc_array(nr, sizeof(struct btrfs_key) + sizeof(u32), GFP_NOFS);
	if (!ins_data)
		return -ENOMEM;

	ins_sizes = (u32 *)ins_data;
	ins_keys = (struct btrfs_key *)(ins_data + nr * sizeof(u32));
	batch.keys = ins_keys;
	batch.data_sizes = ins_sizes;
	batch.total_data_size = 0;
	batch.nr = 0;

	dst_index = 0;
	for (int i = 0; i < nr; i++) {
		const int src_slot = start_slot + i;
		struct btrfs_root *csum_root;
		struct btrfs_ordered_sum *sums;
		struct btrfs_ordered_sum *sums_next;
		LIST_HEAD(ordered_sums);
		u64 disk_bytenr;
		u64 disk_num_bytes;
		u64 extent_offset;
		u64 extent_num_bytes;
		bool is_old_extent;

		btrfs_item_key_to_cpu(src, &ins_keys[dst_index], src_slot);

		if (ins_keys[dst_index].type != BTRFS_EXTENT_DATA_KEY)
			goto add_to_batch;

		extent = btrfs_item_ptr(src, src_slot,
					struct btrfs_file_extent_item);

		is_old_extent = (btrfs_file_extent_generation(src, extent) <
				 trans->transid);

		/*
		 * Don't copy extents from past generations. That would make us
		 * log a lot more metadata for common cases like doing only a
		 * few random writes into a file and then fsync it for the first
		 * time or after the full sync flag is set on the inode. We can
		 * get leaves full of extent items, most of which are from past
		 * generations, so we can skip them - as long as the inode has
		 * not been the target of a reflink operation in this transaction,
		 * as in that case it might have had file extent items with old
		 * generations copied into it. We also must always log prealloc
		 * extents that start at or beyond eof, otherwise we would lose
		 * them on log replay.
		 */
		if (is_old_extent &&
		    ins_keys[dst_index].offset < i_size &&
		    inode->last_reflink_trans < trans->transid)
			continue;

		if (skip_csum)
			goto add_to_batch;

		/* Only regular extents have checksums. */
		if (btrfs_file_extent_type(src, extent) != BTRFS_FILE_EXTENT_REG)
			goto add_to_batch;

		/*
		 * If it's an extent created in a past transaction, then its
		 * checksums are already accessible from the committed csum tree,
		 * no need to log them.
		 */
		if (is_old_extent)
			goto add_to_batch;

		disk_bytenr = btrfs_file_extent_disk_bytenr(src, extent);
		/* If it's an explicit hole, there are no checksums. */
		if (disk_bytenr == 0)
			goto add_to_batch;

		disk_num_bytes = btrfs_file_extent_disk_num_bytes(src, extent);

		if (btrfs_file_extent_compression(src, extent)) {
			extent_offset = 0;
			extent_num_bytes = disk_num_bytes;
		} else {
			extent_offset = btrfs_file_extent_offset(src, extent);
			extent_num_bytes = btrfs_file_extent_num_bytes(src, extent);
		}

		csum_root = btrfs_csum_root(trans->fs_info, disk_bytenr);
		disk_bytenr += extent_offset;
		ret = btrfs_lookup_csums_list(csum_root, disk_bytenr,
					      disk_bytenr + extent_num_bytes - 1,
					      &ordered_sums, false);
		if (ret < 0)
			goto out;
		ret = 0;

		list_for_each_entry_safe(sums, sums_next, &ordered_sums, list) {
			if (!ret)
				ret = log_csums(trans, inode, log, sums);
			list_del(&sums->list);
			kfree(sums);
		}
		if (ret)
			goto out;

add_to_batch:
		ins_sizes[dst_index] = btrfs_item_size(src, src_slot);
		batch.total_data_size += ins_sizes[dst_index];
		batch.nr++;
		dst_index++;
	}

	/*
	 * We have a leaf full of old extent items that don't need to be logged,
	 * so we don't need to do anything.
	 */
	if (batch.nr == 0)
		goto out;

	ret = btrfs_insert_empty_items(trans, log, dst_path, &batch);
	if (ret)
		goto out;

	dst_index = 0;
	for (int i = 0; i < nr; i++) {
		const int src_slot = start_slot + i;
		const int dst_slot = dst_path->slots[0] + dst_index;
		struct btrfs_key key;
		unsigned long src_offset;
		unsigned long dst_offset;

		/*
		 * We're done, all the remaining items in the source leaf
		 * correspond to old file extent items.
		 */
		if (dst_index >= batch.nr)
			break;

		btrfs_item_key_to_cpu(src, &key, src_slot);

		if (key.type != BTRFS_EXTENT_DATA_KEY)
			goto copy_item;

		extent = btrfs_item_ptr(src, src_slot,
					struct btrfs_file_extent_item);

		/* See the comment in the previous loop, same logic. */
		if (btrfs_file_extent_generation(src, extent) < trans->transid &&
		    key.offset < i_size &&
		    inode->last_reflink_trans < trans->transid)
			continue;

copy_item:
		dst_offset = btrfs_item_ptr_offset(dst_path->nodes[0], dst_slot);
		src_offset = btrfs_item_ptr_offset(src, src_slot);

		if (key.type == BTRFS_INODE_ITEM_KEY) {
			struct btrfs_inode_item *inode_item;

			inode_item = btrfs_item_ptr(dst_path->nodes[0], dst_slot,
						    struct btrfs_inode_item);
			fill_inode_item(trans, dst_path->nodes[0], inode_item,
					&inode->vfs_inode,
					inode_only == LOG_INODE_EXISTS,
					logged_isize);
		} else {
			copy_extent_buffer(dst_path->nodes[0], src, dst_offset,
					   src_offset, ins_sizes[dst_index]);
		}

		dst_index++;
	}

	btrfs_release_path(dst_path);
out:
	kfree(ins_data);

	return ret;
}

static int extent_cmp(void *priv, const struct list_head *a,
		      const struct list_head *b)
{
	const struct extent_map *em1, *em2;

	em1 = list_entry(a, struct extent_map, list);
	em2 = list_entry(b, struct extent_map, list);

	if (em1->start < em2->start)
		return -1;
	else if (em1->start > em2->start)
		return 1;
	return 0;
}

static int log_extent_csums(struct btrfs_trans_handle *trans,
			    struct btrfs_inode *inode,
			    struct btrfs_root *log_root,
			    const struct extent_map *em,
			    struct btrfs_log_ctx *ctx)
{
	struct btrfs_ordered_extent *ordered;
	struct btrfs_root *csum_root;
	u64 block_start;
	u64 csum_offset;
	u64 csum_len;
	u64 mod_start = em->start;
	u64 mod_len = em->len;
	LIST_HEAD(ordered_sums);
	int ret = 0;

	if (inode->flags & BTRFS_INODE_NODATASUM ||
	    (em->flags & EXTENT_FLAG_PREALLOC) ||
	    em->disk_bytenr == EXTENT_MAP_HOLE)
		return 0;

	list_for_each_entry(ordered, &ctx->ordered_extents, log_list) {
		const u64 ordered_end = ordered->file_offset + ordered->num_bytes;
		const u64 mod_end = mod_start + mod_len;
		struct btrfs_ordered_sum *sums;

		if (mod_len == 0)
			break;

		if (ordered_end <= mod_start)
			continue;
		if (mod_end <= ordered->file_offset)
			break;

		/*
		 * We are going to copy all the csums on this ordered extent, so
		 * go ahead and adjust mod_start and mod_len in case this ordered
		 * extent has already been logged.
		 */
		if (ordered->file_offset > mod_start) {
			if (ordered_end >= mod_end)
				mod_len = ordered->file_offset - mod_start;
			/*
			 * If we have this case
			 *
			 * |--------- logged extent ---------|
			 *       |----- ordered extent ----|
			 *
			 * Just don't mess with mod_start and mod_len, we'll
			 * just end up logging more csums than we need and it
			 * will be ok.
			 */
		} else {
			if (ordered_end < mod_end) {
				mod_len = mod_end - ordered_end;
				mod_start = ordered_end;
			} else {
				mod_len = 0;
			}
		}

		/*
		 * To keep us from looping for the above case of an ordered
		 * extent that falls inside of the logged extent.
		 */
		if (test_and_set_bit(BTRFS_ORDERED_LOGGED_CSUM, &ordered->flags))
			continue;

		list_for_each_entry(sums, &ordered->list, list) {
			ret = log_csums(trans, inode, log_root, sums);
			if (ret)
				return ret;
		}
	}

	/* We're done, found all csums in the ordered extents. */
	if (mod_len == 0)
		return 0;

	/* If we're compressed we have to save the entire range of csums. */
	if (btrfs_extent_map_is_compressed(em)) {
		csum_offset = 0;
		csum_len = em->disk_num_bytes;
	} else {
		csum_offset = mod_start - em->start;
		csum_len = mod_len;
	}

	/* block start is already adjusted for the file extent offset. */
	block_start = btrfs_extent_map_block_start(em);
	csum_root = btrfs_csum_root(trans->fs_info, block_start);
	ret = btrfs_lookup_csums_list(csum_root, block_start + csum_offset,
				      block_start + csum_offset + csum_len - 1,
				      &ordered_sums, false);
	if (ret < 0)
		return ret;
	ret = 0;

	while (!list_empty(&ordered_sums)) {
		struct btrfs_ordered_sum *sums = list_first_entry(&ordered_sums,
								  struct btrfs_ordered_sum,
								  list);
		if (!ret)
			ret = log_csums(trans, inode, log_root, sums);
		list_del(&sums->list);
		kfree(sums);
	}

	return ret;
}

static int log_one_extent(struct btrfs_trans_handle *trans,
			  struct btrfs_inode *inode,
			  const struct extent_map *em,
			  struct btrfs_path *path,
			  struct btrfs_log_ctx *ctx)
{
	struct btrfs_drop_extents_args drop_args = { 0 };
	struct btrfs_root *log = inode->root->log_root;
	struct btrfs_file_extent_item fi = { 0 };
	struct extent_buffer *leaf;
	struct btrfs_key key;
	enum btrfs_compression_type compress_type;
	u64 extent_offset = em->offset;
	u64 block_start = btrfs_extent_map_block_start(em);
	u64 block_len;
	int ret;

	btrfs_set_stack_file_extent_generation(&fi, trans->transid);
	if (em->flags & EXTENT_FLAG_PREALLOC)
		btrfs_set_stack_file_extent_type(&fi, BTRFS_FILE_EXTENT_PREALLOC);
	else
		btrfs_set_stack_file_extent_type(&fi, BTRFS_FILE_EXTENT_REG);

	block_len = em->disk_num_bytes;
	compress_type = btrfs_extent_map_compression(em);
	if (compress_type != BTRFS_COMPRESS_NONE) {
		btrfs_set_stack_file_extent_disk_bytenr(&fi, block_start);
		btrfs_set_stack_file_extent_disk_num_bytes(&fi, block_len);
	} else if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
		btrfs_set_stack_file_extent_disk_bytenr(&fi, block_start - extent_offset);
		btrfs_set_stack_file_extent_disk_num_bytes(&fi, block_len);
	}

	btrfs_set_stack_file_extent_offset(&fi, extent_offset);
	btrfs_set_stack_file_extent_num_bytes(&fi, em->len);
	btrfs_set_stack_file_extent_ram_bytes(&fi, em->ram_bytes);
	btrfs_set_stack_file_extent_compression(&fi, compress_type);

	ret = log_extent_csums(trans, inode, log, em, ctx);
	if (ret)
		return ret;

	/*
	 * If this is the first time we are logging the inode in the current
	 * transaction, we can avoid btrfs_drop_extents(), which is expensive
	 * because it does a deletion search, which always acquires write locks
	 * for extent buffers at levels 2, 1 and 0. This not only wastes time
	 * but also adds significant contention in a log tree, since log trees
	 * are small, with a root at level 2 or 3 at most, due to their short
	 * life span.
	 */
	if (ctx->logged_before) {
		drop_args.path = path;
		drop_args.start = em->start;
		drop_args.end = em->start + em->len;
		drop_args.replace_extent = true;
		drop_args.extent_item_size = sizeof(fi);
		ret = btrfs_drop_extents(trans, log, inode, &drop_args);
		if (ret)
			return ret;
	}

	if (!drop_args.extent_inserted) {
		key.objectid = btrfs_ino(inode);
		key.type = BTRFS_EXTENT_DATA_KEY;
		key.offset = em->start;

		ret = btrfs_insert_empty_item(trans, log, path, &key,
					      sizeof(fi));
		if (ret)
			return ret;
	}
	leaf = path->nodes[0];
	write_extent_buffer(leaf, &fi,
			    btrfs_item_ptr_offset(leaf, path->slots[0]),
			    sizeof(fi));

	btrfs_release_path(path);

	return ret;
}

/*
 * Log all prealloc extents beyond the inode's i_size to make sure we do not
 * lose them after doing a full/fast fsync and replaying the log. We scan the
 * subvolume's root instead of iterating the inode's extent map tree because
 * otherwise we can log incorrect extent items based on extent map conversion.
 * That can happen due to the fact that extent maps are merged when they
 * are not in the extent map tree's list of modified extents.
 */
static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans,
				      struct btrfs_inode *inode,
				      struct btrfs_path *path,
				      struct btrfs_log_ctx *ctx)
{
	struct btrfs_root *root = inode->root;
	struct btrfs_key key;
	const u64 i_size = i_size_read(&inode->vfs_inode);
	const u64 ino = btrfs_ino(inode);
	BTRFS_PATH_AUTO_FREE(dst_path);
	bool dropped_extents = false;
	u64 truncate_offset = i_size;
	struct extent_buffer *leaf;
	int slot;
	int ins_nr = 0;
	int start_slot = 0;
	int ret;

	if (!(inode->flags & BTRFS_INODE_PREALLOC))
		return 0;

	key.objectid = ino;
	key.type = BTRFS_EXTENT_DATA_KEY;
	key.offset = i_size;
	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	if (ret < 0)
		goto out;

	/*
	 * We must check if there is a prealloc extent that starts before the
	 * i_size and crosses the i_size boundary. This is to ensure later we
	 * truncate down to the end of that extent and not to the i_size, as
	 * otherwise we end up losing part of the prealloc extent after a log
	 * replay and with an implicit hole if there is another prealloc extent
	 * that starts at an offset beyond i_size.
	 */
	ret = btrfs_previous_item(root, path, ino, BTRFS_EXTENT_DATA_KEY);
	if (ret < 0)
		goto out;

	if (ret == 0) {
		struct btrfs_file_extent_item *ei;

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

		if (btrfs_file_extent_type(leaf, ei) ==
		    BTRFS_FILE_EXTENT_PREALLOC) {
			u64 extent_end;

			btrfs_item_key_to_cpu(leaf, &key, slot);
			extent_end = key.offset +
				btrfs_file_extent_num_bytes(leaf, ei);

			if (extent_end > i_size)
				truncate_offset = extent_end;
		}
	} else {
		ret = 0;
	}

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

		if (slot >= btrfs_header_nritems(leaf)) {
			if (ins_nr > 0) {
				ret = copy_items(trans, inode, dst_path, path,
						 start_slot, ins_nr, 1, 0, ctx);
				if (ret < 0)
					goto out;
				ins_nr = 0;
			}
			ret = btrfs_next_leaf(root, path);
			if (ret < 0)
				goto out;
			if (ret > 0) {
				ret = 0;
				break;
			}
			continue;
		}

		btrfs_item_key_to_cpu(leaf, &key, slot);
		if (key.objectid > ino)
			break;
		if (WARN_ON_ONCE(key.objectid < ino) ||
		    key.type < BTRFS_EXTENT_DATA_KEY ||
		    key.offset < i_size) {
			path->slots[0]++;
			continue;
		}
		/*
		 * Avoid overlapping items in the log tree. The first time we
		 * get here, get rid of everything from a past fsync. After
		 * that, if the current extent starts before the end of the last
		 * extent we copied, truncate the last one. This can happen if
		 * an ordered extent completion modifies the subvolume tree
		 * while btrfs_next_leaf() has the tree unlocked.
		 */
		if (!dropped_extents || key.offset < truncate_offset) {
			ret = truncate_inode_items(trans, root->log_root, inode,
						   min(key.offset, truncate_offset),
						   BTRFS_EXTENT_DATA_KEY);
			if (ret)
				goto out;
			dropped_extents = true;
		}
		truncate_offset = btrfs_file_extent_end(path);
		if (ins_nr == 0)
			start_slot = slot;
		ins_nr++;
		path->slots[0]++;
		if (!dst_path) {
			dst_path = btrfs_alloc_path();
			if (!dst_path) {
				ret = -ENOMEM;
				goto out;
			}
		}
	}
	if (ins_nr > 0)
		ret = copy_items(trans, inode, dst_path, path,
				 start_slot, ins_nr, 1, 0, ctx);
out:
	btrfs_release_path(path);
	return ret;
}

static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
				     struct btrfs_inode *inode,
				     struct btrfs_path *path,
				     struct btrfs_log_ctx *ctx)
{
	struct btrfs_ordered_extent *ordered;
	struct btrfs_ordered_extent *tmp;
	struct extent_map *em, *n;
	LIST_HEAD(extents);
	struct extent_map_tree *tree = &inode->extent_tree;
	int ret = 0;
	int num = 0;

	write_lock(&tree->lock);

	list_for_each_entry_safe(em, n, &tree->modified_extents, list) {
		list_del_init(&em->list);
		/*
		 * Just an arbitrary number, this can be really CPU intensive
		 * once we start getting a lot of extents, and really once we
		 * have a bunch of extents we just want to commit since it will
		 * be faster.
		 */
		if (++num > 32768) {
			list_del_init(&tree->modified_extents);
			ret = -EFBIG;
			goto process;
		}

		if (em->generation < trans->transid)
			continue;

		/* We log prealloc extents beyond eof later. */
		if ((em->flags & EXTENT_FLAG_PREALLOC) &&
		    em->start >= i_size_read(&inode->vfs_inode))
			continue;

		/* Need a ref to keep it from getting evicted from cache */
		refcount_inc(&em->refs);
		em->flags |= EXTENT_FLAG_LOGGING;
		list_add_tail(&em->list, &extents);
		num++;
	}

	list_sort(NULL, &extents, extent_cmp);
process:
	while (!list_empty(&extents)) {
		em = list_first_entry(&extents, struct extent_map, list);

		list_del_init(&em->list);

		/*
		 * If we had an error we just need to delete everybody from our
		 * private list.
		 */
		if (ret) {
			btrfs_clear_em_logging(inode, em);
			btrfs_free_extent_map(em);
			continue;
		}

		write_unlock(&tree->lock);

		ret = log_one_extent(trans, inode, em, path, ctx);
		write_lock(&tree->lock);
		btrfs_clear_em_logging(inode, em);
		btrfs_free_extent_map(em);
	}
	WARN_ON(!list_empty(&extents));
	write_unlock(&tree->lock);

	if (!ret)
		ret = btrfs_log_prealloc_extents(trans, inode, path, ctx);
	if (ret)
		return ret;

	/*
	 * We have logged all extents successfully, now make sure the commit of
	 * the current transaction waits for the ordered extents to complete
	 * before it commits and wipes out the log trees, otherwise we would
	 * lose data if an ordered extents completes after the transaction
	 * commits and a power failure happens after the transaction commit.
	 */
	list_for_each_entry_safe(ordered, tmp, &ctx->ordered_extents, log_list) {
		list_del_init(&ordered->log_list);
		set_bit(BTRFS_ORDERED_LOGGED, &ordered->flags);

		if (!test_bit(BTRFS_ORDERED_COMPLETE, &ordered->flags)) {
			spin_lock_irq(&inode->ordered_tree_lock);
			if (!test_bit(BTRFS_ORDERED_COMPLETE, &ordered->flags)) {
				set_bit(BTRFS_ORDERED_PENDING, &ordered->flags);
				atomic_inc(&trans->transaction->pending_ordered);
			}
			spin_unlock_irq(&inode->ordered_tree_lock);
		}
		btrfs_put_ordered_extent(ordered);
	}

	return 0;
}

static int get_inode_size_to_log(struct btrfs_trans_handle *trans,
				 struct btrfs_inode *inode,
				 struct btrfs_path *path, u64 *size_ret)
{
	struct btrfs_key key;
	struct btrfs_inode_item *item;
	int ret;

	key.objectid = btrfs_ino(inode);
	key.type = BTRFS_INODE_ITEM_KEY;
	key.offset = 0;

	/*
	 * Our caller called inode_logged(), so logged_trans is up to date.
	 * Use data_race() to silence any warning from KCSAN. Once logged_trans
	 * is set, it can only be reset to 0 after inode eviction.
	 */
	if (data_race(inode->logged_trans) == trans->transid) {
		ret = btrfs_search_slot(NULL, inode->root->log_root, &key, path, 0, 0);
	} else if (inode->generation < trans->transid) {
		path->search_commit_root = true;
		path->skip_locking = true;
		ret = btrfs_search_slot(NULL, inode->root, &key, path, 0, 0);
		path->search_commit_root = false;
		path->skip_locking = false;

	} else {
		*size_ret = 0;
		return 0;
	}

	/*
	 * If the inode was logged before or is from a past transaction, then
	 * its inode item must exist in the log root or in the commit root.
	 */
	ASSERT(ret <= 0);
	if (WARN_ON_ONCE(ret > 0))
		ret = -ENOENT;

	if (ret < 0)
		return ret;

	item = btrfs_item_ptr(path->nodes[0], path->slots[0],
			      struct btrfs_inode_item);
	*size_ret = btrfs_inode_size(path->nodes[0], item);
	/*
	 * If the in-memory inode's i_size is smaller then the inode size stored
	 * in the btree, return the inode's i_size, so that we get a correct
	 * inode size after replaying the log when before a power failure we had
	 * a shrinking truncate followed by addition of a new name (rename / new
	 * hard link). Otherwise return the inode size from the btree, to avoid
	 * data loss when replaying a log due to previously doing a write that
	 * expands the inode's size and logging a new name immediately after.
	 */
	if (*size_ret > inode->vfs_inode.i_size)
		*size_ret = inode->vfs_inode.i_size;

	btrfs_release_path(path);
	return 0;
}

/*
 * At the moment we always log all xattrs. This is to figure out at log replay
 * time which xattrs must have their deletion replayed. If a xattr is missing
 * in the log tree and exists in the fs/subvol tree, we delete it. This is
 * because if a xattr is deleted, the inode is fsynced and a power failure
 * happens, causing the log to be replayed the next time the fs is mounted,
 * we want the xattr to not exist anymore (same behaviour as other filesystems
 * with a journal, ext3/4, xfs, f2fs, etc).
 */
static int btrfs_log_all_xattrs(struct btrfs_trans_handle *trans,
				struct btrfs_inode *inode,
				struct btrfs_path *path,
				struct btrfs_path *dst_path,
				struct btrfs_log_ctx *ctx)
{
	struct btrfs_root *root = inode->root;
	int ret;
	struct btrfs_key key;
	const u64 ino = btrfs_ino(inode);
	int ins_nr = 0;
	int start_slot = 0;
	bool found_xattrs = false;

	if (test_bit(BTRFS_INODE_NO_XATTRS, &inode->runtime_flags))
		return 0;

	key.objectid = ino;
	key.type = BTRFS_XATTR_ITEM_KEY;
	key.offset = 0;

	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	if (ret < 0)
		return ret;

	while (true) {
		int slot = path->slots[0];
		struct extent_buffer *leaf = path->nodes[0];
		int nritems = btrfs_header_nritems(leaf);

		if (slot >= nritems) {
			if (ins_nr > 0) {
				ret = copy_items(trans, inode, dst_path, path,
						 start_slot, ins_nr, 1, 0, ctx);
				if (ret < 0)
					return ret;
				ins_nr = 0;
			}
			ret = btrfs_next_leaf(root, path);
			if (ret < 0)
				return ret;
			else if (ret > 0)
				break;
			continue;
		}

		btrfs_item_key_to_cpu(leaf, &key, slot);
		if (key.objectid != ino || key.type != BTRFS_XATTR_ITEM_KEY)
			break;

		if (ins_nr == 0)
			start_slot = slot;
		ins_nr++;
		path->slots[0]++;
		found_xattrs = true;
		cond_resched();
	}
	if (ins_nr > 0) {
		ret = copy_items(trans, inode, dst_path, path,
				 start_slot, ins_nr, 1, 0, ctx);
		if (ret < 0)
			return ret;
	}

	if (!found_xattrs)
		set_bit(BTRFS_INODE_NO_XATTRS, &inode->runtime_flags);

	return 0;
}

/*
 * When using the NO_HOLES feature if we punched a hole that causes the
 * deletion of entire leafs or all the extent items of the first leaf (the one
 * that contains the inode item and references) we may end up not processing
 * any extents, because there are no leafs with a generation matching the
 * current transaction that have extent items for our inode. So we need to find
 * if any holes exist and then log them. We also need to log holes after any
 * truncate operation that changes the inode's size.
 */
static int btrfs_log_holes(struct btrfs_trans_handle *trans,
			   struct btrfs_inode *inode,
			   struct btrfs_path *path)
{
	struct btrfs_root *root = inode->root;
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_key key;
	const u64 ino = btrfs_ino(inode);
	const u64 i_size = i_size_read(&inode->vfs_inode);
	u64 prev_extent_end = 0;
	int ret;

	if (!btrfs_fs_incompat(fs_info, NO_HOLES) || i_size == 0)
		return 0;

	key.objectid = ino;
	key.type = BTRFS_EXTENT_DATA_KEY;
	key.offset = 0;

	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	if (ret < 0)
		return ret;

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

		if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
			ret = btrfs_next_leaf(root, path);
			if (ret < 0)
				return ret;
			if (ret > 0) {
				ret = 0;
				break;
			}
			leaf = path->nodes[0];
		}

		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
		if (key.objectid != ino || key.type != BTRFS_EXTENT_DATA_KEY)
			break;

		/* We have a hole, log it. */
		if (prev_extent_end < key.offset) {
			const u64 hole_len = key.offset - prev_extent_end;

			/*
			 * Release the path to avoid deadlocks with other code
			 * paths that search the root while holding locks on
			 * leafs from the log root.
			 */
			btrfs_release_path(path);
			ret = btrfs_insert_hole_extent(trans, root->log_root,
						       ino, prev_extent_end,
						       hole_len);
			if (ret < 0)
				return ret;

			/*
			 * Search for the same key again in the root. Since it's
			 * an extent item and we are holding the inode lock, the
			 * key must still exist. If it doesn't just emit warning
			 * and return an error to fall back to a transaction
			 * commit.
			 */
			ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
			if (ret < 0)
				return ret;
			if (WARN_ON(ret > 0))
				return -ENOENT;
			leaf = path->nodes[0];
		}

		prev_extent_end = btrfs_file_extent_end(path);
		path->slots[0]++;
		cond_resched();
	}

	if (prev_extent_end < i_size) {
		u64 hole_len;

		btrfs_release_path(path);
		hole_len = ALIGN(i_size - prev_extent_end, fs_info->sectorsize);
		ret = btrfs_insert_hole_extent(trans, root->log_root, ino,
					       prev_extent_end, hole_len);
		if (ret < 0)
			return ret;
	}

	return 0;
}

/*
 * When we are logging a new inode X, check if it doesn't have a reference that
 * matches the reference from some other inode Y created in a past transaction
 * and that was renamed in the current transaction. If we don't do this, then at
 * log replay time we can lose inode Y (and all its files if it's a directory):
 *
 * mkdir /mnt/x
 * echo "hello world" > /mnt/x/foobar
 * sync
 * mv /mnt/x /mnt/y
 * mkdir /mnt/x                 # or touch /mnt/x
 * xfs_io -c fsync /mnt/x
 * <power fail>
 * mount fs, trigger log replay
 *
 * After the log replay procedure, we would lose the first directory and all its
 * files (file foobar).
 * For the case where inode Y is not a directory we simply end up losing it:
 *
 * echo "123" > /mnt/foo
 * sync
 * mv /mnt/foo /mnt/bar
 * echo "abc" > /mnt/foo
 * xfs_io -c fsync /mnt/foo
 * <power fail>
 *
 * We also need this for cases where a snapshot entry is replaced by some other
 * entry (file or directory) otherwise we end up with an unreplayable log due to
 * attempts to delete the snapshot entry (entry of type BTRFS_ROOT_ITEM_KEY) as
 * if it were a regular entry:
 *
 * mkdir /mnt/x
 * btrfs subvolume snapshot /mnt /mnt/x/snap
 * btrfs subvolume delete /mnt/x/snap
 * rmdir /mnt/x
 * mkdir /mnt/x
 * fsync /mnt/x or fsync some new file inside it
 * <power fail>
 *
 * The snapshot delete, rmdir of x, mkdir of a new x and the fsync all happen in
 * the same transaction.
 */
static int btrfs_check_ref_name_override(struct extent_buffer *eb,
					 const int slot,
					 const struct btrfs_key *key,
					 struct btrfs_inode *inode,
					 u64 *other_ino, u64 *other_parent)
{
	int ret;
	BTRFS_PATH_AUTO_FREE(search_path);
	char *name = NULL;
	u32 name_len = 0;
	u32 item_size = btrfs_item_size(eb, slot);
	u32 cur_offset = 0;
	unsigned long ptr = btrfs_item_ptr_offset(eb, slot);

	search_path = btrfs_alloc_path();
	if (!search_path)
		return -ENOMEM;
	search_path->search_commit_root = 1;
	search_path->skip_locking = 1;

	while (cur_offset < item_size) {
		u64 parent;
		u32 this_name_len;
		u32 this_len;
		unsigned long name_ptr;
		struct btrfs_dir_item *di;
		struct fscrypt_str name_str;

		if (key->type == BTRFS_INODE_REF_KEY) {
			struct btrfs_inode_ref *iref;

			iref = (struct btrfs_inode_ref *)(ptr + cur_offset);
			parent = key->offset;
			this_name_len = btrfs_inode_ref_name_len(eb, iref);
			name_ptr = (unsigned long)(iref + 1);
			this_len = sizeof(*iref) + this_name_len;
		} else {
			struct btrfs_inode_extref *extref;

			extref = (struct btrfs_inode_extref *)(ptr +
							       cur_offset);
			parent = btrfs_inode_extref_parent(eb, extref);
			this_name_len = btrfs_inode_extref_name_len(eb, extref);
			name_ptr = (unsigned long)&extref->name;
			this_len = sizeof(*extref) + this_name_len;
		}

		if (this_name_len > name_len) {
			char *new_name;

			new_name = krealloc(name, this_name_len, GFP_NOFS);
			if (!new_name) {
				ret = -ENOMEM;
				goto out;
			}
			name_len = this_name_len;
			name = new_name;
		}

		read_extent_buffer(eb, name, name_ptr, this_name_len);

		name_str.name = name;
		name_str.len = this_name_len;
		di = btrfs_lookup_dir_item(NULL, inode->root, search_path,
				parent, &name_str, 0);
		if (di && !IS_ERR(di)) {
			struct btrfs_key di_key;

			btrfs_dir_item_key_to_cpu(search_path->nodes[0],
						  di, &di_key);
			if (di_key.type == BTRFS_INODE_ITEM_KEY) {
				if (di_key.objectid != key->objectid) {
					ret = 1;
					*other_ino = di_key.objectid;
					*other_parent = parent;
				} else {
					ret = 0;
				}
			} else {
				ret = -EAGAIN;
			}
			goto out;
		} else if (IS_ERR(di)) {
			ret = PTR_ERR(di);
			goto out;
		}
		btrfs_release_path(search_path);

		cur_offset += this_len;
	}
	ret = 0;
out:
	kfree(name);
	return ret;
}

/*
 * Check if we need to log an inode. This is used in contexts where while
 * logging an inode we need to log another inode (either that it exists or in
 * full mode). This is used instead of btrfs_inode_in_log() because the later
 * requires the inode to be in the log and have the log transaction committed,
 * while here we do not care if the log transaction was already committed - our
 * caller will commit the log later - and we want to avoid logging an inode
 * multiple times when multiple tasks have joined the same log transaction.
 */
static bool need_log_inode(const struct btrfs_trans_handle *trans,
			   struct btrfs_inode *inode)
{
	/*
	 * If a directory was not modified, no dentries added or removed, we can
	 * and should avoid logging it.
	 */
	if (S_ISDIR(inode->vfs_inode.i_mode) && inode->last_trans < trans->transid)
		return false;

	/*
	 * If this inode does not have new/updated/deleted xattrs since the last
	 * time it was logged and is flagged as logged in the current transaction,
	 * we can skip logging it. As for new/deleted names, those are updated in
	 * the log by link/unlink/rename operations.
	 * In case the inode was logged and then evicted and reloaded, its
	 * logged_trans will be 0, in which case we have to fully log it since
	 * logged_trans is a transient field, not persisted.
	 */
	if (inode_logged(trans, inode, NULL) == 1 &&
	    !test_bit(BTRFS_INODE_COPY_EVERYTHING, &inode->runtime_flags))
		return false;

	return true;
}

struct btrfs_dir_list {
	u64 ino;
	struct list_head list;
};

/*
 * Log the inodes of the new dentries of a directory.
 * See process_dir_items_leaf() for details about why it is needed.
 * This is a recursive operation - if an existing dentry corresponds to a
 * directory, that directory's new entries are logged too (same behaviour as
 * ext3/4, xfs, f2fs, nilfs2). Note that when logging the inodes
 * the dentries point to we do not acquire their VFS lock, otherwise lockdep
 * complains about the following circular lock dependency / possible deadlock:
 *
 *        CPU0                                        CPU1
 *        ----                                        ----
 * lock(&type->i_mutex_dir_key#3/2);
 *                                            lock(sb_internal#2);
 *                                            lock(&type->i_mutex_dir_key#3/2);
 * lock(&sb->s_type->i_mutex_key#14);
 *
 * Where sb_internal is the lock (a counter that works as a lock) acquired by
 * sb_start_intwrite() in btrfs_start_transaction().
 * Not acquiring the VFS lock of the inodes is still safe because:
 *
 * 1) For regular files we log with a mode of LOG_INODE_EXISTS. It's possible
 *    that while logging the inode new references (names) are added or removed
 *    from the inode, leaving the logged inode item with a link count that does
 *    not match the number of logged inode reference items. This is fine because
 *    at log replay time we compute the real number of links and correct the
 *    link count in the inode item (see replay_one_buffer() and
 *    link_to_fixup_dir());
 *
 * 2) For directories we log with a mode of LOG_INODE_ALL. It's possible that
 *    while logging the inode's items new index items (key type
 *    BTRFS_DIR_INDEX_KEY) are added to fs/subvol tree and the logged inode item
 *    has a size that doesn't match the sum of the lengths of all the logged
 *    names - this is ok, not a problem, because at log replay time we set the
 *    directory's i_size to the correct value (see replay_one_name() and
 *    overwrite_item()).
 */
static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
				struct btrfs_inode *start_inode,
				struct btrfs_log_ctx *ctx)
{
	struct btrfs_root *root = start_inode->root;
	struct btrfs_path *path;
	LIST_HEAD(dir_list);
	struct btrfs_dir_list *dir_elem;
	u64 ino = btrfs_ino(start_inode);
	struct btrfs_inode *curr_inode = start_inode;
	int ret = 0;

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

	/* Pairs with btrfs_add_delayed_iput below. */
	ihold(&curr_inode->vfs_inode);

	while (true) {
		struct btrfs_key key;
		struct btrfs_key found_key;
		u64 next_index;
		bool continue_curr_inode = true;
		int iter_ret;

		key.objectid = ino;
		key.type = BTRFS_DIR_INDEX_KEY;
		key.offset = btrfs_get_first_dir_index_to_log(curr_inode);
		next_index = key.offset;
again:
		btrfs_for_each_slot(root->log_root, &key, &found_key, path, iter_ret) {
			struct extent_buffer *leaf = path->nodes[0];
			struct btrfs_dir_item *di;
			struct btrfs_key di_key;
			struct btrfs_inode *di_inode;
			int log_mode = LOG_INODE_EXISTS;
			int type;

			if (found_key.objectid != ino ||
			    found_key.type != BTRFS_DIR_INDEX_KEY) {
				continue_curr_inode = false;
				break;
			}

			next_index = found_key.offset + 1;

			di = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
			type = btrfs_dir_ftype(leaf, di);
			if (btrfs_dir_transid(leaf, di) < trans->transid)
				continue;
			btrfs_dir_item_key_to_cpu(leaf, di, &di_key);
			if (di_key.type == BTRFS_ROOT_ITEM_KEY)
				continue;

			btrfs_release_path(path);
			di_inode = btrfs_iget_logging(di_key.objectid, root);
			if (IS_ERR(di_inode)) {
				ret = PTR_ERR(di_inode);
				goto out;
			}

			if (!need_log_inode(trans, di_inode)) {
				btrfs_add_delayed_iput(di_inode);
				break;
			}

			ctx->log_new_dentries = false;
			if (type == BTRFS_FT_DIR)
				log_mode = LOG_INODE_ALL;
			ret = btrfs_log_inode(trans, di_inode, log_mode, ctx);
			btrfs_add_delayed_iput(di_inode);
			if (ret)
				goto out;
			if (ctx->log_new_dentries) {
				dir_elem = kmalloc(sizeof(*dir_elem), GFP_NOFS);
				if (!dir_elem) {
					ret = -ENOMEM;
					goto out;
				}
				dir_elem->ino = di_key.objectid;
				list_add_tail(&dir_elem->list, &dir_list);
			}
			break;
		}

		btrfs_release_path(path);

		if (iter_ret < 0) {
			ret = iter_ret;
			goto out;
		} else if (iter_ret > 0) {
			continue_curr_inode = false;
		} else {
			key = found_key;
		}

		if (continue_curr_inode && key.offset < (u64)-1) {
			key.offset++;
			goto again;
		}

		btrfs_set_first_dir_index_to_log(curr_inode, next_index);

		if (list_empty(&dir_list))
			break;

		dir_elem = list_first_entry(&dir_list, struct btrfs_dir_list, list);
		ino = dir_elem->ino;
		list_del(&dir_elem->list);
		kfree(dir_elem);

		btrfs_add_delayed_iput(curr_inode);

		curr_inode = btrfs_iget_logging(ino, root);
		if (IS_ERR(curr_inode)) {
			ret = PTR_ERR(curr_inode);
			curr_inode = NULL;
			break;
		}
	}
out:
	btrfs_free_path(path);
	if (curr_inode)
		btrfs_add_delayed_iput(curr_inode);

	if (ret) {
		struct btrfs_dir_list *next;

		list_for_each_entry_safe(dir_elem, next, &dir_list, list)
			kfree(dir_elem);
	}

	return ret;
}

struct btrfs_ino_list {
	u64 ino;
	u64 parent;
	struct list_head list;
};

static void free_conflicting_inodes(struct btrfs_log_ctx *ctx)
{
	struct btrfs_ino_list *curr;
	struct btrfs_ino_list *next;

	list_for_each_entry_safe(curr, next, &ctx->conflict_inodes, list) {
		list_del(&curr->list);
		kfree(curr);
	}
}

static int conflicting_inode_is_dir(struct btrfs_root *root, u64 ino,
				    struct btrfs_path *path)
{
	struct btrfs_key key;
	int ret;

	key.objectid = ino;
	key.type = BTRFS_INODE_ITEM_KEY;
	key.offset = 0;

	path->search_commit_root = 1;
	path->skip_locking = 1;

	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	if (WARN_ON_ONCE(ret > 0)) {
		/*
		 * We have previously found the inode through the commit root
		 * so this should not happen. If it does, just error out and
		 * fallback to a transaction commit.
		 */
		ret = -ENOENT;
	} else if (ret == 0) {
		struct btrfs_inode_item *item;

		item = btrfs_item_ptr(path->nodes[0], path->slots[0],
				      struct btrfs_inode_item);
		if (S_ISDIR(btrfs_inode_mode(path->nodes[0], item)))
			ret = 1;
	}

	btrfs_release_path(path);
	path->search_commit_root = 0;
	path->skip_locking = 0;

	return ret;
}

static bool can_log_conflicting_inode(const struct btrfs_trans_handle *trans,
				      const struct btrfs_inode *inode)
{
	if (!S_ISDIR(inode->vfs_inode.i_mode))
		return true;

	if (inode->last_unlink_trans < trans->transid)
		return true;

	/*
	 * If this is a directory and its unlink_trans is not from a past
	 * transaction then we must fallback to a transaction commit in order
	 * to avoid getting a directory with 2 hard links after log replay.
	 *
	 * This happens if a directory A is renamed, moved from one parent
	 * directory to another one, a new file is created in the old parent
	 * directory with the old name of our directory A, the new file is
	 * fsynced, then we moved the new file to some other parent directory
	 * and fsync again the new file. This results in a log tree where we
	 * logged that directory A existed, with the INODE_REF item for the
	 * new location but without having logged its old parent inode, so
	 * that on log replay we add a new link for the new location but the
	 * old link remains, resulting in a link count of 2.
	 */
	return false;
}

static int add_conflicting_inode(struct btrfs_trans_handle *trans,
				 struct btrfs_root *root,
				 struct btrfs_path *path,
				 u64 ino, u64 parent,
				 struct btrfs_log_ctx *ctx)
{
	struct btrfs_ino_list *ino_elem;
	struct btrfs_inode *inode;

	/*
	 * It's rare to have a lot of conflicting inodes, in practice it is not
	 * common to have more than 1 or 2. We don't want to collect too many,
	 * as we could end up logging too many inodes (even if only in
	 * LOG_INODE_EXISTS mode) and slow down other fsyncs or transaction
	 * commits.
	 */
	if (ctx->num_conflict_inodes >= MAX_CONFLICT_INODES)
		return BTRFS_LOG_FORCE_COMMIT;

	inode = btrfs_iget_logging(ino, root);
	/*
	 * If the other inode that had a conflicting dir entry was deleted in
	 * the current transaction then we either:
	 *
	 * 1) Log the parent directory (later after adding it to the list) if
	 *    the inode is a directory. This is because it may be a deleted
	 *    subvolume/snapshot or it may be a regular directory that had
	 *    deleted subvolumes/snapshots (or subdirectories that had them),
	 *    and at the moment we can't deal with dropping subvolumes/snapshots
	 *    during log replay. So we just log the parent, which will result in
	 *    a fallback to a transaction commit if we are dealing with those
	 *    cases (last_unlink_trans will match the current transaction);
	 *
	 * 2) Do nothing if it's not a directory. During log replay we simply
	 *    unlink the conflicting dentry from the parent directory and then
	 *    add the dentry for our inode. Like this we can avoid logging the
	 *    parent directory (and maybe fallback to a transaction commit in
	 *    case it has a last_unlink_trans == trans->transid, due to moving
	 *    some inode from it to some other directory).
	 */
	if (IS_ERR(inode)) {
		int ret = PTR_ERR(inode);

		if (ret != -ENOENT)
			return ret;

		ret = conflicting_inode_is_dir(root, ino, path);
		/* Not a directory or we got an error. */
		if (ret <= 0)
			return ret;

		/* Conflicting inode is a directory, so we'll log its parent. */
		ino_elem = kmalloc(sizeof(*ino_elem), GFP_NOFS);
		if (!ino_elem)
			return -ENOMEM;
		ino_elem->ino = ino;
		ino_elem->parent = parent;
		list_add_tail(&ino_elem->list, &ctx->conflict_inodes);
		ctx->num_conflict_inodes++;

		return 0;
	}

	/*
	 * If the inode was already logged skip it - otherwise we can hit an
	 * infinite loop. Example:
	 *
	 * From the commit root (previous transaction) we have the following
	 * inodes:
	 *
	 * inode 257 a directory
	 * inode 258 with references "zz" and "zz_link" on inode 257
	 * inode 259 with reference "a" on inode 257
	 *
	 * And in the current (uncommitted) transaction we have:
	 *
	 * inode 257 a directory, unchanged
	 * inode 258 with references "a" and "a2" on inode 257
	 * inode 259 with reference "zz_link" on inode 257
	 * inode 261 with reference "zz" on inode 257
	 *
	 * When logging inode 261 the following infinite loop could
	 * happen if we don't skip already logged inodes:
	 *
	 * - we detect inode 258 as a conflicting inode, with inode 261
	 *   on reference "zz", and log it;
	 *
	 * - we detect inode 259 as a conflicting inode, with inode 258
	 *   on reference "a", and log it;
	 *
	 * - we detect inode 258 as a conflicting inode, with inode 259
	 *   on reference "zz_link", and log it - again! After this we
	 *   repeat the above steps forever.
	 *
	 * Here we can use need_log_inode() because we only need to log the
	 * inode in LOG_INODE_EXISTS mode and rename operations update the log,
	 * so that the log ends up with the new name and without the old name.
	 */
	if (!need_log_inode(trans, inode)) {
		btrfs_add_delayed_iput(inode);
		return 0;
	}

	if (!can_log_conflicting_inode(trans, inode)) {
		btrfs_add_delayed_iput(inode);
		return BTRFS_LOG_FORCE_COMMIT;
	}

	btrfs_add_delayed_iput(inode);

	ino_elem = kmalloc(sizeof(*ino_elem), GFP_NOFS);
	if (!ino_elem)
		return -ENOMEM;
	ino_elem->ino = ino;
	ino_elem->parent = parent;
	list_add_tail(&ino_elem->list, &ctx->conflict_inodes);
	ctx->num_conflict_inodes++;

	return 0;
}

static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
				  struct btrfs_root *root,
				  struct btrfs_log_ctx *ctx)
{
	const bool orig_log_new_dentries = ctx->log_new_dentries;
	int ret = 0;

	/*
	 * Conflicting inodes are logged by the first call to btrfs_log_inode(),
	 * otherwise we could have unbounded recursion of btrfs_log_inode()
	 * calls. This check guarantees we can have only 1 level of recursion.
	 */
	if (ctx->logging_conflict_inodes)
		return 0;

	ctx->logging_conflict_inodes = true;

	/*
	 * New conflicting inodes may be found and added to the list while we
	 * are logging a conflicting inode, so keep iterating while the list is
	 * not empty.
	 */
	while (!list_empty(&ctx->conflict_inodes)) {
		struct btrfs_ino_list *curr;
		struct btrfs_inode *inode;
		u64 ino;
		u64 parent;

		curr = list_first_entry(&ctx->conflict_inodes,
					struct btrfs_ino_list, list);
		ino = curr->ino;
		parent = curr->parent;
		list_del(&curr->list);
		kfree(curr);

		inode = btrfs_iget_logging(ino, root);
		/*
		 * If the other inode that had a conflicting dir entry was
		 * deleted in the current transaction, we need to log its parent
		 * directory. See the comment at add_conflicting_inode().
		 */
		if (IS_ERR(inode)) {
			ret = PTR_ERR(inode);
			if (ret != -ENOENT)
				break;

			inode = btrfs_iget_logging(parent, root);
			if (IS_ERR(inode)) {
				ret = PTR_ERR(inode);
				break;
			}

			if (!can_log_conflicting_inode(trans, inode)) {
				btrfs_add_delayed_iput(inode);
				ret = BTRFS_LOG_FORCE_COMMIT;
				break;
			}

			/*
			 * Always log the directory, we cannot make this
			 * conditional on need_log_inode() because the directory
			 * might have been logged in LOG_INODE_EXISTS mode or
			 * the dir index of the conflicting inode is not in a
			 * dir index key range logged for the directory. So we
			 * must make sure the deletion is recorded.
			 */
			ctx->log_new_dentries = false;
			ret = btrfs_log_inode(trans, inode, LOG_INODE_ALL, ctx);
			if (!ret && ctx->log_new_dentries)
				ret = log_new_dir_dentries(trans, inode, ctx);

			btrfs_add_delayed_iput(inode);
			if (ret)
				break;
			continue;
		}

		/*
		 * Here we can use need_log_inode() because we only need to log
		 * the inode in LOG_INODE_EXISTS mode and rename operations
		 * update the log, so that the log ends up with the new name and
		 * without the old name.
		 *
		 * We did this check at add_conflicting_inode(), but here we do
		 * it again because if some other task logged the inode after
		 * that, we can avoid doing it again.
		 */
		if (!need_log_inode(trans, inode)) {
			btrfs_add_delayed_iput(inode);
			continue;
		}

		/*
		 * We are safe logging the other inode without acquiring its
		 * lock as long as we log with the LOG_INODE_EXISTS mode. We
		 * are safe against concurrent renames of the other inode as
		 * well because during a rename we pin the log and update the
		 * log with the new name before we unpin it.
		 */
		ret = btrfs_log_inode(trans, inode, LOG_INODE_EXISTS, ctx);
		btrfs_add_delayed_iput(inode);
		if (ret)
			break;
	}

	ctx->log_new_dentries = orig_log_new_dentries;
	ctx->logging_conflict_inodes = false;
	if (ret)
		free_conflicting_inodes(ctx);

	return ret;
}

static int copy_inode_items_to_log(struct btrfs_trans_handle *trans,
				   struct btrfs_inode *inode,
				   struct btrfs_key *min_key,
				   const struct btrfs_key *max_key,
				   struct btrfs_path *path,
				   struct btrfs_path *dst_path,
				   const u64 logged_isize,
				   const int inode_only,
				   struct btrfs_log_ctx *ctx,
				   bool *need_log_inode_item)
{
	const u64 i_size = i_size_read(&inode->vfs_inode);
	struct btrfs_root *root = inode->root;
	int ins_start_slot = 0;
	int ins_nr = 0;
	int ret;

	while (1) {
		ret = btrfs_search_forward(root, min_key, path, trans->transid);
		if (ret < 0)
			return ret;
		if (ret > 0) {
			ret = 0;
			break;
		}
again:
		/* Note, ins_nr might be > 0 here, cleanup outside the loop */
		if (min_key->objectid != max_key->objectid)
			break;
		if (min_key->type > max_key->type)
			break;

		if (min_key->type == BTRFS_INODE_ITEM_KEY) {
			*need_log_inode_item = false;
		} else if (min_key->type == BTRFS_EXTENT_DATA_KEY &&
			   min_key->offset >= i_size) {
			/*
			 * Extents at and beyond eof are logged with
			 * btrfs_log_prealloc_extents().
			 * Only regular files have BTRFS_EXTENT_DATA_KEY keys,
			 * and no keys greater than that, so bail out.
			 */
			break;
		} else if (min_key->type == BTRFS_INODE_REF_KEY ||
			   min_key->type == BTRFS_INODE_EXTREF_KEY) {
			u64 other_ino = 0;
			u64 other_parent = 0;

			ret = btrfs_check_ref_name_override(path->nodes[0],
					path->slots[0], min_key, inode,
					&other_ino, &other_parent);
			if (ret < 0) {
				return ret;
			} else if (ret > 0 &&
				   other_ino != btrfs_ino(ctx->inode)) {
				if (ins_nr > 0) {
					ins_nr++;
				} else {
					ins_nr = 1;
					ins_start_slot = path->slots[0];
				}
				ret = copy_items(trans, inode, dst_path, path,
						 ins_start_slot, ins_nr,
						 inode_only, logged_isize, ctx);
				if (ret < 0)
					return ret;
				ins_nr = 0;

				btrfs_release_path(path);
				ret = add_conflicting_inode(trans, root, path,
							    other_ino,
							    other_parent, ctx);
				if (ret)
					return ret;
				goto next_key;
			}
		} else if (min_key->type == BTRFS_XATTR_ITEM_KEY) {
			/* Skip xattrs, logged later with btrfs_log_all_xattrs() */
			if (ins_nr == 0)
				goto next_slot;
			ret = copy_items(trans, inode, dst_path, path,
					 ins_start_slot,
					 ins_nr, inode_only, logged_isize, ctx);
			if (ret < 0)
				return ret;
			ins_nr = 0;
			goto next_slot;
		}

		if (ins_nr && ins_start_slot + ins_nr == path->slots[0]) {
			ins_nr++;
			goto next_slot;
		} else if (!ins_nr) {
			ins_start_slot = path->slots[0];
			ins_nr = 1;
			goto next_slot;
		}

		ret = copy_items(trans, inode, dst_path, path, ins_start_slot,
				 ins_nr, inode_only, logged_isize, ctx);
		if (ret < 0)
			return ret;
		ins_nr = 1;
		ins_start_slot = path->slots[0];
next_slot:
		path->slots[0]++;
		if (path->slots[0] < btrfs_header_nritems(path->nodes[0])) {
			btrfs_item_key_to_cpu(path->nodes[0], min_key,
					      path->slots[0]);
			goto again;
		}
		if (ins_nr) {
			ret = copy_items(trans, inode, dst_path, path,
					 ins_start_slot, ins_nr, inode_only,
					 logged_isize, ctx);
			if (ret < 0)
				return ret;
			ins_nr = 0;
		}
		btrfs_release_path(path);
next_key:
		if (min_key->offset < (u64)-1) {
			min_key->offset++;
		} else if (min_key->type < max_key->type) {
			min_key->type++;
			min_key->offset = 0;
		} else {
			break;
		}

		/*
		 * We may process many leaves full of items for our inode, so
		 * avoid monopolizing a cpu for too long by rescheduling while
		 * not holding locks on any tree.
		 */
		cond_resched();
	}
	if (ins_nr) {
		ret = copy_items(trans, inode, dst_path, path, ins_start_slot,
				 ins_nr, inode_only, logged_isize, ctx);
		if (ret)
			return ret;
	}

	if (inode_only == LOG_INODE_ALL && S_ISREG(inode->vfs_inode.i_mode)) {
		/*
		 * Release the path because otherwise we might attempt to double
		 * lock the same leaf with btrfs_log_prealloc_extents() below.
		 */
		btrfs_release_path(path);
		ret = btrfs_log_prealloc_extents(trans, inode, dst_path, ctx);
	}

	return ret;
}

static int insert_delayed_items_batch(struct btrfs_trans_handle *trans,
				      struct btrfs_root *log,
				      struct btrfs_path *path,
				      const struct btrfs_item_batch *batch,
				      const struct btrfs_delayed_item *first_item)
{
	const struct btrfs_delayed_item *curr = first_item;
	int ret;

	ret = btrfs_insert_empty_items(trans, log, path, batch);
	if (ret)
		return ret;

	for (int i = 0; i < batch->nr; i++) {
		char *data_ptr;

		data_ptr = btrfs_item_ptr(path->nodes[0], path->slots[0], char);
		write_extent_buffer(path->nodes[0], &curr->data,
				    (unsigned long)data_ptr, curr->data_len);
		curr = list_next_entry(curr, log_list);
		path->slots[0]++;
	}

	btrfs_release_path(path);

	return 0;
}

static int log_delayed_insertion_items(struct btrfs_trans_handle *trans,
				       struct btrfs_inode *inode,
				       struct btrfs_path *path,
				       const struct list_head *delayed_ins_list,
				       struct btrfs_log_ctx *ctx)
{
	/* 195 (4095 bytes of keys and sizes) fits in a single 4K page. */
	const int max_batch_size = 195;
	const int leaf_data_size = BTRFS_LEAF_DATA_SIZE(trans->fs_info);
	const u64 ino = btrfs_ino(inode);
	struct btrfs_root *log = inode->root->log_root;
	struct btrfs_item_batch batch = {
		.nr = 0,
		.total_data_size = 0,
	};
	const struct btrfs_delayed_item *first = NULL;
	const struct btrfs_delayed_item *curr;
	char *ins_data;
	struct btrfs_key *ins_keys;
	u32 *ins_sizes;
	u64 curr_batch_size = 0;
	int batch_idx = 0;
	int ret;

	/* We are adding dir index items to the log tree. */
	lockdep_assert_held(&inode->log_mutex);

	/*
	 * We collect delayed items before copying index keys from the subvolume
	 * to the log tree. However just after we collected them, they may have
	 * been flushed (all of them or just some of them), and therefore we
	 * could have copied them from the subvolume tree to the log tree.
	 * So find the first delayed item that was not yet logged (they are
	 * sorted by index number).
	 */
	list_for_each_entry(curr, delayed_ins_list, log_list) {
		if (curr->index > inode->last_dir_index_offset) {
			first = curr;
			break;
		}
	}

	/* Empty list or all delayed items were already logged. */
	if (!first)
		return 0;

	ins_data = kmalloc_array(max_batch_size, sizeof(u32) + sizeof(struct btrfs_key), GFP_NOFS);
	if (!ins_data)
		return -ENOMEM;
	ins_sizes = (u32 *)ins_data;
	batch.data_sizes = ins_sizes;
	ins_keys = (struct btrfs_key *)(ins_data + max_batch_size * sizeof(u32));
	batch.keys = ins_keys;

	curr = first;
	while (!list_entry_is_head(curr, delayed_ins_list, log_list)) {
		const u32 curr_size = curr->data_len + sizeof(struct btrfs_item);

		if (curr_batch_size + curr_size > leaf_data_size ||
		    batch.nr == max_batch_size) {
			ret = insert_delayed_items_batch(trans, log, path,
							 &batch, first);
			if (ret)
				goto out;
			batch_idx = 0;
			batch.nr = 0;
			batch.total_data_size = 0;
			curr_batch_size = 0;
			first = curr;
		}

		ins_sizes[batch_idx] = curr->data_len;
		ins_keys[batch_idx].objectid = ino;
		ins_keys[batch_idx].type = BTRFS_DIR_INDEX_KEY;
		ins_keys[batch_idx].offset = curr->index;
		curr_batch_size += curr_size;
		batch.total_data_size += curr->data_len;
		batch.nr++;
		batch_idx++;
		curr = list_next_entry(curr, log_list);
	}

	ASSERT(batch.nr >= 1);
	ret = insert_delayed_items_batch(trans, log, path, &batch, first);

	curr = list_last_entry(delayed_ins_list, struct btrfs_delayed_item,
			       log_list);
	inode->last_dir_index_offset = curr->index;
out:
	kfree(ins_data);

	return ret;
}

static int log_delayed_deletions_full(struct btrfs_trans_handle *trans,
				      struct btrfs_inode *inode,
				      struct btrfs_path *path,
				      const struct list_head *delayed_del_list,
				      struct btrfs_log_ctx *ctx)
{
	const u64 ino = btrfs_ino(inode);
	const struct btrfs_delayed_item *curr;

	curr = list_first_entry(delayed_del_list, struct btrfs_delayed_item,
				log_list);

	while (!list_entry_is_head(curr, delayed_del_list, log_list)) {
		u64 first_dir_index = curr->index;
		u64 last_dir_index;
		const struct btrfs_delayed_item *next;
		int ret;

		/*
		 * Find a range of consecutive dir index items to delete. Like
		 * this we log a single dir range item spanning several contiguous
		 * dir items instead of logging one range item per dir index item.
		 */
		next = list_next_entry(curr, log_list);
		while (!list_entry_is_head(next, delayed_del_list, log_list)) {
			if (next->index != curr->index + 1)
				break;
			curr = next;
			next = list_next_entry(next, log_list);
		}

		last_dir_index = curr->index;
		ASSERT(last_dir_index >= first_dir_index);

		ret = insert_dir_log_key(trans, inode->root->log_root, path,
					 ino, first_dir_index, last_dir_index);
		if (ret)
			return ret;
		curr = list_next_entry(curr, log_list);
	}

	return 0;
}

static int batch_delete_dir_index_items(struct btrfs_trans_handle *trans,
					struct btrfs_inode *inode,
					struct btrfs_path *path,
					const struct list_head *delayed_del_list,
					const struct btrfs_delayed_item *first,
					const struct btrfs_delayed_item **last_ret)
{
	const struct btrfs_delayed_item *next;
	struct extent_buffer *leaf = path->nodes[0];
	const int last_slot = btrfs_header_nritems(leaf) - 1;
	int slot = path->slots[0] + 1;
	const u64 ino = btrfs_ino(inode);

	next = list_next_entry(first, log_list);

	while (slot < last_slot &&
	       !list_entry_is_head(next, delayed_del_list, log_list)) {
		struct btrfs_key key;

		btrfs_item_key_to_cpu(leaf, &key, slot);
		if (key.objectid != ino ||
		    key.type != BTRFS_DIR_INDEX_KEY ||
		    key.offset != next->index)
			break;

		slot++;
		*last_ret = next;
		next = list_next_entry(next, log_list);
	}

	return btrfs_del_items(trans, inode->root->log_root, path,
			       path->slots[0], slot - path->slots[0]);
}

static int log_delayed_deletions_incremental(struct btrfs_trans_handle *trans,
					     struct btrfs_inode *inode,
					     struct btrfs_path *path,
					     const struct list_head *delayed_del_list,
					     struct btrfs_log_ctx *ctx)
{
	struct btrfs_root *log = inode->root->log_root;
	const struct btrfs_delayed_item *curr;
	u64 last_range_start = 0;
	u64 last_range_end = 0;
	struct btrfs_key key;

	key.objectid = btrfs_ino(inode);
	key.type = BTRFS_DIR_INDEX_KEY;
	curr = list_first_entry(delayed_del_list, struct btrfs_delayed_item,
				log_list);

	while (!list_entry_is_head(curr, delayed_del_list, log_list)) {
		const struct btrfs_delayed_item *last = curr;
		u64 first_dir_index = curr->index;
		u64 last_dir_index;
		bool deleted_items = false;
		int ret;

		key.offset = curr->index;
		ret = btrfs_search_slot(trans, log, &key, path, -1, 1);
		if (ret < 0) {
			return ret;
		} else if (ret == 0) {
			ret = batch_delete_dir_index_items(trans, inode, path,
							   delayed_del_list, curr,
							   &last);
			if (ret)
				return ret;
			deleted_items = true;
		}

		btrfs_release_path(path);

		/*
		 * If we deleted items from the leaf, it means we have a range
		 * item logging their range, so no need to add one or update an
		 * existing one. Otherwise we have to log a dir range item.
		 */
		if (deleted_items)
			goto next_batch;

		last_dir_index = last->index;
		ASSERT(last_dir_index >= first_dir_index);
		/*
		 * If this range starts right after where the previous one ends,
		 * then we want to reuse the previous range item and change its
		 * end offset to the end of this range. This is just to minimize
		 * leaf space usage, by avoiding adding a new range item.
		 */
		if (last_range_end != 0 && first_dir_index == last_range_end + 1)
			first_dir_index = last_range_start;

		ret = insert_dir_log_key(trans, log, path, key.objectid,
					 first_dir_index, last_dir_index);
		if (ret)
			return ret;

		last_range_start = first_dir_index;
		last_range_end = last_dir_index;
next_batch:
		curr = list_next_entry(last, log_list);
	}

	return 0;
}

static int log_delayed_deletion_items(struct btrfs_trans_handle *trans,
				      struct btrfs_inode *inode,
				      struct btrfs_path *path,
				      const struct list_head *delayed_del_list,
				      struct btrfs_log_ctx *ctx)
{
	/*
	 * We are deleting dir index items from the log tree or adding range
	 * items to it.
	 */
	lockdep_assert_held(&inode->log_mutex);

	if (list_empty(delayed_del_list))
		return 0;

	if (ctx->logged_before)
		return log_delayed_deletions_incremental(trans, inode, path,
							 delayed_del_list, ctx);

	return log_delayed_deletions_full(trans, inode, path, delayed_del_list,
					  ctx);
}

/*
 * Similar logic as for log_new_dir_dentries(), but it iterates over the delayed
 * items instead of the subvolume tree.
 */
static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
				    struct btrfs_inode *inode,
				    const struct list_head *delayed_ins_list,
				    struct btrfs_log_ctx *ctx)
{
	const bool orig_log_new_dentries = ctx->log_new_dentries;
	struct btrfs_delayed_item *item;
	int ret = 0;

	/*
	 * No need for the log mutex, plus to avoid potential deadlocks or
	 * lockdep annotations due to nesting of delayed inode mutexes and log
	 * mutexes.
	 */
	lockdep_assert_not_held(&inode->log_mutex);

	ASSERT(!ctx->logging_new_delayed_dentries);
	ctx->logging_new_delayed_dentries = true;

	list_for_each_entry(item, delayed_ins_list, log_list) {
		struct btrfs_dir_item *dir_item;
		struct btrfs_inode *di_inode;
		struct btrfs_key key;
		int log_mode = LOG_INODE_EXISTS;

		dir_item = (struct btrfs_dir_item *)item->data;
		btrfs_disk_key_to_cpu(&key, &dir_item->location);

		if (key.type == BTRFS_ROOT_ITEM_KEY)
			continue;

		di_inode = btrfs_iget_logging(key.objectid, inode->root);
		if (IS_ERR(di_inode)) {
			ret = PTR_ERR(di_inode);
			break;
		}

		if (!need_log_inode(trans, di_inode)) {
			btrfs_add_delayed_iput(di_inode);
			continue;
		}

		if (btrfs_stack_dir_ftype(dir_item) == BTRFS_FT_DIR)
			log_mode = LOG_INODE_ALL;

		ctx->log_new_dentries = false;
		ret = btrfs_log_inode(trans, di_inode, log_mode, ctx);

		if (!ret && ctx->log_new_dentries)
			ret = log_new_dir_dentries(trans, di_inode, ctx);

		btrfs_add_delayed_iput(di_inode);

		if (ret)
			break;
	}

	ctx->log_new_dentries = orig_log_new_dentries;
	ctx->logging_new_delayed_dentries = false;

	return ret;
}

/* log a single inode in the tree log.
 * At least one parent directory for this inode must exist in the tree
 * or be logged already.
 *
 * Any items from this inode changed by the current transaction are copied
 * to the log tree.  An extra reference is taken on any extents in this
 * file, allowing us to avoid a whole pile of corner cases around logging
 * blocks that have been removed from the tree.
 *
 * See LOG_INODE_ALL and related defines for a description of what inode_only
 * does.
 *
 * This handles both files and directories.
 */
static int btrfs_log_inode(struct btrfs_trans_handle *trans,
			   struct btrfs_inode *inode,
			   int inode_only,
			   struct btrfs_log_ctx *ctx)
{
	struct btrfs_path *path;
	struct btrfs_path *dst_path;
	struct btrfs_key min_key;
	struct btrfs_key max_key;
	struct btrfs_root *log = inode->root->log_root;
	int ret;
	bool fast_search = false;
	u64 ino = btrfs_ino(inode);
	struct extent_map_tree *em_tree = &inode->extent_tree;
	u64 logged_isize = 0;
	bool need_log_inode_item = true;
	bool xattrs_logged = false;
	bool inode_item_dropped = true;
	bool full_dir_logging = false;
	LIST_HEAD(delayed_ins_list);
	LIST_HEAD(delayed_del_list);

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
	dst_path = btrfs_alloc_path();
	if (!dst_path) {
		btrfs_free_path(path);
		return -ENOMEM;
	}

	min_key.objectid = ino;
	min_key.type = BTRFS_INODE_ITEM_KEY;
	min_key.offset = 0;

	max_key.objectid = ino;


	/* today the code can only do partial logging of directories */
	if (S_ISDIR(inode->vfs_inode.i_mode) ||
	    (!test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
		       &inode->runtime_flags) &&
	     inode_only >= LOG_INODE_EXISTS))
		max_key.type = BTRFS_XATTR_ITEM_KEY;
	else
		max_key.type = (u8)-1;
	max_key.offset = (u64)-1;

	if (S_ISDIR(inode->vfs_inode.i_mode) && inode_only == LOG_INODE_ALL)
		full_dir_logging = true;

	/*
	 * If we are logging a directory while we are logging dentries of the
	 * delayed items of some other inode, then we need to flush the delayed
	 * items of this directory and not log the delayed items directly. This
	 * is to prevent more than one level of recursion into btrfs_log_inode()
	 * by having something like this:
	 *
	 *     $ mkdir -p a/b/c/d/e/f/g/h/...
	 *     $ xfs_io -c "fsync" a
	 *
	 * Where all directories in the path did not exist before and are
	 * created in the current transaction.
	 * So in such a case we directly log the delayed items of the main
	 * directory ("a") without flushing them first, while for each of its
	 * subdirectories we flush their delayed items before logging them.
	 * This prevents a potential unbounded recursion like this:
	 *
	 * btrfs_log_inode()
	 *   log_new_delayed_dentries()
	 *      btrfs_log_inode()
	 *        log_new_delayed_dentries()
	 *          btrfs_log_inode()
	 *            log_new_delayed_dentries()
	 *              (...)
	 *
	 * We have thresholds for the maximum number of delayed items to have in
	 * memory, and once they are hit, the items are flushed asynchronously.
	 * However the limit is quite high, so lets prevent deep levels of
	 * recursion to happen by limiting the maximum depth to be 1.
	 */
	if (full_dir_logging && ctx->logging_new_delayed_dentries) {
		ret = btrfs_commit_inode_delayed_items(trans, inode);
		if (ret)
			goto out;
	}

	mutex_lock(&inode->log_mutex);

	/*
	 * For symlinks, we must always log their content, which is stored in an
	 * inline extent, otherwise we could end up with an empty symlink after
	 * log replay, which is invalid on linux (symlink(2) returns -ENOENT if
	 * one attempts to create an empty symlink).
	 * We don't need to worry about flushing delalloc, because when we create
	 * the inline extent when the symlink is created (we never have delalloc
	 * for symlinks).
	 */
	if (S_ISLNK(inode->vfs_inode.i_mode))
		inode_only = LOG_INODE_ALL;

	/*
	 * Before logging the inode item, cache the value returned by
	 * inode_logged(), because after that we have the need to figure out if
	 * the inode was previously logged in this transaction.
	 */
	ret = inode_logged(trans, inode, path);
	if (ret < 0)
		goto out_unlock;
	ctx->logged_before = (ret == 1);
	ret = 0;

	/*
	 * This is for cases where logging a directory could result in losing a
	 * a file after replaying the log. For example, if we move a file from a
	 * directory A to a directory B, then fsync directory A, we have no way
	 * to known the file was moved from A to B, so logging just A would
	 * result in losing the file after a log replay.
	 */
	if (full_dir_logging && inode->last_unlink_trans >= trans->transid) {
		ret = BTRFS_LOG_FORCE_COMMIT;
		goto out_unlock;
	}

	/*
	 * a brute force approach to making sure we get the most uptodate
	 * copies of everything.
	 */
	if (S_ISDIR(inode->vfs_inode.i_mode)) {
		clear_bit(BTRFS_INODE_COPY_EVERYTHING, &inode->runtime_flags);
		if (ctx->logged_before)
			ret = drop_inode_items(trans, log, path, inode,
					       BTRFS_XATTR_ITEM_KEY);
	} else {
		if (inode_only == LOG_INODE_EXISTS) {
			/*
			 * Make sure the new inode item we write to the log has
			 * the same isize as the current one (if it exists).
			 * This is necessary to prevent data loss after log
			 * replay, and also to prevent doing a wrong expanding
			 * truncate - for e.g. create file, write 4K into offset
			 * 0, fsync, write 4K into offset 4096, add hard link,
			 * fsync some other file (to sync log), power fail - if
			 * we use the inode's current i_size, after log replay
			 * we get a 8Kb file, with the last 4Kb extent as a hole
			 * (zeroes), as if an expanding truncate happened,
			 * instead of getting a file of 4Kb only.
			 */
			ret = get_inode_size_to_log(trans, inode, path, &logged_isize);
			if (ret)
				goto out_unlock;
		}
		if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
			     &inode->runtime_flags)) {
			if (inode_only == LOG_INODE_EXISTS) {
				max_key.type = BTRFS_XATTR_ITEM_KEY;
				if (ctx->logged_before)
					ret = drop_inode_items(trans, log, path,
							       inode, max_key.type);
			} else {
				clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
					  &inode->runtime_flags);
				clear_bit(BTRFS_INODE_COPY_EVERYTHING,
					  &inode->runtime_flags);
				if (ctx->logged_before)
					ret = truncate_inode_items(trans, log,
								   inode, 0, 0);
			}
		} else if (test_and_clear_bit(BTRFS_INODE_COPY_EVERYTHING,
					      &inode->runtime_flags) ||
			   inode_only == LOG_INODE_EXISTS) {
			if (inode_only == LOG_INODE_ALL)
				fast_search = true;
			max_key.type = BTRFS_XATTR_ITEM_KEY;
			if (ctx->logged_before)
				ret = drop_inode_items(trans, log, path, inode,
						       max_key.type);
		} else {
			if (inode_only == LOG_INODE_ALL)
				fast_search = true;
			inode_item_dropped = false;
			goto log_extents;
		}

	}
	if (ret)
		goto out_unlock;

	/*
	 * If we are logging a directory in full mode, collect the delayed items
	 * before iterating the subvolume tree, so that we don't miss any new
	 * dir index items in case they get flushed while or right after we are
	 * iterating the subvolume tree.
	 */
	if (full_dir_logging && !ctx->logging_new_delayed_dentries)
		btrfs_log_get_delayed_items(inode, &delayed_ins_list,
					    &delayed_del_list);

	/*
	 * If we are fsyncing a file with 0 hard links, then commit the delayed
	 * inode because the last inode ref (or extref) item may still be in the
	 * subvolume tree and if we log it the file will still exist after a log
	 * replay. So commit the delayed inode to delete that last ref and we
	 * skip logging it.
	 */
	if (inode->vfs_inode.i_nlink == 0) {
		ret = btrfs_commit_inode_delayed_inode(inode);
		if (ret)
			goto out_unlock;
	}

	ret = copy_inode_items_to_log(trans, inode, &min_key, &max_key,
				      path, dst_path, logged_isize,
				      inode_only, ctx,
				      &need_log_inode_item);
	if (ret)
		goto out_unlock;

	btrfs_release_path(path);
	btrfs_release_path(dst_path);
	ret = btrfs_log_all_xattrs(trans, inode, path, dst_path, ctx);
	if (ret)
		goto out_unlock;
	xattrs_logged = true;
	if (max_key.type >= BTRFS_EXTENT_DATA_KEY && !fast_search) {
		btrfs_release_path(path);
		btrfs_release_path(dst_path);
		ret = btrfs_log_holes(trans, inode, path);
		if (ret)
			goto out_unlock;
	}
log_extents:
	btrfs_release_path(path);
	btrfs_release_path(dst_path);
	if (need_log_inode_item) {
		ret = log_inode_item(trans, log, dst_path, inode, inode_item_dropped);
		if (ret)
			goto out_unlock;
		/*
		 * If we are doing a fast fsync and the inode was logged before
		 * in this transaction, we don't need to log the xattrs because
		 * they were logged before. If xattrs were added, changed or
		 * deleted since the last time we logged the inode, then we have
		 * already logged them because the inode had the runtime flag
		 * BTRFS_INODE_COPY_EVERYTHING set.
		 */
		if (!xattrs_logged && inode->logged_trans < trans->transid) {
			ret = btrfs_log_all_xattrs(trans, inode, path, dst_path, ctx);
			if (ret)
				goto out_unlock;
			btrfs_release_path(path);
		}
	}
	if (fast_search) {
		ret = btrfs_log_changed_extents(trans, inode, dst_path, ctx);
		if (ret)
			goto out_unlock;
	} else if (inode_only == LOG_INODE_ALL) {
		struct extent_map *em, *n;

		write_lock(&em_tree->lock);
		list_for_each_entry_safe(em, n, &em_tree->modified_extents, list)
			list_del_init(&em->list);
		write_unlock(&em_tree->lock);
	}

	if (full_dir_logging) {
		ret = log_directory_changes(trans, inode, path, dst_path, ctx);
		if (ret)
			goto out_unlock;
		ret = log_delayed_insertion_items(trans, inode, path,
						  &delayed_ins_list, ctx);
		if (ret)
			goto out_unlock;
		ret = log_delayed_deletion_items(trans, inode, path,
						 &delayed_del_list, ctx);
		if (ret)
			goto out_unlock;
	}

	spin_lock(&inode->lock);
	inode->logged_trans = trans->transid;
	/*
	 * Don't update last_log_commit if we logged that an inode exists.
	 * We do this for three reasons:
	 *
	 * 1) We might have had buffered writes to this inode that were
	 *    flushed and had their ordered extents completed in this
	 *    transaction, but we did not previously log the inode with
	 *    LOG_INODE_ALL. Later the inode was evicted and after that
	 *    it was loaded again and this LOG_INODE_EXISTS log operation
	 *    happened. We must make sure that if an explicit fsync against
	 *    the inode is performed later, it logs the new extents, an
	 *    updated inode item, etc, and syncs the log. The same logic
	 *    applies to direct IO writes instead of buffered writes.
	 *
	 * 2) When we log the inode with LOG_INODE_EXISTS, its inode item
	 *    is logged with an i_size of 0 or whatever value was logged
	 *    before. If later the i_size of the inode is increased by a
	 *    truncate operation, the log is synced through an fsync of
	 *    some other inode and then finally an explicit fsync against
	 *    this inode is made, we must make sure this fsync logs the
	 *    inode with the new i_size, the hole between old i_size and
	 *    the new i_size, and syncs the log.
	 *
	 * 3) If we are logging that an ancestor inode exists as part of
	 *    logging a new name from a link or rename operation, don't update
	 *    its last_log_commit - otherwise if an explicit fsync is made
	 *    against an ancestor, the fsync considers the inode in the log
	 *    and doesn't sync the log, resulting in the ancestor missing after
	 *    a power failure unless the log was synced as part of an fsync
	 *    against any other unrelated inode.
	 */
	if (!ctx->logging_new_name && inode_only != LOG_INODE_EXISTS)
		inode->last_log_commit = inode->last_sub_trans;
	spin_unlock(&inode->lock);

	/*
	 * Reset the last_reflink_trans so that the next fsync does not need to
	 * go through the slower path when logging extents and their checksums.
	 */
	if (inode_only == LOG_INODE_ALL)
		inode->last_reflink_trans = 0;

out_unlock:
	mutex_unlock(&inode->log_mutex);
out:
	btrfs_free_path(path);
	btrfs_free_path(dst_path);

	if (ret)
		free_conflicting_inodes(ctx);
	else
		ret = log_conflicting_inodes(trans, inode->root, ctx);

	if (full_dir_logging && !ctx->logging_new_delayed_dentries) {
		if (!ret)
			ret = log_new_delayed_dentries(trans, inode,
						       &delayed_ins_list, ctx);

		btrfs_log_put_delayed_items(inode, &delayed_ins_list,
					    &delayed_del_list);
	}

	return ret;
}

static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
				 struct btrfs_inode *inode,
				 struct btrfs_log_ctx *ctx)
{
	int ret;
	BTRFS_PATH_AUTO_FREE(path);
	struct btrfs_key key;
	struct btrfs_root *root = inode->root;
	const u64 ino = btrfs_ino(inode);

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
	path->skip_locking = 1;
	path->search_commit_root = 1;

	key.objectid = ino;
	key.type = BTRFS_INODE_REF_KEY;
	key.offset = 0;
	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	if (ret < 0)
		return ret;

	while (true) {
		struct extent_buffer *leaf = path->nodes[0];
		int slot = path->slots[0];
		u32 cur_offset = 0;
		u32 item_size;
		unsigned long ptr;

		if (slot >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(root, path);
			if (ret < 0)
				return ret;
			if (ret > 0)
				break;
			continue;
		}

		btrfs_item_key_to_cpu(leaf, &key, slot);
		/* BTRFS_INODE_EXTREF_KEY is BTRFS_INODE_REF_KEY + 1 */
		if (key.objectid != ino || key.type > BTRFS_INODE_EXTREF_KEY)
			break;

		item_size = btrfs_item_size(leaf, slot);
		ptr = btrfs_item_ptr_offset(leaf, slot);
		while (cur_offset < item_size) {
			struct btrfs_key inode_key;
			struct btrfs_inode *dir_inode;

			inode_key.type = BTRFS_INODE_ITEM_KEY;
			inode_key.offset = 0;

			if (key.type == BTRFS_INODE_EXTREF_KEY) {
				struct btrfs_inode_extref *extref;

				extref = (struct btrfs_inode_extref *)
					(ptr + cur_offset);
				inode_key.objectid = btrfs_inode_extref_parent(
					leaf, extref);
				cur_offset += sizeof(*extref);
				cur_offset += btrfs_inode_extref_name_len(leaf,
					extref);
			} else {
				inode_key.objectid = key.offset;
				cur_offset = item_size;
			}

			dir_inode = btrfs_iget_logging(inode_key.objectid, root);
			/*
			 * If the parent inode was deleted, return an error to
			 * fallback to a transaction commit. This is to prevent
			 * getting an inode that was moved from one parent A to
			 * a parent B, got its former parent A deleted and then
			 * it got fsync'ed, from existing at both parents after
			 * a log replay (and the old parent still existing).
			 * Example:
			 *
			 * mkdir /mnt/A
			 * mkdir /mnt/B
			 * touch /mnt/B/bar
			 * sync
			 * mv /mnt/B/bar /mnt/A/bar
			 * mv -T /mnt/A /mnt/B
			 * fsync /mnt/B/bar
			 * <power fail>
			 *
			 * If we ignore the old parent B which got deleted,
			 * after a log replay we would have file bar linked
			 * at both parents and the old parent B would still
			 * exist.
			 */
			if (IS_ERR(dir_inode))
				return PTR_ERR(dir_inode);

			if (!need_log_inode(trans, dir_inode)) {
				btrfs_add_delayed_iput(dir_inode);
				continue;
			}

			ctx->log_new_dentries = false;
			ret = btrfs_log_inode(trans, dir_inode, LOG_INODE_ALL, ctx);
			if (!ret && ctx->log_new_dentries)
				ret = log_new_dir_dentries(trans, dir_inode, ctx);
			btrfs_add_delayed_iput(dir_inode);
			if (ret)
				return ret;
		}
		path->slots[0]++;
	}
	return 0;
}

static int log_new_ancestors(struct btrfs_trans_handle *trans,
			     struct btrfs_root *root,
			     struct btrfs_path *path,
			     struct btrfs_log_ctx *ctx)
{
	struct btrfs_key found_key;

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

	while (true) {
		struct extent_buffer *leaf;
		int slot;
		struct btrfs_key search_key;
		struct btrfs_inode *inode;
		u64 ino;
		int ret = 0;

		btrfs_release_path(path);

		ino = found_key.offset;

		search_key.objectid = found_key.offset;
		search_key.type = BTRFS_INODE_ITEM_KEY;
		search_key.offset = 0;
		inode = btrfs_iget_logging(ino, root);
		if (IS_ERR(inode))
			return PTR_ERR(inode);

		if (inode->generation >= trans->transid &&
		    need_log_inode(trans, inode))
			ret = btrfs_log_inode(trans, inode, LOG_INODE_EXISTS, ctx);
		btrfs_add_delayed_iput(inode);
		if (ret)
			return ret;

		if (search_key.objectid == BTRFS_FIRST_FREE_OBJECTID)
			break;

		search_key.type = BTRFS_INODE_REF_KEY;
		ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
		if (ret < 0)
			return ret;

		leaf = path->nodes[0];
		slot = path->slots[0];
		if (slot >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(root, path);
			if (ret < 0)
				return ret;
			else if (ret > 0)
				return -ENOENT;
			leaf = path->nodes[0];
			slot = path->slots[0];
		}

		btrfs_item_key_to_cpu(leaf, &found_key, slot);
		if (found_key.objectid != search_key.objectid ||
		    found_key.type != BTRFS_INODE_REF_KEY)
			return -ENOENT;
	}
	return 0;
}

static int log_new_ancestors_fast(struct btrfs_trans_handle *trans,
				  struct btrfs_inode *inode,
				  struct dentry *parent,
				  struct btrfs_log_ctx *ctx)
{
	struct btrfs_root *root = inode->root;
	struct dentry *old_parent = NULL;
	struct super_block *sb = inode->vfs_inode.i_sb;
	int ret = 0;

	while (true) {
		if (!parent || d_really_is_negative(parent) ||
		    sb != parent->d_sb)
			break;

		inode = BTRFS_I(d_inode(parent));
		if (root != inode->root)
			break;

		if (inode->generation >= trans->transid &&
		    need_log_inode(trans, inode)) {
			ret = btrfs_log_inode(trans, inode,
					      LOG_INODE_EXISTS, ctx);
			if (ret)
				break;
		}
		if (IS_ROOT(parent))
			break;

		parent = dget_parent(parent);
		dput(old_parent);
		old_parent = parent;
	}
	dput(old_parent);

	return ret;
}

static int log_all_new_ancestors(struct btrfs_trans_handle *trans,
				 struct btrfs_inode *inode,
				 struct dentry *parent,
				 struct btrfs_log_ctx *ctx)
{
	struct btrfs_root *root = inode->root;
	const u64 ino = btrfs_ino(inode);
	BTRFS_PATH_AUTO_FREE(path);
	struct btrfs_key search_key;
	int ret;

	/*
	 * For a single hard link case, go through a fast path that does not
	 * need to iterate the fs/subvolume tree.
	 */
	if (inode->vfs_inode.i_nlink < 2)
		return log_new_ancestors_fast(trans, inode, parent, ctx);

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

	search_key.objectid = ino;
	search_key.type = BTRFS_INODE_REF_KEY;
	search_key.offset = 0;
again:
	ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
	if (ret < 0)
		return ret;
	if (ret == 0)
		path->slots[0]++;

	while (true) {
		struct extent_buffer *leaf = path->nodes[0];
		int slot = path->slots[0];
		struct btrfs_key found_key;

		if (slot >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(root, path);
			if (ret < 0)
				return ret;
			if (ret > 0)
				break;
			continue;
		}

		btrfs_item_key_to_cpu(leaf, &found_key, slot);
		if (found_key.objectid != ino ||
		    found_key.type > BTRFS_INODE_EXTREF_KEY)
			break;

		/*
		 * Don't deal with extended references because they are rare
		 * cases and too complex to deal with (we would need to keep
		 * track of which subitem we are processing for each item in
		 * this loop, etc). So just return some error to fallback to
		 * a transaction commit.
		 */
		if (found_key.type == BTRFS_INODE_EXTREF_KEY)
			return -EMLINK;

		/*
		 * Logging ancestors needs to do more searches on the fs/subvol
		 * tree, so it releases the path as needed to avoid deadlocks.
		 * Keep track of the last inode ref key and resume from that key
		 * after logging all new ancestors for the current hard link.
		 */
		memcpy(&search_key, &found_key, sizeof(search_key));

		ret = log_new_ancestors(trans, root, path, ctx);
		if (ret)
			return ret;
		btrfs_release_path(path);
		goto again;
	}
	return 0;
}

/*
 * helper function around btrfs_log_inode to make sure newly created
 * parent directories also end up in the log.  A minimal inode and backref
 * only logging is done of any parent directories that are older than
 * the last committed transaction
 */
static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
				  struct btrfs_inode *inode,
				  struct dentry *parent,
				  int inode_only,
				  struct btrfs_log_ctx *ctx)
{
	struct btrfs_root *root = inode->root;
	struct btrfs_fs_info *fs_info = root->fs_info;
	int ret = 0;
	bool log_dentries;

	if (btrfs_test_opt(fs_info, NOTREELOG))
		return BTRFS_LOG_FORCE_COMMIT;

	if (btrfs_root_refs(&root->root_item) == 0)
		return BTRFS_LOG_FORCE_COMMIT;

	/*
	 * If we're logging an inode from a subvolume created in the current
	 * transaction we must force a commit since the root is not persisted.
	 */
	if (btrfs_root_generation(&root->root_item) == trans->transid)
		return BTRFS_LOG_FORCE_COMMIT;

	/* Skip already logged inodes and without new extents. */
	if (btrfs_inode_in_log(inode, trans->transid) &&
	    list_empty(&ctx->ordered_extents))
		return BTRFS_NO_LOG_SYNC;

	ret = start_log_trans(trans, root, ctx);
	if (ret)
		return ret;

	ret = btrfs_log_inode(trans, inode, inode_only, ctx);
	if (ret)
		goto end_trans;

	/*
	 * for regular files, if its inode is already on disk, we don't
	 * have to worry about the parents at all.  This is because
	 * we can use the last_unlink_trans field to record renames
	 * and other fun in this file.
	 */
	if (S_ISREG(inode->vfs_inode.i_mode) &&
	    inode->generation < trans->transid &&
	    inode->last_unlink_trans < trans->transid) {
		ret = 0;
		goto end_trans;
	}

	/*
	 * Track if we need to log dentries because ctx->log_new_dentries can
	 * be modified in the call chains below.
	 */
	log_dentries = ctx->log_new_dentries;

	/*
	 * On unlink we must make sure all our current and old parent directory
	 * inodes are fully logged. This is to prevent leaving dangling
	 * directory index entries in directories that were our parents but are
	 * not anymore. Not doing this results in old parent directory being
	 * impossible to delete after log replay (rmdir will always fail with
	 * error -ENOTEMPTY).
	 *
	 * Example 1:
	 *
	 * mkdir testdir
	 * touch testdir/foo
	 * ln testdir/foo testdir/bar
	 * sync
	 * unlink testdir/bar
	 * xfs_io -c fsync testdir/foo
	 * <power failure>
	 * mount fs, triggers log replay
	 *
	 * If we don't log the parent directory (testdir), after log replay the
	 * directory still has an entry pointing to the file inode using the bar
	 * name, but a matching BTRFS_INODE_[REF|EXTREF]_KEY does not exist and
	 * the file inode has a link count of 1.
	 *
	 * Example 2:
	 *
	 * mkdir testdir
	 * touch foo
	 * ln foo testdir/foo2
	 * ln foo testdir/foo3
	 * sync
	 * unlink testdir/foo3
	 * xfs_io -c fsync foo
	 * <power failure>
	 * mount fs, triggers log replay
	 *
	 * Similar as the first example, after log replay the parent directory
	 * testdir still has an entry pointing to the inode file with name foo3
	 * but the file inode does not have a matching BTRFS_INODE_REF_KEY item
	 * and has a link count of 2.
	 */
	if (inode->last_unlink_trans >= trans->transid) {
		ret = btrfs_log_all_parents(trans, inode, ctx);
		if (ret)
			goto end_trans;
	}

	ret = log_all_new_ancestors(trans, inode, parent, ctx);
	if (ret)
		goto end_trans;

	if (log_dentries)
		ret = log_new_dir_dentries(trans, inode, ctx);
end_trans:
	if (ret < 0) {
		btrfs_set_log_full_commit(trans);
		ret = BTRFS_LOG_FORCE_COMMIT;
	}

	if (ret)
		btrfs_remove_log_ctx(root, ctx);
	btrfs_end_log_trans(root);

	return ret;
}

/*
 * it is not safe to log dentry if the chunk root has added new
 * chunks.  This returns 0 if the dentry was logged, and 1 otherwise.
 * If this returns 1, you must commit the transaction to safely get your
 * data on disk.
 */
int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans,
			  struct dentry *dentry,
			  struct btrfs_log_ctx *ctx)
{
	struct dentry *parent = dget_parent(dentry);
	int ret;

	ret = btrfs_log_inode_parent(trans, BTRFS_I(d_inode(dentry)), parent,
				     LOG_INODE_ALL, ctx);
	dput(parent);

	return ret;
}

/*
 * should be called during mount to recover any replay any log trees
 * from the FS
 */
int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
{
	int ret;
	struct btrfs_path *path;
	struct btrfs_trans_handle *trans;
	struct btrfs_key key;
	struct btrfs_fs_info *fs_info = log_root_tree->fs_info;
	struct walk_control wc = {
		.process_func = process_one_buffer,
		.stage = LOG_WALK_PIN_ONLY,
	};

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

	set_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags);

	trans = btrfs_start_transaction(fs_info->tree_root, 0);
	if (IS_ERR(trans)) {
		ret = PTR_ERR(trans);
		goto error;
	}

	wc.trans = trans;
	wc.pin = true;
	wc.log = log_root_tree;

	ret = walk_log_tree(&wc);
	wc.log = NULL;
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		goto error;
	}

again:
	key.objectid = BTRFS_TREE_LOG_OBJECTID;
	key.type = BTRFS_ROOT_ITEM_KEY;
	key.offset = (u64)-1;

	while (1) {
		struct btrfs_key found_key;

		ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0);

		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			goto error;
		}
		if (ret > 0) {
			if (path->slots[0] == 0)
				break;
			path->slots[0]--;
		}
		btrfs_item_key_to_cpu(path->nodes[0], &found_key,
				      path->slots[0]);
		btrfs_release_path(path);
		if (found_key.objectid != BTRFS_TREE_LOG_OBJECTID)
			break;

		wc.log = btrfs_read_tree_root(log_root_tree, &found_key);
		if (IS_ERR(wc.log)) {
			ret = PTR_ERR(wc.log);
			wc.log = NULL;
			btrfs_abort_transaction(trans, ret);
			goto error;
		}

		wc.root = btrfs_get_fs_root(fs_info, found_key.offset, true);
		if (IS_ERR(wc.root)) {
			ret = PTR_ERR(wc.root);
			wc.root = NULL;
			if (unlikely(ret != -ENOENT)) {
				btrfs_abort_transaction(trans, ret);
				goto error;
			}

			/*
			 * We didn't find the subvol, likely because it was
			 * deleted.  This is ok, simply skip this log and go to
			 * the next one.
			 *
			 * We need to exclude the root because we can't have
			 * other log replays overwriting this log as we'll read
			 * it back in a few more times.  This will keep our
			 * block from being modified, and we'll just bail for
			 * each subsequent pass.
			 */
			ret = btrfs_pin_extent_for_log_replay(trans, wc.log->node);
			if (unlikely(ret)) {
				btrfs_abort_transaction(trans, ret);
				goto error;
			}
			goto next;
		}

		wc.root->log_root = wc.log;
		ret = btrfs_record_root_in_trans(trans, wc.root);
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			goto next;
		}

		ret = walk_log_tree(&wc);
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			goto next;
		}

		if (wc.stage == LOG_WALK_REPLAY_ALL) {
			struct btrfs_root *root = wc.root;

			wc.subvol_path = path;
			ret = fixup_inode_link_counts(&wc);
			wc.subvol_path = NULL;
			if (unlikely(ret)) {
				btrfs_abort_transaction(trans, ret);
				goto next;
			}
			/*
			 * We have just replayed everything, and the highest
			 * objectid of fs roots probably has changed in case
			 * some inode_item's got replayed.
			 *
			 * root->objectid_mutex is not acquired as log replay
			 * could only happen during mount.
			 */
			ret = btrfs_init_root_free_objectid(root);
			if (unlikely(ret)) {
				btrfs_abort_transaction(trans, ret);
				goto next;
			}
		}
next:
		if (wc.root) {
			wc.root->log_root = NULL;
			btrfs_put_root(wc.root);
		}
		btrfs_put_root(wc.log);
		wc.log = NULL;

		if (ret)
			goto error;
		if (found_key.offset == 0)
			break;
		key.offset = found_key.offset - 1;
	}
	btrfs_release_path(path);

	/* step one is to pin it all, step two is to replay just inodes */
	if (wc.pin) {
		wc.pin = false;
		wc.process_func = replay_one_buffer;
		wc.stage = LOG_WALK_REPLAY_INODES;
		goto again;
	}
	/* step three is to replay everything */
	if (wc.stage < LOG_WALK_REPLAY_ALL) {
		wc.stage++;
		goto again;
	}

	btrfs_free_path(path);

	/* step 4: commit the transaction, which also unpins the blocks */
	ret = btrfs_commit_transaction(trans);
	if (ret)
		return ret;

	clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags);

	return 0;
error:
	if (wc.trans)
		btrfs_end_transaction(wc.trans);
	btrfs_put_root(wc.log);
	clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags);
	btrfs_free_path(path);
	return ret;
}

/*
 * there are some corner cases where we want to force a full
 * commit instead of allowing a directory to be logged.
 *
 * They revolve around files there were unlinked from the directory, and
 * this function updates the parent directory so that a full commit is
 * properly done if it is fsync'd later after the unlinks are done.
 *
 * Must be called before the unlink operations (updates to the subvolume tree,
 * inodes, etc) are done.
 */
void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
			     struct btrfs_inode *dir, struct btrfs_inode *inode,
			     bool for_rename)
{
	/*
	 * when we're logging a file, if it hasn't been renamed
	 * or unlinked, and its inode is fully committed on disk,
	 * we don't have to worry about walking up the directory chain
	 * to log its parents.
	 *
	 * So, we use the last_unlink_trans field to put this transid
	 * into the file.  When the file is logged we check it and
	 * don't log the parents if the file is fully on disk.
	 */
	mutex_lock(&inode->log_mutex);
	inode->last_unlink_trans = trans->transid;
	mutex_unlock(&inode->log_mutex);

	if (!for_rename)
		return;

	/*
	 * If this directory was already logged, any new names will be logged
	 * with btrfs_log_new_name() and old names will be deleted from the log
	 * tree with btrfs_del_dir_entries_in_log() or with
	 * btrfs_del_inode_ref_in_log().
	 */
	if (inode_logged(trans, dir, NULL) == 1)
		return;

	/*
	 * If the inode we're about to unlink was logged before, the log will be
	 * properly updated with the new name with btrfs_log_new_name() and the
	 * old name removed with btrfs_del_dir_entries_in_log() or with
	 * btrfs_del_inode_ref_in_log().
	 */
	if (inode_logged(trans, inode, NULL) == 1)
		return;

	/*
	 * when renaming files across directories, if the directory
	 * there we're unlinking from gets fsync'd later on, there's
	 * no way to find the destination directory later and fsync it
	 * properly.  So, we have to be conservative and force commits
	 * so the new name gets discovered.
	 */
	mutex_lock(&dir->log_mutex);
	dir->last_unlink_trans = trans->transid;
	mutex_unlock(&dir->log_mutex);
}

/*
 * Make sure that if someone attempts to fsync the parent directory of a deleted
 * snapshot, it ends up triggering a transaction commit. This is to guarantee
 * that after replaying the log tree of the parent directory's root we will not
 * see the snapshot anymore and at log replay time we will not see any log tree
 * corresponding to the deleted snapshot's root, which could lead to replaying
 * it after replaying the log tree of the parent directory (which would replay
 * the snapshot delete operation).
 *
 * Must be called before the actual snapshot destroy operation (updates to the
 * parent root and tree of tree roots trees, etc) are done.
 */
void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
				   struct btrfs_inode *dir)
{
	mutex_lock(&dir->log_mutex);
	dir->last_unlink_trans = trans->transid;
	mutex_unlock(&dir->log_mutex);
}

/*
 * Call this when creating a subvolume in a directory.
 * Because we don't commit a transaction when creating a subvolume, we can't
 * allow the directory pointing to the subvolume to be logged with an entry that
 * points to an unpersisted root if we are still in the transaction used to
 * create the subvolume, so make any attempt to log the directory to result in a
 * full log sync.
 * Also we don't need to worry with renames, since btrfs_rename() marks the log
 * for full commit when renaming a subvolume.
 *
 * Must be called before creating the subvolume entry in its parent directory.
 */
void btrfs_record_new_subvolume(const struct btrfs_trans_handle *trans,
				struct btrfs_inode *dir)
{
	mutex_lock(&dir->log_mutex);
	dir->last_unlink_trans = trans->transid;
	mutex_unlock(&dir->log_mutex);
}

/*
 * Update the log after adding a new name for an inode.
 *
 * @trans:              Transaction handle.
 * @old_dentry:         The dentry associated with the old name and the old
 *                      parent directory.
 * @old_dir:            The inode of the previous parent directory for the case
 *                      of a rename. For a link operation, it must be NULL.
 * @old_dir_index:      The index number associated with the old name, meaningful
 *                      only for rename operations (when @old_dir is not NULL).
 *                      Ignored for link operations.
 * @parent:             The dentry associated with the directory under which the
 *                      new name is located.
 *
 * Call this after adding a new name for an inode, as a result of a link or
 * rename operation, and it will properly update the log to reflect the new name.
 */
void btrfs_log_new_name(struct btrfs_trans_handle *trans,
			struct dentry *old_dentry, struct btrfs_inode *old_dir,
			u64 old_dir_index, struct dentry *parent)
{
	struct btrfs_inode *inode = BTRFS_I(d_inode(old_dentry));
	struct btrfs_root *root = inode->root;
	struct btrfs_log_ctx ctx;
	bool log_pinned = false;
	int ret;

	/* The inode has a new name (ref/extref), so make sure we log it. */
	set_bit(BTRFS_INODE_COPY_EVERYTHING, &inode->runtime_flags);

	btrfs_init_log_ctx(&ctx, inode);
	ctx.logging_new_name = true;

	/*
	 * this will force the logging code to walk the dentry chain
	 * up for the file
	 */
	if (!S_ISDIR(inode->vfs_inode.i_mode))
		inode->last_unlink_trans = trans->transid;

	/*
	 * if this inode hasn't been logged and directory we're renaming it
	 * from hasn't been logged, we don't need to log it
	 */
	ret = inode_logged(trans, inode, NULL);
	if (ret < 0) {
		goto out;
	} else if (ret == 0) {
		if (!old_dir)
			return;
		/*
		 * If the inode was not logged and we are doing a rename (old_dir is not
		 * NULL), check if old_dir was logged - if it was not we can return and
		 * do nothing.
		 */
		ret = inode_logged(trans, old_dir, NULL);
		if (ret < 0)
			goto out;
		else if (ret == 0)
			return;
	}
	ret = 0;

	/*
	 * Now that we know we need to update the log, allocate the scratch eb
	 * for the context before joining a log transaction below, as this can
	 * take time and therefore we could delay log commits from other tasks.
	 */
	btrfs_init_log_ctx_scratch_eb(&ctx);

	/*
	 * If we are doing a rename (old_dir is not NULL) from a directory that
	 * was previously logged, make sure that on log replay we get the old
	 * dir entry deleted. This is needed because we will also log the new
	 * name of the renamed inode, so we need to make sure that after log
	 * replay we don't end up with both the new and old dir entries existing.
	 */
	if (old_dir && old_dir->logged_trans == trans->transid) {
		struct btrfs_root *log = old_dir->root->log_root;
		struct btrfs_path *path;
		struct fscrypt_name fname;

		ASSERT(old_dir_index >= BTRFS_DIR_START_INDEX);

		ret = fscrypt_setup_filename(&old_dir->vfs_inode,
					     &old_dentry->d_name, 0, &fname);
		if (ret)
			goto out;

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

		/*
		 * We have two inodes to update in the log, the old directory and
		 * the inode that got renamed, so we must pin the log to prevent
		 * anyone from syncing the log until we have updated both inodes
		 * in the log.
		 */
		ret = join_running_log_trans(root);
		/*
		 * At least one of the inodes was logged before, so this should
		 * not fail, but if it does, it's not serious, just bail out and
		 * mark the log for a full commit.
		 */
		if (WARN_ON_ONCE(ret < 0)) {
			btrfs_free_path(path);
			fscrypt_free_filename(&fname);
			goto out;
		}

		log_pinned = true;

		/*
		 * Other concurrent task might be logging the old directory,
		 * as it can be triggered when logging other inode that had or
		 * still has a dentry in the old directory. We lock the old
		 * directory's log_mutex to ensure the deletion of the old
		 * name is persisted, because during directory logging we
		 * delete all BTRFS_DIR_LOG_INDEX_KEY keys and the deletion of
		 * the old name's dir index item is in the delayed items, so
		 * it could be missed by an in progress directory logging.
		 */
		mutex_lock(&old_dir->log_mutex);
		ret = del_logged_dentry(trans, log, path, btrfs_ino(old_dir),
					&fname.disk_name, old_dir_index);
		if (ret > 0) {
			/*
			 * The dentry does not exist in the log, so record its
			 * deletion.
			 */
			btrfs_release_path(path);
			ret = insert_dir_log_key(trans, log, path,
						 btrfs_ino(old_dir),
						 old_dir_index, old_dir_index);
		}
		mutex_unlock(&old_dir->log_mutex);

		btrfs_free_path(path);
		fscrypt_free_filename(&fname);
		if (ret < 0)
			goto out;
	}

	/*
	 * We don't care about the return value. If we fail to log the new name
	 * then we know the next attempt to sync the log will fallback to a full
	 * transaction commit (due to a call to btrfs_set_log_full_commit()), so
	 * we don't need to worry about getting a log committed that has an
	 * inconsistent state after a rename operation.
	 */
	btrfs_log_inode_parent(trans, inode, parent, LOG_INODE_EXISTS, &ctx);
	ASSERT(list_empty(&ctx.conflict_inodes));
out:
	/*
	 * If an error happened mark the log for a full commit because it's not
	 * consistent and up to date or we couldn't find out if one of the
	 * inodes was logged before in this transaction. Do it before unpinning
	 * the log, to avoid any races with someone else trying to commit it.
	 */
	if (ret < 0)
		btrfs_set_log_full_commit(trans);
	if (log_pinned)
		btrfs_end_log_trans(root);
	free_extent_buffer(ctx.scratch_eb);
}

