// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2020-2024 Oracle.  All Rights Reserved.
 * Author: Darrick J. Wong <djwong@kernel.org>
 */
#include "xfs.h"
#include "xfs_fs.h"
#include "xfs_shared.h"
#include "xfs_format.h"
#include "xfs_trans_resv.h"
#include "xfs_mount.h"
#include "xfs_defer.h"
#include "xfs_bit.h"
#include "xfs_log_format.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_inode.h"
#include "xfs_icache.h"
#include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_dir2.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir2_priv.h"
#include "xfs_trans_space.h"
#include "xfs_health.h"
#include "xfs_exchmaps.h"
#include "xfs_parent.h"
#include "xfs_attr.h"
#include "xfs_bmap.h"
#include "xfs_ag.h"
#include "scrub/xfs_scrub.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
#include "scrub/repair.h"
#include "scrub/iscan.h"
#include "scrub/findparent.h"
#include "scrub/readdir.h"
#include "scrub/tempfile.h"
#include "scrub/tempexch.h"
#include "scrub/orphanage.h"
#include "scrub/xfile.h"
#include "scrub/xfarray.h"
#include "scrub/xfblob.h"
#include "scrub/attr_repair.h"
#include "scrub/listxattr.h"

/*
 * Repairing The Directory Parent Pointer
 * ======================================
 *
 * Currently, only directories support parent pointers (in the form of '..'
 * entries), so we simply scan the filesystem and update the '..' entry.
 *
 * Note that because the only parent pointer is the dotdot entry, we won't
 * touch an unhealthy directory, since the directory repair code is perfectly
 * capable of rebuilding a directory with the proper parent inode.
 *
 * See the section on locking issues in dir_repair.c for more information about
 * conflicts with the VFS.  The findparent code wll keep our incore parent
 * inode up to date.
 *
 * If parent pointers are enabled, we instead reconstruct the parent pointer
 * information by visiting every directory entry of every directory in the
 * system and translating the relevant dirents into parent pointers.  In this
 * case, it is advantageous to stash all parent pointers created from dirents
 * from a single parent file before replaying them into the temporary file.  To
 * save memory, the live filesystem scan reuses the findparent object.  Parent
 * pointer repair chooses either directory scanning or findparent, but not
 * both.
 *
 * When salvaging completes, the remaining stashed entries are replayed to the
 * temporary file.  All non-parent pointer extended attributes are copied to
 * the temporary file's extended attributes.  An atomic file mapping exchange
 * is used to commit the new xattr blocks to the file being repaired.  This
 * will disrupt attrmulti cursors.
 */

/* Create a parent pointer in the tempfile. */
#define XREP_PPTR_ADD		(1)

/* Remove a parent pointer from the tempfile. */
#define XREP_PPTR_REMOVE	(2)

/* A stashed parent pointer update. */
struct xrep_pptr {
	/* Cookie for retrieval of the pptr name. */
	xfblob_cookie		name_cookie;

	/* Parent pointer record. */
	struct xfs_parent_rec	pptr_rec;

	/* Length of the pptr name. */
	uint8_t			namelen;

	/* XREP_PPTR_{ADD,REMOVE} */
	uint8_t			action;
};

/*
 * Stash up to 8 pages of recovered parent pointers in pptr_recs and
 * pptr_names before we write them to the temp file.
 */
#define XREP_PARENT_MAX_STASH_BYTES	(PAGE_SIZE * 8)

struct xrep_parent {
	struct xfs_scrub	*sc;

	/* Fixed-size array of xrep_pptr structures. */
	struct xfarray		*pptr_recs;

	/* Blobs containing parent pointer names. */
	struct xfblob		*pptr_names;

	/* xattr keys */
	struct xfarray		*xattr_records;

	/* xattr values */
	struct xfblob		*xattr_blobs;

	/* Scratch buffers for saving extended attributes */
	unsigned char		*xattr_name;
	void			*xattr_value;
	unsigned int		xattr_value_sz;

	/*
	 * Information used to exchange the attr fork mappings, if the fs
	 * supports parent pointers.
	 */
	struct xrep_tempexch	tx;

	/*
	 * Information used to scan the filesystem to find the inumber of the
	 * dotdot entry for this directory.  On filesystems without parent
	 * pointers, we use the findparent_* functions on this object and
	 * access only the parent_ino field directly.
	 *
	 * When parent pointers are enabled, the directory entry scanner uses
	 * the iscan, hooks, and lock fields of this object directly.
	 * @pscan.lock coordinates access to pptr_recs, pptr_names, pptr, and
	 * pptr_scratch.  This reduces the memory requirements of this
	 * structure.
	 *
	 * The lock also controls access to xattr_records and xattr_blobs(?)
	 */
	struct xrep_parent_scan_info pscan;

	/* Orphanage reparenting request. */
	struct xrep_adoption	adoption;

	/* Directory entry name, plus the trailing null. */
	struct xfs_name		xname;
	unsigned char		namebuf[MAXNAMELEN];

	/* Scratch buffer for scanning pptr xattrs */
	struct xfs_da_args	pptr_args;

	/* Have we seen any live updates of parent pointers recently? */
	bool			saw_pptr_updates;

	/* Number of parents we found after all other repairs */
	unsigned long long	parents;
};

struct xrep_parent_xattr {
	/* Cookie for retrieval of the xattr name. */
	xfblob_cookie		name_cookie;

	/* Cookie for retrieval of the xattr value. */
	xfblob_cookie		value_cookie;

	/* XFS_ATTR_* flags */
	int			flags;

	/* Length of the value and name. */
	uint32_t		valuelen;
	uint16_t		namelen;
};

/*
 * Stash up to 8 pages of attrs in xattr_records/xattr_blobs before we write
 * them to the temp file.
 */
#define XREP_PARENT_XATTR_MAX_STASH_BYTES	(PAGE_SIZE * 8)

/* Tear down all the incore stuff we created. */
static void
xrep_parent_teardown(
	struct xrep_parent	*rp)
{
	xrep_findparent_scan_teardown(&rp->pscan);
	kvfree(rp->xattr_name);
	rp->xattr_name = NULL;
	kvfree(rp->xattr_value);
	rp->xattr_value = NULL;
	if (rp->xattr_blobs)
		xfblob_destroy(rp->xattr_blobs);
	rp->xattr_blobs = NULL;
	if (rp->xattr_records)
		xfarray_destroy(rp->xattr_records);
	rp->xattr_records = NULL;
	if (rp->pptr_names)
		xfblob_destroy(rp->pptr_names);
	rp->pptr_names = NULL;
	if (rp->pptr_recs)
		xfarray_destroy(rp->pptr_recs);
	rp->pptr_recs = NULL;
}

