// 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 "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/listxattr.h"

/*
 * Finding the Parent of a Directory
 * =================================
 *
 * Directories have parent pointers, in the sense that each directory contains
 * a dotdot entry that points to the single allowed parent.  The brute force
 * way to find the parent of a given directory is to scan every directory in
 * the filesystem looking for a child dirent that references this directory.
 *
 * This module wraps the process of scanning the directory tree.  It requires
 * that @sc->ip is the directory whose parent we want to find, and that the
 * caller hold only the IOLOCK on that directory.  The scan itself needs to
 * take the ILOCK of each directory visited.
 *
 * Because we cannot hold @sc->ip's ILOCK during a scan of the whole fs, it is
 * necessary to use dirent hook to update the parent scan results.  Callers
 * must not read the scan results without re-taking @sc->ip's ILOCK.
 *
 * There are a few shortcuts that we can take to avoid scanning the entire
 * filesystem, such as noticing directory tree roots and querying the dentry
 * cache for parent information.
 */

struct xrep_findparent_info {
	/* The directory currently being scanned. */
	struct xfs_inode	*dp;

	/*
	 * Scrub context.  We're looking for a @dp containing a directory
	 * entry pointing to sc->ip->i_ino.
	 */
	struct xfs_scrub	*sc;

	/* Optional scan information for a xrep_findparent_scan call. */
	struct xrep_parent_scan_info *parent_scan;

	/*
	 * Parent that we've found for sc->ip.  If we're scanning the entire
	 * directory tree, we need this to ensure that we only find /one/
	 * parent directory.
	 */
	xfs_ino_t		found_parent;

	/*
	 * This is set to true if @found_parent was not observed directly from
	 * the directory scan but by noticing a change in dotdot entries after
	 * cycling the sc->ip IOLOCK.
	 */
	bool			parent_tentative;
};

/*
 * If this directory entry points to the scrub target inode, then the directory
 * we're scanning is the parent of the scrub target inode.
 */
STATIC int
xrep_findparent_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_findparent_info	*fpi = priv;
	int				error = 0;

	if (xchk_should_terminate(fpi->sc, &error))
		return error;

	if (ino != fpi->sc->ip->i_ino)
		return 0;

	/* Ignore garbage directory entry names. */
	if (name->len == 0 || !xfs_dir2_namecheck(name->name, name->len))
		return -EFSCORRUPTED;

	/*
	 * Ignore dotdot and dot entries -- we're looking for parent -> child
	 * links only.
	 */
	if (name->name[0] == '.' && (name->len == 1 ||
				     (name->len == 2 && name->name[1] == '.')))
		return 0;

	/* Uhoh, more than one parent for a dir? */
	if (fpi->found_parent != NULLFSINO &&
	    !(fpi->parent_tentative && fpi->found_parent == fpi->dp->i_ino)) {
		trace_xrep_findparent_dirent(fpi->sc->ip, 0);
		return -EFSCORRUPTED;
	}

	/* We found a potential parent; remember this. */
	trace_xrep_findparent_dirent(fpi->sc->ip, fpi->dp->i_ino);
	fpi->found_parent = fpi->dp->i_ino;
	fpi->parent_tentative = false;

	if (fpi->parent_scan)
		xrep_findparent_scan_found(fpi->parent_scan, fpi->dp->i_ino);

	return 0;
}

/*
 * If this is a directory, walk the dirents looking for any that point to the
 * scrub target inode.
 */
STATIC int
xrep_findparent_walk_directory(
	struct xrep_findparent_info	*fpi)
{
	struct xfs_scrub		*sc = fpi->sc;
	struct xfs_inode		*dp = fpi->dp;
	unsigned int			lock_mode;
	int				error = 0;

	/*
	 * The inode being scanned cannot be its own parent, nor can any
	 * temporary directory we created to stage this repair.
	 */
	if (dp == sc->ip || dp == sc->tempip)
		return 0;

	/*
	 * Similarly, temporary files created to stage a repair cannot be the
	 * parent of this inode.
	 */
	if (xrep_is_tempfile(dp))
		return 0;

	/*
	 * Scan the directory to see if there it contains an entry pointing to
	 * the directory that we are repairing.
	 */
	lock_mode = xfs_ilock_data_map_shared(dp);

