// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2018-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_btree.h"
#include "xfs_bit.h"
#include "xfs_log_format.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_inode.h"
#include "xfs_inode_fork.h"
#include "xfs_symlink.h"
#include "xfs_bmap.h"
#include "xfs_quota.h"
#include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_trans_space.h"
#include "xfs_symlink_remote.h"
#include "xfs_exchmaps.h"
#include "xfs_exchrange.h"
#include "xfs_health.h"
#include "scrub/xfs_scrub.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
#include "scrub/repair.h"
#include "scrub/tempfile.h"
#include "scrub/tempexch.h"
#include "scrub/reap.h"

/*
 * Symbolic Link Repair
 * ====================
 *
 * We repair symbolic links by reading whatever target data we can find, up to
 * the first NULL byte.  If the recovered target strlen matches i_size, then
 * we rewrite the target.  In all other cases, we replace the target with an
 * overly long string that cannot possibly resolve.  The new target is written
 * into a private hidden temporary file, and then a file contents exchange
 * commits the new symlink target to the file being repaired.
 */

/* Set us up to repair the symlink file. */
int
xrep_setup_symlink(
	struct xfs_scrub	*sc,
	unsigned int		*resblks)
{
	struct xfs_mount	*mp = sc->mp;
	unsigned long long	blocks;
	int			error;

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

	/*
	 * If we're doing a repair, we reserve enough blocks to write out a
	 * completely new symlink file, plus twice as many blocks as we would
	 * need if we can only allocate one block per data fork mapping.  This
	 * should cover the preallocation of the temporary file and exchanging
	 * the extent mappings.
	 *
	 * We cannot use xfs_exchmaps_estimate because we have not yet
	 * constructed the replacement symlink and therefore do not know how
	 * many extents it will use.  By the time we do, we will have a dirty
	 * transaction (which we cannot drop because we cannot drop the
	 * symlink ILOCK) and cannot ask for more reservation.
	 */
	blocks = xfs_symlink_blocks(sc->mp, XFS_SYMLINK_MAXLEN);
	blocks += xfs_bmbt_calc_size(mp, blocks) * 2;
	if (blocks > UINT_MAX)
		return -EOPNOTSUPP;

	*resblks += blocks;
	return 0;
}

/*
 * Try to salvage the pathname from remote blocks.  Returns the number of bytes
 * salvaged or a negative errno.
 */
STATIC ssize_t
xrep_symlink_salvage_remote(
	struct xfs_scrub	*sc)
{
	struct xfs_bmbt_irec	mval[XFS_SYMLINK_MAPS];
	struct xfs_inode	*ip = sc->ip;
	struct xfs_buf		*bp;
	char			*target_buf = sc->buf;
	xfs_failaddr_t		fa;
	xfs_filblks_t		fsblocks;
	xfs_daddr_t		d;
	loff_t			len;
	loff_t			offset = 0;
	unsigned int		byte_cnt;
	bool			magic_ok;
	bool			hdr_ok;
	int			n;
	int			nmaps = XFS_SYMLINK_MAPS;
	int			error;

	/* We'll only read until the buffer is full. */
	len = min_t(loff_t, ip->i_disk_size, XFS_SYMLINK_MAXLEN);
	fsblocks = xfs_symlink_blocks(sc->mp, len);
	error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0);
	if (error)
		return error;

	for (n = 0; n < nmaps; n++) {
		struct xfs_dsymlink_hdr	*dsl;

		d = XFS_FSB_TO_DADDR(sc->mp, mval[n].br_startblock);

		/* Read the rmt block.  We'll run the verifiers manually. */
		error = xfs_trans_read_buf(sc->mp, sc->tp, sc->mp->m_ddev_targp,
				d, XFS_FSB_TO_BB(sc->mp, mval[n].br_blockcount),
				0, &bp, NULL);
		if (error)
			return error;
		bp->b_ops = &xfs_symlink_buf_ops;

		/* How many bytes do we expect to get out of this buffer? */
		byte_cnt = XFS_FSB_TO_B(sc->mp, mval[n].br_blockcount);
		byte_cnt = XFS_SYMLINK_BUF_SPACE(sc->mp, byte_cnt);
		byte_cnt = min_t(unsigned int, byte_cnt, len);

		/*
		 * See if the verifiers accept this block.  We're willing to
		 * salvage if the if the offset/byte/ino are ok and either the
		 * verifier passed or the magic is ok.  Anything else and we
		 * stop dead in our tracks.
		 */
		fa = bp->b_ops->verify_struct(bp);
		dsl = bp->b_addr;
		magic_ok = dsl->sl_magic == cpu_to_be32(XFS_SYMLINK_MAGIC);
		hdr_ok = xfs_symlink_hdr_ok(ip->i_ino, offset, byte_cnt, bp);
		if (!hdr_ok || (fa != NULL && !magic_ok))
			break;

		memcpy(target_buf + offset, dsl + 1, byte_cnt);

		len -= byte_cnt;
		offset += byte_cnt;
	}
	return offset;
}