/* Set up for a parent repair. */
int
xrep_setup_parent(
	struct xfs_scrub	*sc)
{
	struct xrep_parent	*rp;
	int			error;

	xchk_fsgates_enable(sc, XCHK_FSGATES_DIRENTS);

	rp = kvzalloc(sizeof(struct xrep_parent), XCHK_GFP_FLAGS);
	if (!rp)
		return -ENOMEM;
	rp->sc = sc;
	rp->xname.name = rp->namebuf;
	sc->buf = rp;

	error = xrep_tempfile_create(sc, S_IFREG);
	if (error)
		return error;

	return xrep_orphanage_try_create(sc);
}

/*
 * Scan all files in the filesystem for a child dirent that we can turn into
 * the dotdot entry for this directory.
 */
STATIC int
xrep_parent_find_dotdot(
	struct xrep_parent	*rp)
{
	struct xfs_scrub	*sc = rp->sc;
	xfs_ino_t		ino;
	unsigned int		sick, checked;
	int			error;

	/*
	 * Avoid sick directories.  There shouldn't be anyone else clearing the
	 * directory's sick status.
	 */
	xfs_inode_measure_sickness(sc->ip, &sick, &checked);
	if (sick & XFS_SICK_INO_DIR)
		return -EFSCORRUPTED;

	ino = xrep_findparent_self_reference(sc);
	if (ino != NULLFSINO) {
		xrep_findparent_scan_finish_early(&rp->pscan, ino);
		return 0;
	}

	/*
	 * Drop the ILOCK on this directory so that we can scan for the dotdot
	 * entry.  Figure out who is going to be the parent of this directory,
	 * then retake the ILOCK so that we can salvage directory entries.
	 */
	xchk_iunlock(sc, XFS_ILOCK_EXCL);

	/* Does the VFS dcache have an answer for us? */
	ino = xrep_findparent_from_dcache(sc);
	if (ino != NULLFSINO) {
		error = xrep_findparent_confirm(sc, &ino);
		if (!error && ino != NULLFSINO) {
			xrep_findparent_scan_finish_early(&rp->pscan, ino);
			goto out_relock;
		}
	}

	/* Scan the entire filesystem for a parent. */
	error = xrep_findparent_scan(&rp->pscan);
out_relock:
	xchk_ilock(sc, XFS_ILOCK_EXCL);

	return error;
}

/*
 * Add this stashed incore parent pointer to the temporary file.
 * The caller must hold the tempdir's IOLOCK, must not hold any ILOCKs, and
 * must not be in transaction context.
 */
STATIC int
xrep_parent_replay_update(
	struct xrep_parent	*rp,
	const struct xfs_name	*xname,
	struct xrep_pptr	*pptr)
{
	struct xfs_scrub	*sc = rp->sc;

	switch (pptr->action) {
	case XREP_PPTR_ADD:
		/* Create parent pointer. */
		trace_xrep_parent_replay_parentadd(sc->tempip, xname,
				&pptr->pptr_rec);

		return xfs_parent_set(sc->tempip, sc->ip->i_ino, xname,
				&pptr->pptr_rec, &rp->pptr_args);
	case XREP_PPTR_REMOVE:
		/* Remove parent pointer. */
		trace_xrep_parent_replay_parentremove(sc->tempip, xname,
				&pptr->pptr_rec);

		return xfs_parent_unset(sc->tempip, sc->ip->i_ino, xname,
				&pptr->pptr_rec, &rp->pptr_args);
	}

	ASSERT(0);
	return -EIO;
}

/*
 * Flush stashed parent pointer updates that have been recorded by the scanner.
 * This is done to reduce the memory requirements of the parent pointer
 * rebuild, since files can have a lot of hardlinks and the fs can be busy.
 *
 * Caller must not hold transactions or ILOCKs.  Caller must hold the tempfile
 * IOLOCK.
 */
STATIC int
xrep_parent_replay_updates(
	struct xrep_parent	*rp)
{
	xfarray_idx_t		array_cur;
	int			error;

	mutex_lock(&rp->pscan.lock);
	foreach_xfarray_idx(rp->pptr_recs, array_cur) {
		struct xrep_pptr	pptr;

		error = xfarray_load(rp->pptr_recs, array_cur, &pptr);
		if (error)
			goto out_unlock;

		error = xfblob_loadname(rp->pptr_names, pptr.name_cookie,
				&rp->xname, pptr.namelen);
		if (error)
			goto out_unlock;
		rp->xname.len = pptr.namelen;
		mutex_unlock(&rp->pscan.lock);

		error = xrep_parent_replay_update(rp, &rp->xname, &pptr);
		if (error)
			return error;

		mutex_lock(&rp->pscan.lock);
	}

	/* Empty out both arrays now that we've added the entries. */
	xfarray_truncate(rp->pptr_recs);
	xfblob_truncate(rp->pptr_names);
	mutex_unlock(&rp->pscan.lock);
	return 0;
out_unlock:
	mutex_unlock(&rp->pscan.lock);
	return error;
}

/*
 * Remember that we want to create a parent pointer in the tempfile.  These
 * stashed actions will be replayed later.
 */
STATIC int
xrep_parent_stash_parentadd(
	struct xrep_parent	*rp,
	const struct xfs_name	*name,
	const struct xfs_inode	*dp)
{
	struct xrep_pptr	pptr = {
		.action		= XREP_PPTR_ADD,
		.namelen	= name->len,
	};
	int			error;

	trace_xrep_parent_stash_parentadd(rp->sc->tempip, dp, name);

	xfs_inode_to_parent_rec(&pptr.pptr_rec, dp);
	error = xfblob_storename(rp->pptr_names, &pptr.name_cookie, name);
	if (error)
		return error;

	return xfarray_append(rp->pptr_recs, &pptr);
}

/*
 * Remember that we want to remove a parent pointer from the tempfile.  These
 * stashed actions will be replayed later.
 */