	/*
	 * If this directory is known to be sick, we cannot scan it reliably
	 * and must abort.
	 */
	if (xfs_inode_has_sickness(dp, XFS_SICK_INO_CORE |
				       XFS_SICK_INO_BMBTD |
				       XFS_SICK_INO_DIR)) {
		error = -EFSCORRUPTED;
		goto out_unlock;
	}

	/*
	 * We cannot complete our parent pointer scan if a directory looks as
	 * though it has been zapped by the inode record repair code.
	 */
	if (xchk_dir_looks_zapped(dp)) {
		error = -EBUSY;
		goto out_unlock;
	}

	error = xchk_dir_walk(sc, dp, xrep_findparent_dirent, fpi);
	if (error)
		goto out_unlock;

out_unlock:
	xfs_iunlock(dp, lock_mode);
	return error;
}

/*
 * Update this directory's dotdot pointer based on ongoing dirent updates.
 */
STATIC int
xrep_findparent_live_update(
	struct notifier_block		*nb,
	unsigned long			action,
	void				*data)
{
	struct xfs_dir_update_params	*p = data;
	struct xrep_parent_scan_info	*pscan;
	struct xfs_scrub		*sc;

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

	/*
	 * If @p->ip is the subdirectory that we're interested in and we've
	 * already scanned @p->dp, update the dotdot target inumber to the
	 * parent inode.
	 */
	if (p->ip->i_ino == sc->ip->i_ino &&
	    xchk_iscan_want_live_update(&pscan->iscan, p->dp->i_ino)) {
		if (p->delta > 0) {
			xrep_findparent_scan_found(pscan, p->dp->i_ino);
		} else {
			xrep_findparent_scan_found(pscan, NULLFSINO);
		}
	}

	return NOTIFY_DONE;
}

/*
 * Set up a scan to find the parent of a directory.  The provided dirent hook
 * will be called when there is a dotdot update for the inode being repaired.
 */
int
__xrep_findparent_scan_start(
	struct xfs_scrub		*sc,
	struct xrep_parent_scan_info	*pscan,
	notifier_fn_t			custom_fn)
{
	int				error;

	if (!(sc->flags & XCHK_FSGATES_DIRENTS)) {
		ASSERT(sc->flags & XCHK_FSGATES_DIRENTS);
		return -EINVAL;
	}

	pscan->sc = sc;
	pscan->parent_ino = NULLFSINO;

	mutex_init(&pscan->lock);

	xchk_iscan_start(sc, 30000, 100, &pscan->iscan);

	/*
	 * Hook into the dirent update code.  The hook only operates on inodes
	 * that were already scanned, and the scanner thread takes each inode's
	 * ILOCK, which means that any in-progress inode updates will finish
	 * before we can scan the inode.
	 */
	if (custom_fn)
		xfs_dir_hook_setup(&pscan->dhook, custom_fn);
	else
		xfs_dir_hook_setup(&pscan->dhook, xrep_findparent_live_update);
	error = xfs_dir_hook_add(sc->mp, &pscan->dhook);
	if (error)
		goto out_iscan;

	return 0;
out_iscan:
	xchk_iscan_teardown(&pscan->iscan);
	mutex_destroy(&pscan->lock);
	return error;
}

/*
 * Scan the entire filesystem looking for a parent inode for the inode being
 * scrubbed.  @sc->ip must not be the root of a directory tree.  Callers must
 * not hold a dirty transaction or any lock that would interfere with taking
 * an ILOCK.
 *
 * Returns 0 with @pscan->parent_ino set to the parent that we found.
 * Returns 0 with @pscan->parent_ino set to NULLFSINO if we found no parents.
 * Returns the usual negative errno if something else happened.
 */
int
xrep_findparent_scan(
	struct xrep_parent_scan_info	*pscan)
{
	struct xrep_findparent_info	fpi = {
		.sc			= pscan->sc,
		.found_parent		= NULLFSINO,
		.parent_scan		= pscan,
	};
	struct xfs_scrub		*sc = pscan->sc;
	int				ret;

	ASSERT(S_ISDIR(VFS_IC(sc->ip)->i_mode));

	while ((ret = xchk_iscan_iter(&pscan->iscan, &fpi.dp)) == 1) {
		if (S_ISDIR(VFS_I(fpi.dp)->i_mode))
			ret = xrep_findparent_walk_directory(&fpi);
		else
			ret = 0;
		xchk_iscan_mark_visited(&pscan->iscan, fpi.dp);
		xchk_irele(sc, fpi.dp);
		if (ret)
			break;

		if (xchk_should_terminate(sc, &ret))
			break;
	}
	xchk_iscan_iter_finish(&pscan->iscan);