/*
 * Try to salvage an inline symlink's contents.  Returns the number of bytes
 * salvaged or a negative errno.
 */
STATIC ssize_t
xrep_symlink_salvage_inline(
	struct xfs_scrub	*sc)
{
	struct xfs_inode	*ip = sc->ip;
	char			*target_buf = sc->buf;
	char			*old_target;
	struct xfs_ifork	*ifp;
	unsigned int		nr;

	ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);
	if (!ifp->if_data)
		return 0;

	/*
	 * If inode repair zapped the link target, pretend that we didn't find
	 * any bytes at all so that we can replace the (now totally lost) link
	 * target with a warning message.
	 */
	old_target = ifp->if_data;
	if (xfs_inode_has_sickness(sc->ip, XFS_SICK_INO_SYMLINK_ZAPPED) &&
	    sc->ip->i_disk_size == 1 && old_target[0] == '?')
		return 0;

	nr = min(XFS_SYMLINK_MAXLEN, xfs_inode_data_fork_size(ip));
	strncpy(target_buf, ifp->if_data, nr);
	return nr;
}

#define DUMMY_TARGET \
	"The target of this symbolic link could not be recovered at all and " \
	"has been replaced with this explanatory message.  To avoid " \
	"accidentally pointing to an existing file path, this message is " \
	"longer than the maximum supported file name length.  That is an " \
	"acceptable length for a symlink target on XFS but will produce " \
	"File Name Too Long errors if resolved."

/* Salvage whatever we can of the target. */
STATIC int
xrep_symlink_salvage(
	struct xfs_scrub	*sc)
{
	char			*target_buf = sc->buf;
	ssize_t			buflen = 0;

	BUILD_BUG_ON(sizeof(DUMMY_TARGET) - 1 <= NAME_MAX);