STATIC int
xrep_parent_stash_parentremove(
	struct xrep_parent	*rp,
	const struct xfs_name	*name,
	const struct xfs_inode	*dp)
{
	struct xrep_pptr	pptr = {
		.action		= XREP_PPTR_REMOVE,
		.namelen	= name->len,
	};
	int			error;

	trace_xrep_parent_stash_parentremove(rp->sc->tempip, dp, name);

	xfs_inode_to_parent_rec(&pptr.pptr_rec, dp);
	error = xfblob_storename(rp->pptr_names, &pptr.name_cookie, name);
	if (error)
		return error;

	return xfarray_append(rp->pptr_recs, &pptr);
}

/*
 * Examine an entry of a directory.  If this dirent leads us back to the file
 * whose parent pointers we're rebuilding, add a pptr to the temporary
 * directory.
 */
STATIC int
xrep_parent_scan_dirent(
	struct xfs_scrub	*sc,
	struct xfs_inode	*dp,
	xfs_dir2_dataptr_t	dapos,
	const struct xfs_name	*name,
	xfs_ino_t		ino,
	void			*priv)
{
	struct xrep_parent	*rp = priv;
	int			error;

	/* Dirent doesn't point to this directory. */
	if (ino != rp->sc->ip->i_ino)
		return 0;

	/* No weird looking names. */
	if (name->len == 0 || !xfs_dir2_namecheck(name->name, name->len))
		return -EFSCORRUPTED;

	/* No mismatching ftypes. */
	if (name->type != xfs_mode_to_ftype(VFS_I(sc->ip)->i_mode))
		return -EFSCORRUPTED;

	/* Don't pick up dot or dotdot entries; we only want child dirents. */
	if (xfs_dir2_samename(name, &xfs_name_dotdot) ||
	    xfs_dir2_samename(name, &xfs_name_dot))
		return 0;

	/*
	 * Transform this dirent into a parent pointer and queue it for later
	 * addition to the temporary file.
	 */
	mutex_lock(&rp->pscan.lock);
	error = xrep_parent_stash_parentadd(rp, name, dp);
	mutex_unlock(&rp->pscan.lock);
	return error;
}

/*
 * Decide if we want to look for dirents in this directory.  Skip the file
 * being repaired and any files being used to stage repairs.
 */
static inline bool
xrep_parent_want_scan(
	struct xrep_parent	*rp,
	const struct xfs_inode	*ip)
{
	return ip != rp->sc->ip && !xrep_is_tempfile(ip);
}

/*
 * Take ILOCK on a file that we want to scan.
 *
 * Select ILOCK_EXCL if the file is a directory with an unloaded data bmbt.
 * Otherwise, take ILOCK_SHARED.
 */
static inline unsigned int
xrep_parent_scan_ilock(
	struct xrep_parent	*rp,
	struct xfs_inode	*ip)
{
	uint			lock_mode = XFS_ILOCK_SHARED;

	/* Still need to take the shared ILOCK to advance the iscan cursor. */
	if (!xrep_parent_want_scan(rp, ip))
		goto lock;

	if (S_ISDIR(VFS_I(ip)->i_mode) && xfs_need_iread_extents(&ip->i_df)) {
		lock_mode = XFS_ILOCK_EXCL;
		goto lock;
	}

lock:
	xfs_ilock(ip, lock_mode);
	return lock_mode;
}

/*
 * Scan this file for relevant child dirents that point to the file whose
 * parent pointers we're rebuilding.
 */
STATIC int
xrep_parent_scan_file(
	struct xrep_parent	*rp,
	struct xfs_inode	*ip)
{
	unsigned int		lock_mode;
	int			error = 0;

	lock_mode = xrep_parent_scan_ilock(rp, ip);

	if (!xrep_parent_want_scan(rp, ip))
		goto scan_done;

	if (S_ISDIR(VFS_I(ip)->i_mode)) {
		/*
		 * If the directory looks as though it has been zapped by the
		 * inode record repair code, we cannot scan for child dirents.
		 */
		if (xchk_dir_looks_zapped(ip)) {
			error = -EBUSY;
			goto scan_done;
		}

		error = xchk_dir_walk(rp->sc, ip, xrep_parent_scan_dirent, rp);
		if (error)
			goto scan_done;
	}

scan_done:
	xchk_iscan_mark_visited(&rp->pscan.iscan, ip);
	xfs_iunlock(ip, lock_mode);
	return error;
}

/* Decide if we've stashed too much pptr data in memory. */
static inline bool
xrep_parent_want_flush_stashed(
	struct xrep_parent	*rp)
{
	unsigned long long	bytes;

	bytes = xfarray_bytes(rp->pptr_recs) + xfblob_bytes(rp->pptr_names);
	return bytes > XREP_PARENT_MAX_STASH_BYTES;
}

/*
 * Scan all directories in the filesystem to look for dirents that we can turn
 * into parent pointers.
 */
STATIC int
xrep_parent_scan_dirtree(
	struct xrep_parent	*rp)
{
	struct xfs_scrub	*sc = rp->sc;
	struct xfs_inode	*ip;
	int			error;

	/*
	 * Filesystem scans are time consuming.  Drop the file ILOCK and all
	 * other resources for the duration of the scan and hope for the best.
	 * The live update hooks will keep our scan information up to date.
	 */
	xchk_trans_cancel(sc);
	if (sc->ilock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL))
		xchk_iunlock(sc, sc->ilock_flags & (XFS_ILOCK_SHARED |
						    XFS_ILOCK_EXCL));
	error = xchk_trans_alloc_empty(sc);
	if (error)
		return error;

	while ((error = xchk_iscan_iter(&rp->pscan.iscan, &ip)) == 1) {
		bool		flush;

		error = xrep_parent_scan_file(rp, ip);
		xchk_irele(sc, ip);
		if (error)
			break;

		/* Flush stashed pptr updates to constrain memory usage. */
		mutex_lock(&rp->pscan.lock);
		flush = xrep_parent_want_flush_stashed(rp);
		mutex_unlock(&rp->pscan.lock);
		if (flush) {
			xchk_trans_cancel(sc);

			error = xrep_tempfile_iolock_polled(sc);
			if (error)
				break;

			error = xrep_parent_replay_updates(rp);
			xrep_tempfile_iounlock(sc);
			if (error)
				break;

			error = xchk_trans_alloc_empty(sc);
			if (error)
				break;
		}

		if (xchk_should_terminate(sc, &error))
			break;
	}
	xchk_iscan_iter_finish(&rp->pscan.iscan);
	if (error) {
		/*
		 * If we couldn't grab an inode that was busy with a state
		 * change, change the error code so that we exit to userspace
		 * as quickly as possible.
		 */
		if (error == -EBUSY)
			return -ECANCELED;
		return error;
	}

	/*
	 * Retake sc->ip's ILOCK now that we're done flushing stashed parent
	 * pointers.  We end this function with an empty transaction and the
	 * ILOCK.
	 */
	xchk_ilock(rp->sc, XFS_ILOCK_EXCL);
	return 0;
}