	return ret;
}

/* Tear down a parent scan. */
void
xrep_findparent_scan_teardown(
	struct xrep_parent_scan_info	*pscan)
{
	xfs_dir_hook_del(pscan->sc->mp, &pscan->dhook);
	xchk_iscan_teardown(&pscan->iscan);
	mutex_destroy(&pscan->lock);
}

/* Finish a parent scan early. */
void
xrep_findparent_scan_finish_early(
	struct xrep_parent_scan_info	*pscan,
	xfs_ino_t			ino)
{
	xrep_findparent_scan_found(pscan, ino);
	xchk_iscan_finish_early(&pscan->iscan);
}

/*
 * Confirm that the directory @parent_ino actually contains a directory entry
 * pointing to the child @sc->ip->ino.  This function returns one of several
 * ways:
 *
 * Returns 0 with @parent_ino unchanged if the parent was confirmed.
 * Returns 0 with @parent_ino set to NULLFSINO if the parent was not valid.
 * Returns the usual negative errno if something else happened.
 */
int
xrep_findparent_confirm(
	struct xfs_scrub	*sc,
	xfs_ino_t		*parent_ino)
{
	struct xrep_findparent_info fpi = {
		.sc		= sc,
		.found_parent	= NULLFSINO,
	};
	int			error;

	/*
	 * The root directory always points to itself.  Unlinked dirs can point
	 * anywhere, so we point them at the root dir too.
	 */
	if (sc->ip == sc->mp->m_rootip || VFS_I(sc->ip)->i_nlink == 0) {
		*parent_ino = sc->mp->m_sb.sb_rootino;
		return 0;
	}

	/* Reject garbage parent inode numbers and self-referential parents. */
	if (*parent_ino == NULLFSINO)
	       return 0;
	if (!xfs_verify_dir_ino(sc->mp, *parent_ino) ||
	    *parent_ino == sc->ip->i_ino) {
		*parent_ino = NULLFSINO;
		return 0;
	}

	error = xchk_iget(sc, *parent_ino, &fpi.dp);
	if (error)
		return error;

	if (!S_ISDIR(VFS_I(fpi.dp)->i_mode)) {
		*parent_ino = NULLFSINO;
		goto out_rele;
	}

	error = xrep_findparent_walk_directory(&fpi);
	if (error)
		goto out_rele;

	*parent_ino = fpi.found_parent;
out_rele:
	xchk_irele(sc, fpi.dp);
	return error;
}

/*
 * If we're the root of a directory tree, we are our own parent.  If we're an
 * unlinked directory, the parent /won't/ have a link to us.  Set the parent
 * directory to the root for both cases.  Returns NULLFSINO if we don't know
 * what to do.
 */
xfs_ino_t
xrep_findparent_self_reference(
	struct xfs_scrub	*sc)
{
	if (sc->ip->i_ino == sc->mp->m_sb.sb_rootino)
		return sc->mp->m_sb.sb_rootino;

	if (VFS_I(sc->ip)->i_nlink == 0)
		return sc->mp->m_sb.sb_rootino;

	return NULLFSINO;
}

/* Check the dentry cache to see if knows of a parent for the scrub target. */
xfs_ino_t
xrep_findparent_from_dcache(
	struct xfs_scrub	*sc)
{
	struct inode		*pip = NULL;
	struct dentry		*dentry, *parent;
	xfs_ino_t		ret = NULLFSINO;

	dentry = d_find_alias(VFS_I(sc->ip));
	if (!dentry)
		goto out;

	parent = dget_parent(dentry);
	if (!parent)
		goto out_dput;

	ASSERT(parent->d_sb == sc->ip->i_mount->m_super);

	pip = igrab(d_inode(parent));
	dput(parent);

	if (S_ISDIR(pip->i_mode)) {
		trace_xrep_findparent_from_dcache(sc->ip, XFS_I(pip)->i_ino);
		ret = XFS_I(pip)->i_ino;
	}

	xchk_irele(sc, XFS_I(pip));

out_dput:
	dput(dentry);
out:
	return ret;
}