	/*
	 * Salvage the target if there weren't any corruption problems observed
	 * while scanning it.
	 */
	if (!(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) {
		if (sc->ip->i_df.if_format == XFS_DINODE_FMT_LOCAL)
			buflen = xrep_symlink_salvage_inline(sc);
		else
			buflen = xrep_symlink_salvage_remote(sc);
		if (buflen < 0)
			return buflen;

		/*
		 * NULL-terminate the buffer because the ondisk target does not
		 * do that for us.  If salvage didn't find the exact amount of
		 * data that we expected to find, don't salvage anything.
		 */
		target_buf[buflen] = 0;
		if (strlen(target_buf) != sc->ip->i_disk_size)
			buflen = 0;
	}

	/*
	 * Change an empty target into a dummy target and clear the symlink
	 * target zapped flag.
	 */
	if (buflen == 0) {
		sc->sick_mask |= XFS_SICK_INO_SYMLINK_ZAPPED;
		sprintf(target_buf, DUMMY_TARGET);
	}

	trace_xrep_symlink_salvage_target(sc->ip, target_buf,
			strlen(target_buf));
	return 0;
}

STATIC void
xrep_symlink_local_to_remote(
	struct xfs_trans	*tp,
	struct xfs_buf		*bp,
	struct xfs_inode	*ip,
	struct xfs_ifork	*ifp,
	void			*priv)
{
	struct xfs_scrub	*sc = priv;
	struct xfs_dsymlink_hdr	*dsl = bp->b_addr;

	xfs_symlink_local_to_remote(tp, bp, ip, ifp, NULL);

	if (!xfs_has_crc(sc->mp))
		return;

	dsl->sl_owner = cpu_to_be64(sc->ip->i_ino);
	xfs_trans_log_buf(tp, bp, 0,
			  sizeof(struct xfs_dsymlink_hdr) + ifp->if_bytes - 1);
}

/*
 * Prepare both links' data forks for an exchange.  Promote the tempfile from
 * local format to extents format, and if the file being repaired has a short
 * format data fork, turn it into an empty extent list.
 */
STATIC int
xrep_symlink_swap_prep(
	struct xfs_scrub	*sc,
	bool			temp_local,
	bool			ip_local)
{
	int			error;

	/*
	 * If the temp link is in shortform format, convert that to a remote
	 * target so that we can use the atomic mapping exchange.
	 */
	if (temp_local) {
		int		logflags = XFS_ILOG_CORE;

		error = xfs_bmap_local_to_extents(sc->tp, sc->tempip, 1,
				&logflags, XFS_DATA_FORK,
				xrep_symlink_local_to_remote,
				sc);
		if (error)
			return error;

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

		error = xfs_defer_finish(&sc->tp);
		if (error)
			return error;
	}

	/*
	 * If the file being repaired had a shortform data fork, convert that
	 * to an empty extent list in preparation for the atomic mapping
	 * exchange.
	 */
	if (ip_local) {
		struct xfs_ifork	*ifp;

		ifp = xfs_ifork_ptr(sc->ip, XFS_DATA_FORK);
		xfs_idestroy_fork(ifp);
		ifp->if_format = XFS_DINODE_FMT_EXTENTS;
		ifp->if_nextents = 0;
		ifp->if_bytes = 0;
		ifp->if_data = NULL;
		ifp->if_height = 0;

		xfs_trans_log_inode(sc->tp, sc->ip,
				XFS_ILOG_CORE | XFS_ILOG_DDATA);
	}

	return 0;
}

/* Exchange the temporary symlink's data fork with the one being repaired. */
STATIC int
xrep_symlink_swap(
	struct xfs_scrub	*sc)
{
	struct xrep_tempexch	*tx = sc->buf;
	bool			ip_local, temp_local;
	int			error;

	ip_local = sc->ip->i_df.if_format == XFS_DINODE_FMT_LOCAL;
	temp_local = sc->tempip->i_df.if_format == XFS_DINODE_FMT_LOCAL;

	/*
	 * If the both links have a local format data fork and the rebuilt
	 * remote data would fit in the repaired file's data fork, copy the
	 * contents from the tempfile and declare ourselves done.
	 */
	if (ip_local && temp_local &&
	    sc->tempip->i_disk_size <= xfs_inode_data_fork_size(sc->ip)) {
		xrep_tempfile_copyout_local(sc, XFS_DATA_FORK);
		return 0;
	}

	/* Otherwise, make sure both data forks are in block-mapping mode. */
	error = xrep_symlink_swap_prep(sc, temp_local, ip_local);
	if (error)
		return error;

	return xrep_tempexch_contents(sc, tx);
}

/*
 * Free all the remote blocks and reset the data fork.  The caller must join
 * the inode to the transaction.  This function returns with the inode joined
 * to a clean scrub transaction.
 */
STATIC int
xrep_symlink_reset_fork(
	struct xfs_scrub	*sc)
{
	struct xfs_ifork	*ifp = xfs_ifork_ptr(sc->tempip, XFS_DATA_FORK);
	int			error;

	/* Unmap all the remote target buffers. */
	if (xfs_ifork_has_extents(ifp)) {
		error = xrep_reap_ifork(sc, sc->tempip, XFS_DATA_FORK);
		if (error)
			return error;
	}

	trace_xrep_symlink_reset_fork(sc->tempip);