/*
 * Capture dirent updates being made by other threads which are relevant to the
 * file being repaired.
 */
STATIC int
xrep_parent_live_update(
	struct notifier_block		*nb,
	unsigned long			action,
	void				*data)
{
	struct xfs_dir_update_params	*p = data;
	struct xrep_parent		*rp;
	struct xfs_scrub		*sc;
	int				error;

	rp = container_of(nb, struct xrep_parent, pscan.dhook.dirent_hook.nb);
	sc = rp->sc;

	/*
	 * This thread updated a dirent that points to the file that we're
	 * repairing, so stash the update for replay against the temporary
	 * file.
	 */
	if (p->ip->i_ino == sc->ip->i_ino &&
	    xchk_iscan_want_live_update(&rp->pscan.iscan, p->dp->i_ino)) {
		mutex_lock(&rp->pscan.lock);
		if (p->delta > 0)
			error = xrep_parent_stash_parentadd(rp, p->name, p->dp);
		else
			error = xrep_parent_stash_parentremove(rp, p->name,
					p->dp);
		if (!error)
			rp->saw_pptr_updates = true;
		mutex_unlock(&rp->pscan.lock);
		if (error)
			goto out_abort;
	}

	return NOTIFY_DONE;
out_abort:
	xchk_iscan_abort(&rp->pscan.iscan);
	return NOTIFY_DONE;
}

/* Reset a directory's dotdot entry, if needed. */
STATIC int
xrep_parent_reset_dotdot(
	struct xrep_parent	*rp)
{
	struct xfs_scrub	*sc = rp->sc;
	xfs_ino_t		ino;
	unsigned int		spaceres;
	int			error = 0;

	ASSERT(sc->ilock_flags & XFS_ILOCK_EXCL);

	error = xchk_dir_lookup(sc, sc->ip, &xfs_name_dotdot, &ino);
	if (error || ino == rp->pscan.parent_ino)
		return error;

	xfs_trans_ijoin(sc->tp, sc->ip, 0);

	trace_xrep_parent_reset_dotdot(sc->ip, rp->pscan.parent_ino);

	/*
	 * Reserve more space just in case we have to expand the dir.  We're
	 * allowed to exceed quota to repair inconsistent metadata.
	 */
	spaceres = xfs_rename_space_res(sc->mp, 0, false, xfs_name_dotdot.len,
			false);
	error = xfs_trans_reserve_more_inode(sc->tp, sc->ip, spaceres, 0,
			true);
	if (error)
		return error;

	error = xfs_dir_replace(sc->tp, sc->ip, &xfs_name_dotdot,
			rp->pscan.parent_ino, spaceres);
	if (error)
		return error;

	/*
	 * Roll transaction to detach the inode from the transaction but retain
	 * ILOCK_EXCL.
	 */
	return xfs_trans_roll(&sc->tp);
}

/* Pass back the parent inumber if this a parent pointer */
STATIC int
xrep_parent_lookup_pptr(
	struct xfs_scrub	*sc,
	struct xfs_inode	*ip,
	unsigned int		attr_flags,
	const unsigned char	*name,
	unsigned int		namelen,
	const void		*value,
	unsigned int		valuelen,
	void			*priv)
{
	xfs_ino_t		*inop = priv;
	xfs_ino_t		parent_ino;
	int			error;

	if (!(attr_flags & XFS_ATTR_PARENT))
		return 0;

	error = xfs_parent_from_attr(sc->mp, attr_flags, name, namelen, value,
			valuelen, &parent_ino, NULL);
	if (error)
		return error;

	*inop = parent_ino;
	return -ECANCELED;
}

/*
 * Find the first parent of the scrub target by walking parent pointers for
 * the purpose of deciding if we're going to move it to the orphanage.
 * We don't care if the attr fork is zapped.
 */
STATIC int
xrep_parent_lookup_pptrs(
	struct xfs_scrub	*sc,
	xfs_ino_t		*inop)
{
	int			error;

	*inop = NULLFSINO;

	error = xchk_xattr_walk(sc, sc->ip, xrep_parent_lookup_pptr, NULL,
			inop);
	if (error && error != -ECANCELED)
		return error;
	return 0;
}

/*
 * Move the current file to the orphanage.
 *
 * Caller must hold IOLOCK_EXCL on @sc->ip, and no other inode locks.  Upon
 * successful return, the scrub transaction will have enough extra reservation
 * to make the move; it will hold IOLOCK_EXCL and ILOCK_EXCL of @sc->ip and the
 * orphanage; and both inodes will be ijoined.
 */
STATIC int
xrep_parent_move_to_orphanage(
	struct xrep_parent	*rp)
{
	struct xfs_scrub	*sc = rp->sc;
	xfs_ino_t		orig_parent, new_parent;
	int			error;

	if (S_ISDIR(VFS_I(sc->ip)->i_mode)) {
		/*
		 * We are about to drop the ILOCK on sc->ip to lock the
		 * orphanage and prepare for the adoption.  Therefore, look up
		 * the old dotdot entry for sc->ip so that we can compare it
		 * after we re-lock sc->ip.
		 */
		error = xchk_dir_lookup(sc, sc->ip, &xfs_name_dotdot,
				&orig_parent);
		if (error)
			return error;
	} else {
		/*
		 * We haven't dropped the ILOCK since we committed the new
		 * xattr structure (and hence the new parent pointer records),
		 * which means that the file cannot have been moved in the
		 * directory tree, and there are no parents.
		 */
		orig_parent = NULLFSINO;
	}

	/*
	 * Drop the ILOCK on the scrub target and commit the transaction.
	 * Adoption computes its own resource requirements and gathers the
	 * necessary components.
	 */
	error = xrep_trans_commit(sc);
	if (error)
		return error;
	xchk_iunlock(sc, XFS_ILOCK_EXCL);

	/* If we can take the orphanage's iolock then we're ready to move. */
	if (!xrep_orphanage_ilock_nowait(sc, XFS_IOLOCK_EXCL)) {
		xchk_iunlock(sc, sc->ilock_flags);
		error = xrep_orphanage_iolock_two(sc);
		if (error)
			return error;
	}

	/* Grab transaction and ILOCK the two files. */
	error = xrep_adoption_trans_alloc(sc, &rp->adoption);
	if (error)
		return error;

	error = xrep_adoption_compute_name(&rp->adoption, &rp->xname);
	if (error)
		return error;

	/*
	 * Now that we've reacquired the ILOCK on sc->ip, look up the dotdot
	 * entry again.  If the parent changed or the child was unlinked while
	 * the child directory was unlocked, we don't need to move the child to
	 * the orphanage after all.  For a non-directory, we have to scan for
	 * the first parent pointer to see if one has been added.
	 */
	if (S_ISDIR(VFS_I(sc->ip)->i_mode))
		error = xchk_dir_lookup(sc, sc->ip, &xfs_name_dotdot,
				&new_parent);
	else
		error = xrep_parent_lookup_pptrs(sc, &new_parent);
	if (error)
		return error;

	/*
	 * Attach to the orphanage if we still have a linked directory and it
	 * hasn't been moved.
	 */
	if (orig_parent == new_parent && VFS_I(sc->ip)->i_nlink > 0) {
		error = xrep_adoption_move(&rp->adoption);
		if (error)
			return error;
	}

	/*
	 * Launder the scrub transaction so we can drop the orphanage ILOCK
	 * and IOLOCK.  Return holding the scrub target's ILOCK and IOLOCK.
	 */
	error = xrep_adoption_trans_roll(&rp->adoption);
	if (error)
		return error;

	xrep_orphanage_iunlock(sc, XFS_ILOCK_EXCL);
	xrep_orphanage_iunlock(sc, XFS_IOLOCK_EXCL);
	return 0;
}

/* Ensure that the xattr value buffer is large enough. */
STATIC int
xrep_parent_alloc_xattr_value(
	struct xrep_parent	*rp,
	size_t			bufsize)
{
	void			*new_val;

	if (rp->xattr_value_sz >= bufsize)
		return 0;

	if (rp->xattr_value) {
		kvfree(rp->xattr_value);
		rp->xattr_value = NULL;
		rp->xattr_value_sz = 0;
	}

	new_val = kvmalloc(bufsize, XCHK_GFP_FLAGS);
	if (!new_val)
		return -ENOMEM;

	rp->xattr_value = new_val;
	rp->xattr_value_sz = bufsize;
	return 0;
}

/* Retrieve the (remote) value of a non-pptr xattr. */
STATIC int
xrep_parent_fetch_xattr_remote(
	struct xrep_parent	*rp,
	struct xfs_inode	*ip,
	unsigned int		attr_flags,
	const unsigned char	*name,
	unsigned int		namelen,
	unsigned int		valuelen)
{
	struct xfs_scrub	*sc = rp->sc;
	struct xfs_da_args	args = {
		.attr_filter	= attr_flags & XFS_ATTR_NSP_ONDISK_MASK,
		.geo		= sc->mp->m_attr_geo,
		.whichfork	= XFS_ATTR_FORK,
		.dp		= ip,
		.name		= name,
		.namelen	= namelen,
		.trans		= sc->tp,
		.valuelen	= valuelen,
		.owner		= ip->i_ino,
	};
	int			error;

	/*
	 * If we need a larger value buffer, try to allocate one.  If that
	 * fails, return with -EDEADLOCK to try harder.
	 */
	error = xrep_parent_alloc_xattr_value(rp, valuelen);
	if (error == -ENOMEM)
		return -EDEADLOCK;
	if (error)
		return error;

	args.value = rp->xattr_value;
	xfs_attr_sethash(&args);
	return xfs_attr_get_ilocked(&args);
}

/* Stash non-pptr attributes for later replay into the temporary file. */
STATIC int
xrep_parent_stash_xattr(
	struct xfs_scrub	*sc,
	struct xfs_inode	*ip,
	unsigned int		attr_flags,
	const unsigned char	*name,
	unsigned int		namelen,
	const void		*value,
	unsigned int		valuelen,
	void			*priv)
{
	struct xrep_parent_xattr key = {
		.valuelen	= valuelen,
		.namelen	= namelen,
		.flags		= attr_flags & XFS_ATTR_NSP_ONDISK_MASK,
	};
	struct xrep_parent	*rp = priv;
	int			error;

	if (attr_flags & (XFS_ATTR_INCOMPLETE | XFS_ATTR_PARENT))
		return 0;

	if (!value) {
		error = xrep_parent_fetch_xattr_remote(rp, ip, attr_flags,
				name, namelen, valuelen);
		if (error)
			return error;

		value = rp->xattr_value;
	}

	trace_xrep_parent_stash_xattr(rp->sc->tempip, key.flags, (void *)name,
			key.namelen, key.valuelen);

	error = xfblob_store(rp->xattr_blobs, &key.name_cookie, name,
			key.namelen);
	if (error)
		return error;

	error = xfblob_store(rp->xattr_blobs, &key.value_cookie, value,
			key.valuelen);
	if (error)
		return error;

	return xfarray_append(rp->xattr_records, &key);
}

/* Insert one xattr key/value. */
STATIC int
xrep_parent_insert_xattr(
	struct xrep_parent		*rp,
	const struct xrep_parent_xattr	*key)
{
	struct xfs_da_args		args = {
		.dp			= rp->sc->tempip,
		.attr_filter		= key->flags,
		.namelen		= key->namelen,
		.valuelen		= key->valuelen,
		.owner			= rp->sc->ip->i_ino,
		.geo			= rp->sc->mp->m_attr_geo,
		.whichfork		= XFS_ATTR_FORK,
		.op_flags		= XFS_DA_OP_OKNOENT,
	};
	int				error;

	ASSERT(!(key->flags & XFS_ATTR_PARENT));

	/*
	 * Grab pointers to the scrub buffer so that we can use them to insert
	 * attrs into the temp file.
	 */
	args.name = rp->xattr_name;
	args.value = rp->xattr_value;

	/*
	 * The attribute name is stored near the end of the in-core buffer,
	 * though we reserve one more byte to ensure null termination.
	 */
	rp->xattr_name[XATTR_NAME_MAX] = 0;

	error = xfblob_load(rp->xattr_blobs, key->name_cookie, rp->xattr_name,
			key->namelen);
	if (error)
		return error;

	error = xfblob_free(rp->xattr_blobs, key->name_cookie);
	if (error)
		return error;

	error = xfblob_load(rp->xattr_blobs, key->value_cookie, args.value,
			key->valuelen);
	if (error)
		return error;

	error = xfblob_free(rp->xattr_blobs, key->value_cookie);
	if (error)
		return error;

	rp->xattr_name[key->namelen] = 0;

	trace_xrep_parent_insert_xattr(rp->sc->tempip, key->flags,
			rp->xattr_name, key->namelen, key->valuelen);

	xfs_attr_sethash(&args);
	return xfs_attr_set(&args, XFS_ATTRUPDATE_UPSERT, false);
}