	/* Reset the temp symlink target to dummy content. */
	xfs_idestroy_fork(ifp);
	return xfs_symlink_write_target(sc->tp, sc->tempip, sc->tempip->i_ino,
			"?", 1, 0, 0);
}

/*
 * Reinitialize a link target.  Caller must ensure the inode is joined to
 * the transaction.
 */
STATIC int
xrep_symlink_rebuild(
	struct xfs_scrub	*sc)
{
	struct xrep_tempexch	*tx;
	char			*target_buf = sc->buf;
	xfs_fsblock_t		fs_blocks;
	unsigned int		target_len;
	unsigned int		resblks;
	int			error;

	/* How many blocks do we need? */
	target_len = strlen(target_buf);
	ASSERT(target_len != 0);
	if (target_len == 0 || target_len > XFS_SYMLINK_MAXLEN)
		return -EFSCORRUPTED;

	trace_xrep_symlink_rebuild(sc->ip);

	/*
	 * In preparation to write the new symlink target to the temporary
	 * file, drop the ILOCK of the file being repaired (it shouldn't be
	 * joined) and take the ILOCK of the temporary file.
	 *
	 * The VFS does not take the IOLOCK while reading a symlink (and new
	 * symlinks are hidden with INEW until they've been written) so it's
	 * possible that a readlink() could see the old corrupted contents
	 * while we're doing this.
	 */
	xchk_iunlock(sc, XFS_ILOCK_EXCL);
	xrep_tempfile_ilock(sc);
	xfs_trans_ijoin(sc->tp, sc->tempip, 0);

	/*
	 * Reserve resources to reinitialize the target.  We're allowed to
	 * exceed file quota to repair inconsistent metadata, though this is
	 * unlikely.
	 */
	fs_blocks = xfs_symlink_blocks(sc->mp, target_len);
	resblks = xfs_symlink_space_res(sc->mp, target_len, fs_blocks);
	error = xfs_trans_reserve_quota_nblks(sc->tp, sc->tempip, resblks, 0,
			true);
	if (error)
		return error;

	/* Erase the dummy target set up by the tempfile initialization. */
	xfs_idestroy_fork(&sc->tempip->i_df);
	sc->tempip->i_df.if_bytes = 0;
	sc->tempip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;

	/* Write the salvaged target to the temporary link. */
	error = xfs_symlink_write_target(sc->tp, sc->tempip, sc->ip->i_ino,
			target_buf, target_len, fs_blocks, resblks);
	if (error)
		return error;

	/*
	 * Commit the repair transaction so that we can use the atomic mapping
	 * exchange functions to compute the correct block reservations and
	 * re-lock the inodes.
	 */
	target_buf = NULL;
	error = xrep_trans_commit(sc);
	if (error)
		return error;

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

	xrep_tempfile_iunlock(sc);

	/*
	 * We're done with the temporary buffer, so we can reuse it for the
	 * tempfile contents exchange information.
	 */
	tx = sc->buf;
	error = xrep_tempexch_trans_alloc(sc, XFS_DATA_FORK, tx);
	if (error)
		return error;

	/*
	 * Exchange the temp link's data fork with the file being repaired.
	 * This recreates the transaction and takes the ILOCKs of the file
	 * being repaired and the temporary file.
	 */
	error = xrep_symlink_swap(sc);
	if (error)
		return error;

	/*
	 * Release the old symlink blocks and reset the data fork of the temp
	 * link to an empty shortform link.  This is the last repair action we
	 * perform on the symlink, so we don't need to clean the transaction.
	 */
	return xrep_symlink_reset_fork(sc);
}

/* Repair a symbolic link. */
int
xrep_symlink(
	struct xfs_scrub	*sc)
{
	int			error;

	/* The rmapbt is required to reap the old data fork. */
	if (!xfs_has_rmapbt(sc->mp))
		return -EOPNOTSUPP;
	/* We require atomic file exchange range to rebuild anything. */
	if (!xfs_has_exchange_range(sc->mp))
		return -EOPNOTSUPP;

	ASSERT(sc->ilock_flags & XFS_ILOCK_EXCL);

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

	/* Now reset the target. */
	error = xrep_symlink_rebuild(sc);
	if (error)
		return error;

	return xrep_trans_commit(sc);
}