/*
 * Periodically flush salvaged attributes to the temporary file.  This is done
 * to reduce the memory requirements of the xattr rebuild because files can
 * contain millions of attributes.
 */
STATIC int
xrep_parent_flush_xattrs(
	struct xrep_parent	*rp)
{
	xfarray_idx_t		array_cur;
	int			error;

	/*
	 * Entering this function, the scrub context has a reference to the
	 * inode being repaired, the temporary file, and the empty scrub
	 * transaction that we created for the xattr scan.  We hold ILOCK_EXCL
	 * on the inode being repaired.
	 *
	 * To constrain kernel memory use, we occasionally flush salvaged
	 * xattrs from the xfarray and xfblob structures into the temporary
	 * file in preparation for exchanging the xattr structures at the end.
	 * Updating the temporary file requires a transaction, so we commit the
	 * scrub transaction and drop the ILOCK so that xfs_attr_set can
	 * allocate whatever transaction it wants.
	 *
	 * We still hold IOLOCK_EXCL on the inode being repaired, which
	 * prevents anyone from adding xattrs (or parent pointers) while we're
	 * flushing.
	 */
	xchk_trans_cancel(rp->sc);
	xchk_iunlock(rp->sc, XFS_ILOCK_EXCL);

	/*
	 * Take the IOLOCK of the temporary file while we modify xattrs.  This
	 * isn't strictly required because the temporary file is never revealed
	 * to userspace, but we follow the same locking rules.  We still hold
	 * sc->ip's IOLOCK.
	 */
	error = xrep_tempfile_iolock_polled(rp->sc);
	if (error)
		return error;

	/* Add all the salvaged attrs to the temporary file. */
	foreach_xfarray_idx(rp->xattr_records, array_cur) {
		struct xrep_parent_xattr	key;

		error = xfarray_load(rp->xattr_records, array_cur, &key);
		if (error)
			return error;

		error = xrep_parent_insert_xattr(rp, &key);
		if (error)
			return error;
	}

	/* Empty out both arrays now that we've added the entries. */
	xfarray_truncate(rp->xattr_records);
	xfblob_truncate(rp->xattr_blobs);

	xrep_tempfile_iounlock(rp->sc);

	/* Recreate the empty transaction and relock the inode. */
	error = xchk_trans_alloc_empty(rp->sc);
	if (error)
		return error;
	xchk_ilock(rp->sc, XFS_ILOCK_EXCL);
	return 0;
}

/* Decide if we've stashed too much xattr data in memory. */
static inline bool
xrep_parent_want_flush_xattrs(
	struct xrep_parent	*rp)
{
	unsigned long long	bytes;

	bytes = xfarray_bytes(rp->xattr_records) +
		xfblob_bytes(rp->xattr_blobs);
	return bytes > XREP_PARENT_XATTR_MAX_STASH_BYTES;
}

/* Flush staged attributes to the temporary file if we're over the limit. */
STATIC int
xrep_parent_try_flush_xattrs(
	struct xfs_scrub	*sc,
	void			*priv)
{
	struct xrep_parent	*rp = priv;
	int			error;

	if (!xrep_parent_want_flush_xattrs(rp))
		return 0;

	error = xrep_parent_flush_xattrs(rp);
	if (error)
		return error;

	/*
	 * If there were any parent pointer updates to the xattr structure
	 * while we dropped the ILOCK, the xattr structure is now stale.
	 * Signal to the attr copy process that we need to start over, but
	 * this time without opportunistic attr flushing.
	 *
	 * This is unlikely to happen, so we're ok with restarting the copy.
	 */
	mutex_lock(&rp->pscan.lock);
	if (rp->saw_pptr_updates)
		error = -ESTALE;
	mutex_unlock(&rp->pscan.lock);
	return error;
}

/* Copy all the non-pptr extended attributes into the temporary file. */
STATIC int
xrep_parent_copy_xattrs(
	struct xrep_parent	*rp)
{
	struct xfs_scrub	*sc = rp->sc;
	int			error;

	/*
	 * Clear the pptr updates flag.  We hold sc->ip ILOCKed, so there
	 * can't be any parent pointer updates in progress.
	 */
	mutex_lock(&rp->pscan.lock);
	rp->saw_pptr_updates = false;
	mutex_unlock(&rp->pscan.lock);

	/* Copy xattrs, stopping periodically to flush the incore buffers. */
	error = xchk_xattr_walk(sc, sc->ip, xrep_parent_stash_xattr,
			xrep_parent_try_flush_xattrs, rp);
	if (error && error != -ESTALE)
		return error;

	if (error == -ESTALE) {
		/*
		 * The xattr copy collided with a parent pointer update.
		 * Restart the copy, but this time hold the ILOCK all the way
		 * to the end to lock out any directory parent pointer updates.
		 */
		error = xchk_xattr_walk(sc, sc->ip, xrep_parent_stash_xattr,
				NULL, rp);
		if (error)
			return error;
	}

	/* Flush any remaining stashed xattrs to the temporary file. */
	if (xfarray_bytes(rp->xattr_records) == 0)
		return 0;

	return xrep_parent_flush_xattrs(rp);
}

/*
 * Ensure that @sc->ip and @sc->tempip both have attribute forks before we head
 * into the attr fork exchange transaction.  All files on a filesystem with
 * parent pointers must have an attr fork because the parent pointer code does
 * not itself add attribute forks.
 *
 * Note: Unlinkable unlinked files don't need one, but the overhead of having
 * an unnecessary attr fork is not justified by the additional code complexity
 * that would be needed to track that state correctly.
 */
STATIC int
xrep_parent_ensure_attr_fork(
	struct xrep_parent	*rp)
{
	struct xfs_scrub	*sc = rp->sc;
	int			error;

	error = xfs_attr_add_fork(sc->tempip,
			sizeof(struct xfs_attr_sf_hdr), 1);
	if (error)
		return error;
	return xfs_attr_add_fork(sc->ip, sizeof(struct xfs_attr_sf_hdr), 1);
}

/*
 * Finish replaying stashed parent pointer updates, allocate a transaction for
 * exchanging extent mappings, and take the ILOCKs of both files before we
 * commit the new attribute structure.
 */
STATIC int
xrep_parent_finalize_tempfile(
	struct xrep_parent	*rp)
{
	struct xfs_scrub	*sc = rp->sc;
	int			error;

	/*
	 * Repair relies on the ILOCK to quiesce all possible xattr updates.
	 * Replay all queued parent pointer updates into the tempfile before
	 * exchanging the contents, even if that means dropping the ILOCKs and
	 * the transaction.
	 */
	do {
		error = xrep_parent_replay_updates(rp);
		if (error)
			return error;

		error = xrep_parent_ensure_attr_fork(rp);
		if (error)
			return error;

		error = xrep_tempexch_trans_alloc(sc, XFS_ATTR_FORK, &rp->tx);
		if (error)
			return error;

		if (xfarray_length(rp->pptr_recs) == 0)
			break;

		xchk_trans_cancel(sc);
		xrep_tempfile_iunlock_both(sc);
	} while (!xchk_should_terminate(sc, &error));
	return error;
}

/*
 * Replay all the stashed parent pointers into the temporary file, copy all
 * the non-pptr xattrs from the file being repaired into the temporary file,
 * and exchange the attr fork contents atomically.
 */
STATIC int
xrep_parent_rebuild_pptrs(
	struct xrep_parent	*rp)
{
	struct xfs_scrub	*sc = rp->sc;
	xfs_ino_t		parent_ino = NULLFSINO;
	int			error;

	/*
	 * Copy non-ppttr xattrs from the file being repaired into the
	 * temporary file's xattr structure.  We hold sc->ip's IOLOCK, which
	 * prevents setxattr/removexattr calls from occurring, but renames
	 * update the parent pointers without holding IOLOCK.  If we detect
	 * stale attr structures, we restart the scan but only flush at the
	 * end.
	 */
	error = xrep_parent_copy_xattrs(rp);
	if (error)
		return error;

	/*
	 * Cancel the empty transaction that we used to walk and copy attrs,
	 * and drop the ILOCK so that we can take the IOLOCK on the temporary
	 * file.  We still hold sc->ip's IOLOCK.
	 */
	xchk_trans_cancel(sc);
	xchk_iunlock(sc, XFS_ILOCK_EXCL);

	error = xrep_tempfile_iolock_polled(sc);
	if (error)
		return error;

	/*
	 * Allocate transaction, lock inodes, and make sure that we've replayed
	 * all the stashed pptr updates to the tempdir.  After this point,
	 * we're ready to exchange the attr fork mappings.
	 */
	error = xrep_parent_finalize_tempfile(rp);
	if (error)
		return error;

	/* Last chance to abort before we start committing pptr fixes. */
	if (xchk_should_terminate(sc, &error))
		return error;

	if (xchk_iscan_aborted(&rp->pscan.iscan))
		return -ECANCELED;

	/*
	 * Exchange the attr fork contents and junk the old attr fork contents,
	 * which are now in the tempfile.
	 */
	error = xrep_xattr_swap(sc, &rp->tx);
	if (error)
		return error;
	error = xrep_xattr_reset_tempfile_fork(sc);
	if (error)
		return error;

	/*
	 * Roll to get a transaction without any inodes joined to it.  Then we
	 * can drop the tempfile's ILOCK and IOLOCK before doing more work on
	 * the scrub target file.
	 */
	error = xfs_trans_roll(&sc->tp);
	if (error)
		return error;
	xrep_tempfile_iunlock(sc);
	xrep_tempfile_iounlock(sc);

	/*
	 * We've committed the new parent pointers.  Find at least one parent
	 * so that we can decide if we're moving this file to the orphanage.
	 * For this purpose, root directories are their own parents.
	 */
	if (sc->ip == sc->mp->m_rootip) {
		xrep_findparent_scan_found(&rp->pscan, sc->ip->i_ino);
	} else {
		error = xrep_parent_lookup_pptrs(sc, &parent_ino);
		if (error)
			return error;
		if (parent_ino != NULLFSINO)
			xrep_findparent_scan_found(&rp->pscan, parent_ino);
	}
	return 0;
}

/*
 * Commit the new parent pointer structure (currently only the dotdot entry) to
 * the file that we're repairing.
 */
STATIC int
xrep_parent_rebuild_tree(
	struct xrep_parent	*rp)
{
	int			error;

	if (xfs_has_parent(rp->sc->mp)) {
		error = xrep_parent_rebuild_pptrs(rp);
		if (error)
			return error;
	}

	if (rp->pscan.parent_ino == NULLFSINO) {
		if (xrep_orphanage_can_adopt(rp->sc))
			return xrep_parent_move_to_orphanage(rp);
		return -EFSCORRUPTED;
	}

	if (S_ISDIR(VFS_I(rp->sc->ip)->i_mode))
		return xrep_parent_reset_dotdot(rp);

	return 0;
}

/* Count the number of parent pointers. */
STATIC int
xrep_parent_count_pptr(
	struct xfs_scrub	*sc,
	struct xfs_inode	*ip,
	unsigned int		attr_flags,
	const unsigned char	*name,
	unsigned int		namelen,
	const void		*value,
	unsigned int		valuelen,
	void			*priv)
{
	struct xrep_parent	*rp = priv;
	int			error;

	if (!(attr_flags & XFS_ATTR_PARENT))
		return 0;

	error = xfs_parent_from_attr(sc->mp, attr_flags, name, namelen, value,
			valuelen, NULL, NULL);
	if (error)
		return error;

	rp->parents++;
	return 0;
}

/*
 * After all parent pointer rebuilding and adoption activity completes, reset
 * the link count of this nondirectory, having scanned the fs to rebuild all
 * parent pointers.
 */
STATIC int
xrep_parent_set_nondir_nlink(
	struct xrep_parent	*rp)
{
	struct xfs_scrub	*sc = rp->sc;
	struct xfs_inode	*ip = sc->ip;
	struct xfs_perag	*pag;
	bool			joined = false;
	int			error;

	/* Count parent pointers so we can reset the file link count. */
	rp->parents = 0;
	error = xchk_xattr_walk(sc, ip, xrep_parent_count_pptr, NULL, rp);
	if (error)
		return error;

	if (rp->parents > 0 && xfs_inode_on_unlinked_list(ip)) {
		xfs_trans_ijoin(sc->tp, sc->ip, 0);
		joined = true;

		/*
		 * The file is on the unlinked list but we found parents.
		 * Remove the file from the unlinked list.
		 */
		pag = xfs_perag_get(sc->mp, XFS_INO_TO_AGNO(sc->mp, ip->i_ino));
		if (!pag) {
			ASSERT(0);
			return -EFSCORRUPTED;
		}

		error = xfs_iunlink_remove(sc->tp, pag, ip);
		xfs_perag_put(pag);
		if (error)
			return error;
	} else if (rp->parents == 0 && !xfs_inode_on_unlinked_list(ip)) {
		xfs_trans_ijoin(sc->tp, sc->ip, 0);
		joined = true;

		/*
		 * The file is not on the unlinked list but we found no
		 * parents.  Add the file to the unlinked list.
		 */
		error = xfs_iunlink(sc->tp, ip);
		if (error)
			return error;
	}

	/* Set the correct link count. */
	if (VFS_I(ip)->i_nlink != rp->parents) {
		if (!joined) {
			xfs_trans_ijoin(sc->tp, sc->ip, 0);
			joined = true;
		}

		set_nlink(VFS_I(ip), min_t(unsigned long long, rp->parents,
					   XFS_NLINK_PINNED));
	}

	/* Log the inode to keep it moving forward if we dirtied anything. */
	if (joined)
		xfs_trans_log_inode(sc->tp, ip, XFS_ILOG_CORE);
	return 0;
}

/* Set up the filesystem scan so we can look for parents. */
STATIC int
xrep_parent_setup_scan(
	struct xrep_parent	*rp)
{
	struct xfs_scrub	*sc = rp->sc;
	char			*descr;
	struct xfs_da_geometry	*geo = sc->mp->m_attr_geo;
	int			max_len;
	int			error;

	if (!xfs_has_parent(sc->mp))
		return xrep_findparent_scan_start(sc, &rp->pscan);

	/* Buffers for copying non-pptr attrs to the tempfile */
	rp->xattr_name = kvmalloc(XATTR_NAME_MAX + 1, XCHK_GFP_FLAGS);
	if (!rp->xattr_name)
		return -ENOMEM;

	/*
	 * Allocate enough memory to handle loading local attr values from the
	 * xfblob data while flushing stashed attrs to the temporary file.
	 * We only realloc the buffer when salvaging remote attr values, so
	 * TRY_HARDER means we allocate the maximal attr value size.
	 */
	if (sc->flags & XCHK_TRY_HARDER)
		max_len = XATTR_SIZE_MAX;
	else
		max_len = xfs_attr_leaf_entsize_local_max(geo->blksize);
	error = xrep_parent_alloc_xattr_value(rp, max_len);
	if (error)
		goto out_xattr_name;

	/* Set up some staging memory for logging parent pointer updates. */
	descr = xchk_xfile_ino_descr(sc, "parent pointer entries");
	error = xfarray_create(descr, 0, sizeof(struct xrep_pptr),
			&rp->pptr_recs);
	kfree(descr);
	if (error)
		goto out_xattr_value;

	descr = xchk_xfile_ino_descr(sc, "parent pointer names");
	error = xfblob_create(descr, &rp->pptr_names);
	kfree(descr);
	if (error)
		goto out_recs;

	/* Set up some storage for copying attrs before the mapping exchange */
	descr = xchk_xfile_ino_descr(sc,
				"parent pointer retained xattr entries");
	error = xfarray_create(descr, 0, sizeof(struct xrep_parent_xattr),
			&rp->xattr_records);
	kfree(descr);
	if (error)
		goto out_names;

	descr = xchk_xfile_ino_descr(sc,
				"parent pointer retained xattr values");
	error = xfblob_create(descr, &rp->xattr_blobs);
	kfree(descr);
	if (error)
		goto out_attr_keys;

	error = __xrep_findparent_scan_start(sc, &rp->pscan,
			xrep_parent_live_update);
	if (error)
		goto out_attr_values;

	return 0;

out_attr_values:
	xfblob_destroy(rp->xattr_blobs);
	rp->xattr_blobs = NULL;
out_attr_keys:
	xfarray_destroy(rp->xattr_records);
	rp->xattr_records = NULL;
out_names:
	xfblob_destroy(rp->pptr_names);
	rp->pptr_names = NULL;
out_recs:
	xfarray_destroy(rp->pptr_recs);
	rp->pptr_recs = NULL;
out_xattr_value:
	kvfree(rp->xattr_value);
	rp->xattr_value = NULL;
out_xattr_name:
	kvfree(rp->xattr_name);
	rp->xattr_name = NULL;
	return error;
}

int
xrep_parent(
	struct xfs_scrub	*sc)
{
	struct xrep_parent	*rp = sc->buf;
	int			error;

	/*
	 * When the parent pointers feature is enabled, repairs are committed
	 * by atomically committing a new xattr structure and reaping the old
	 * attr fork.  Reaping requires rmap and exchange-range to be enabled.
	 */
	if (xfs_has_parent(sc->mp)) {
		if (!xfs_has_rmapbt(sc->mp))
			return -EOPNOTSUPP;
		if (!xfs_has_exchange_range(sc->mp))
			return -EOPNOTSUPP;
	}

	error = xrep_parent_setup_scan(rp);
	if (error)
		return error;

	if (xfs_has_parent(sc->mp))
		error = xrep_parent_scan_dirtree(rp);
	else
		error = xrep_parent_find_dotdot(rp);
	if (error)
		goto out_teardown;

	/* Last chance to abort before we start committing dotdot fixes. */
	if (xchk_should_terminate(sc, &error))
		goto out_teardown;

	error = xrep_parent_rebuild_tree(rp);
	if (error)
		goto out_teardown;
	if (xfs_has_parent(sc->mp) && !S_ISDIR(VFS_I(sc->ip)->i_mode)) {
		error = xrep_parent_set_nondir_nlink(rp);
		if (error)
			goto out_teardown;
	}

	error = xrep_defer_finish(sc);

out_teardown:
	xrep_parent_teardown(rp);
	return error;
}
