// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2018-2023 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_alloc.h"
#include "xfs_bmap.h"
#include "xfs_quota.h"
#include "xfs_qm.h"
#include "xfs_dquot.h"
#include "xfs_dquot_item.h"
#include "xfs_reflink.h"
#include "xfs_bmap_btree.h"
#include "xfs_trans_space.h"
#include "scrub/xfs_scrub.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/quota.h"
#include "scrub/trace.h"
#include "scrub/repair.h"

/*
 * Quota Repair
 * ============
 *
 * Quota repairs are fairly simplistic; we fix everything that the dquot
 * verifiers complain about, cap any counters or limits that make no sense,
 * and schedule a quotacheck if we had to fix anything.  We also repair any
 * data fork extent records that don't apply to metadata files.
 */

struct xrep_quota_info {
	struct xfs_scrub	*sc;
	bool			need_quotacheck;
};

/*
 * Allocate a new block into a sparse hole in the quota file backing this
 * dquot, initialize the block, and commit the whole mess.
 */
STATIC int
xrep_quota_item_fill_bmap_hole(
	struct xfs_scrub	*sc,
	struct xfs_dquot	*dq,
	struct xfs_bmbt_irec	*irec)
{
	struct xfs_buf		*bp;
	struct xfs_mount	*mp = sc->mp;
	int			nmaps = 1;
	int			error;

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

	/* Map a block into the file. */
	error = xfs_trans_reserve_more(sc->tp, XFS_QM_DQALLOC_SPACE_RES(mp),
			0);
	if (error)
		return error;

	error = xfs_bmapi_write(sc->tp, sc->ip, dq->q_fileoffset,
			XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, 0,
			irec, &nmaps);
	if (error)
		return error;

	dq->q_blkno = XFS_FSB_TO_DADDR(mp, irec->br_startblock);

	trace_xrep_dquot_item_fill_bmap_hole(sc->mp, dq->q_type, dq->q_id);

	/* Initialize the new block. */
	error = xfs_trans_get_buf(sc->tp, mp->m_ddev_targp, dq->q_blkno,
			mp->m_quotainfo->qi_dqchunklen, 0, &bp);
	if (error)
		return error;
	bp->b_ops = &xfs_dquot_buf_ops;

	xfs_qm_init_dquot_blk(sc->tp, dq->q_id, dq->q_type, bp);
	xfs_buf_set_ref(bp, XFS_DQUOT_REF);

	/*
	 * Finish the mapping transactions and roll one more time to
	 * disconnect sc->ip from sc->tp.
	 */
	error = xrep_defer_finish(sc);
	if (error)
		return error;
	return xfs_trans_roll(&sc->tp);
}

/* Make sure there's a written block backing this dquot */
STATIC int
xrep_quota_item_bmap(
	struct xfs_scrub	*sc,
	struct xfs_dquot	*dq,
	bool			*dirty)
{
	struct xfs_bmbt_irec	irec;
	struct xfs_mount	*mp = sc->mp;
	struct xfs_quotainfo	*qi = mp->m_quotainfo;
	xfs_fileoff_t		offset = dq->q_id / qi->qi_dqperchunk;
	int			nmaps = 1;
	int			error;

	/* The computed file offset should always be valid. */
	if (!xfs_verify_fileoff(mp, offset)) {
		ASSERT(xfs_verify_fileoff(mp, offset));
		return -EFSCORRUPTED;
	}
	dq->q_fileoffset = offset;

	error = xfs_bmapi_read(sc->ip, offset, 1, &irec, &nmaps, 0);
	if (error)
		return error;

	if (nmaps < 1 || !xfs_bmap_is_real_extent(&irec)) {
		/* Hole/delalloc extent; allocate a real block. */
		error = xrep_quota_item_fill_bmap_hole(sc, dq, &irec);
		if (error)
			return error;
	} else if (irec.br_state != XFS_EXT_NORM) {
		/* Unwritten extent, which we already took care of? */
		ASSERT(irec.br_state == XFS_EXT_NORM);
		return -EFSCORRUPTED;
	} else if (dq->q_blkno != XFS_FSB_TO_DADDR(mp, irec.br_startblock)) {
		/*
		 * If the cached daddr is incorrect, repair probably punched a
		 * hole out of the quota file and filled it back in with a new
		 * block.  Update the block mapping in the dquot.
		 */
		dq->q_blkno = XFS_FSB_TO_DADDR(mp, irec.br_startblock);
	}

	*dirty = true;
	return 0;
}

/* Reset quota timers if incorrectly set. */
static inline void
xrep_quota_item_timer(
	struct xfs_scrub		*sc,
	const struct xfs_dquot_res	*res,
	bool				*dirty)
{
	if ((res->softlimit && res->count > res->softlimit) ||
	    (res->hardlimit && res->count > res->hardlimit)) {
		if (!res->timer)
			*dirty = true;
	} else {
		if (res->timer)
			*dirty = true;
	}
}

/* Scrub the fields in an individual quota item. */
STATIC int
xrep_quota_item(
	struct xrep_quota_info	*rqi,
	struct xfs_dquot	*dq)
{
	struct xfs_scrub	*sc = rqi->sc;
	struct xfs_mount	*mp = sc->mp;
	xfs_ino_t		fs_icount;
	bool			dirty = false;
	int			error = 0;

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

	/*
	 * We might need to fix holes in the bmap record for the storage
	 * backing this dquot, so we need to lock the dquot and the quota file.
	 * dqiterate gave us a locked dquot, so drop the dquot lock to get the
	 * ILOCK_EXCL.
	 */
	xfs_dqunlock(dq);
	xchk_ilock(sc, XFS_ILOCK_EXCL);
	xfs_dqlock(dq);

	error = xrep_quota_item_bmap(sc, dq, &dirty);
	xchk_iunlock(sc, XFS_ILOCK_EXCL);
	if (error)
		return error;

	/* Check the limits. */
	if (dq->q_blk.softlimit > dq->q_blk.hardlimit) {
		dq->q_blk.softlimit = dq->q_blk.hardlimit;
		dirty = true;
	}

	if (dq->q_ino.softlimit > dq->q_ino.hardlimit) {
		dq->q_ino.softlimit = dq->q_ino.hardlimit;
		dirty = true;
	}

	if (dq->q_rtb.softlimit > dq->q_rtb.hardlimit) {
		dq->q_rtb.softlimit = dq->q_rtb.hardlimit;
		dirty = true;
	}

	/*
	 * Check that usage doesn't exceed physical limits.  However, on
	 * a reflink filesystem we're allowed to exceed physical space
	 * if there are no quota limits.  We don't know what the real number
	 * is, but we can make quotacheck find out for us.
	 */
	if (!xfs_has_reflink(mp) && dq->q_blk.count > mp->m_sb.sb_dblocks) {
		dq->q_blk.reserved -= dq->q_blk.count;
		dq->q_blk.reserved += mp->m_sb.sb_dblocks;
		dq->q_blk.count = mp->m_sb.sb_dblocks;
		rqi->need_quotacheck = true;
		dirty = true;
	}
	fs_icount = percpu_counter_sum(&mp->m_icount);
	if (dq->q_ino.count > fs_icount) {
		dq->q_ino.reserved -= dq->q_ino.count;
		dq->q_ino.reserved += fs_icount;
		dq->q_ino.count = fs_icount;
		rqi->need_quotacheck = true;
		dirty = true;
	}
	if (dq->q_rtb.count > mp->m_sb.sb_rblocks) {
		dq->q_rtb.reserved -= dq->q_rtb.count;
		dq->q_rtb.reserved += mp->m_sb.sb_rblocks;
		dq->q_rtb.count = mp->m_sb.sb_rblocks;
		rqi->need_quotacheck = true;
		dirty = true;
	}

	xrep_quota_item_timer(sc, &dq->q_blk, &dirty);
	xrep_quota_item_timer(sc, &dq->q_ino, &dirty);
	xrep_quota_item_timer(sc, &dq->q_rtb, &dirty);

	if (!dirty)
		return 0;

	trace_xrep_dquot_item(sc->mp, dq->q_type, dq->q_id);

	dq->q_flags |= XFS_DQFLAG_DIRTY;
	xfs_trans_dqjoin(sc->tp, dq);
	if (dq->q_id) {
		xfs_qm_adjust_dqlimits(dq);
		xfs_qm_adjust_dqtimers(dq);
	}
	xfs_trans_log_dquot(sc->tp, dq);
	error = xfs_trans_roll(&sc->tp);
	xfs_dqlock(dq);
	return error;
}

/* Fix a quota timer so that we can pass the verifier. */
STATIC void
xrep_quota_fix_timer(
	struct xfs_mount	*mp,
	const struct xfs_disk_dquot *ddq,
	__be64			softlimit,
	__be64			countnow,
	__be32			*timer,
	time64_t		timelimit)
{
	uint64_t		soft = be64_to_cpu(softlimit);
	uint64_t		count = be64_to_cpu(countnow);
	time64_t		new_timer;
	uint32_t		t;

	if (!soft || count <= soft || *timer != 0)
		return;

	new_timer = xfs_dquot_set_timeout(mp,
				ktime_get_real_seconds() + timelimit);
	if (ddq->d_type & XFS_DQTYPE_BIGTIME)
		t = xfs_dq_unix_to_bigtime(new_timer);
	else
		t = new_timer;

	*timer = cpu_to_be32(t);
}

/* Fix anything the verifiers complain about. */
STATIC int
xrep_quota_block(
	struct xfs_scrub	*sc,
	xfs_daddr_t		daddr,
	xfs_dqtype_t		dqtype,
	xfs_dqid_t		id)
{
	struct xfs_dqblk	*dqblk;
	struct xfs_disk_dquot	*ddq;
	struct xfs_quotainfo	*qi = sc->mp->m_quotainfo;
	struct xfs_def_quota	*defq = xfs_get_defquota(qi, dqtype);
	struct xfs_buf		*bp = NULL;
	enum xfs_blft		buftype = 0;
	int			i;
	int			error;

	error = xfs_trans_read_buf(sc->mp, sc->tp, sc->mp->m_ddev_targp, daddr,
			qi->qi_dqchunklen, 0, &bp, &xfs_dquot_buf_ops);
	switch (error) {
	case -EFSBADCRC:
	case -EFSCORRUPTED:
		/* Failed verifier, retry read with no ops. */
		error = xfs_trans_read_buf(sc->mp, sc->tp,
				sc->mp->m_ddev_targp, daddr, qi->qi_dqchunklen,
				0, &bp, NULL);
		if (error)
			return error;
		break;
	case 0:
		dqblk = bp->b_addr;
		ddq = &dqblk[0].dd_diskdq;

		/*
		 * If there's nothing that would impede a dqiterate, we're
		 * done.
		 */
		if ((ddq->d_type & XFS_DQTYPE_REC_MASK) != dqtype ||
		    id == be32_to_cpu(ddq->d_id)) {
			xfs_trans_brelse(sc->tp, bp);
			return 0;
		}
		break;
	default:
		return error;
	}

	/* Something's wrong with the block, fix the whole thing. */
	dqblk = bp->b_addr;
	bp->b_ops = &xfs_dquot_buf_ops;
	for (i = 0; i < qi->qi_dqperchunk; i++, dqblk++) {
		ddq = &dqblk->dd_diskdq;

		trace_xrep_disk_dquot(sc->mp, dqtype, id + i);

		ddq->d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
		ddq->d_version = XFS_DQUOT_VERSION;
		ddq->d_type = dqtype;
		ddq->d_id = cpu_to_be32(id + i);

		if (xfs_has_bigtime(sc->mp) && ddq->d_id)
			ddq->d_type |= XFS_DQTYPE_BIGTIME;

		xrep_quota_fix_timer(sc->mp, ddq, ddq->d_blk_softlimit,
				ddq->d_bcount, &ddq->d_btimer,
				defq->blk.time);

		xrep_quota_fix_timer(sc->mp, ddq, ddq->d_ino_softlimit,
				ddq->d_icount, &ddq->d_itimer,
				defq->ino.time);

		xrep_quota_fix_timer(sc->mp, ddq, ddq->d_rtb_softlimit,
				ddq->d_rtbcount, &ddq->d_rtbtimer,
				defq->rtb.time);

		/* We only support v5 filesystems so always set these. */
		uuid_copy(&dqblk->dd_uuid, &sc->mp->m_sb.sb_meta_uuid);
		xfs_update_cksum((char *)dqblk, sizeof(struct xfs_dqblk),
				 XFS_DQUOT_CRC_OFF);
		dqblk->dd_lsn = 0;
	}
	switch (dqtype) {
	case XFS_DQTYPE_USER:
		buftype = XFS_BLFT_UDQUOT_BUF;
		break;
	case XFS_DQTYPE_GROUP:
		buftype = XFS_BLFT_GDQUOT_BUF;
		break;
	case XFS_DQTYPE_PROJ:
		buftype = XFS_BLFT_PDQUOT_BUF;
		break;
	}
	xfs_trans_buf_set_type(sc->tp, bp, buftype);
	xfs_trans_log_buf(sc->tp, bp, 0, BBTOB(bp->b_length) - 1);
	return xrep_roll_trans(sc);
}

/*
 * Repair a quota file's data fork.  The function returns with the inode
 * joined.
 */
STATIC int
xrep_quota_data_fork(
	struct xfs_scrub	*sc,
	xfs_dqtype_t		dqtype)
{
	struct xfs_bmbt_irec	irec = { 0 };
	struct xfs_iext_cursor	icur;
	struct xfs_quotainfo	*qi = sc->mp->m_quotainfo;
	struct xfs_ifork	*ifp;
	xfs_fileoff_t		max_dqid_off;
	xfs_fileoff_t		off;
	xfs_fsblock_t		fsbno;
	bool			truncate = false;
	bool			joined = false;
	int			error = 0;

	error = xrep_metadata_inode_forks(sc);
	if (error)
		goto out;

	/* Check for data fork problems that apply only to quota files. */
	max_dqid_off = XFS_DQ_ID_MAX / qi->qi_dqperchunk;
	ifp = xfs_ifork_ptr(sc->ip, XFS_DATA_FORK);
	for_each_xfs_iext(ifp, &icur, &irec) {
		if (isnullstartblock(irec.br_startblock)) {
			error = -EFSCORRUPTED;
			goto out;
		}

		if (irec.br_startoff > max_dqid_off ||
		    irec.br_startoff + irec.br_blockcount - 1 > max_dqid_off) {
			truncate = true;
			break;
		}

		/* Convert unwritten extents to real ones. */
		if (irec.br_state == XFS_EXT_UNWRITTEN) {
			struct xfs_bmbt_irec	nrec;
			int			nmap = 1;

			if (!joined) {
				xfs_trans_ijoin(sc->tp, sc->ip, 0);
				joined = true;
			}

			error = xfs_bmapi_write(sc->tp, sc->ip,
					irec.br_startoff, irec.br_blockcount,
					XFS_BMAPI_CONVERT, 0, &nrec, &nmap);
			if (error)
				goto out;
			ASSERT(nrec.br_startoff == irec.br_startoff);
			ASSERT(nrec.br_blockcount == irec.br_blockcount);

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

	if (!joined) {
		xfs_trans_ijoin(sc->tp, sc->ip, 0);
		joined = true;
	}

	if (truncate) {
		/* Erase everything after the block containing the max dquot */
		error = xfs_bunmapi_range(&sc->tp, sc->ip, 0,
				max_dqid_off * sc->mp->m_sb.sb_blocksize,
				XFS_MAX_FILEOFF);
		if (error)
			goto out;

		/* Remove all CoW reservations. */
		error = xfs_reflink_cancel_cow_blocks(sc->ip, &sc->tp, 0,
				XFS_MAX_FILEOFF, true);
		if (error)
			goto out;
		sc->ip->i_diflags2 &= ~XFS_DIFLAG2_REFLINK;

		/*
		 * Always re-log the inode so that our permanent transaction
		 * can keep on rolling it forward in the log.
		 */
		xfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE);
	}

	/* Now go fix anything that fails the verifiers. */
	for_each_xfs_iext(ifp, &icur, &irec) {
		for (fsbno = irec.br_startblock, off = irec.br_startoff;
		     fsbno < irec.br_startblock + irec.br_blockcount;
		     fsbno += XFS_DQUOT_CLUSTER_SIZE_FSB,
				off += XFS_DQUOT_CLUSTER_SIZE_FSB) {
			error = xrep_quota_block(sc,
					XFS_FSB_TO_DADDR(sc->mp, fsbno),
					dqtype, off * qi->qi_dqperchunk);
			if (error)
				goto out;
		}
	}

out:
	return error;
}

/*
 * Go fix anything in the quota items that we could have been mad about.  Now
 * that we've checked the quota inode data fork we have to drop ILOCK_EXCL to
 * use the regular dquot functions.
 */
STATIC int
xrep_quota_problems(
	struct xfs_scrub	*sc,
	xfs_dqtype_t		dqtype)
{
	struct xchk_dqiter	cursor = { };
	struct xrep_quota_info	rqi = { .sc = sc };
	struct xfs_dquot	*dq;
	int			error;

	xchk_dqiter_init(&cursor, sc, dqtype);
	while ((error = xchk_dquot_iter(&cursor, &dq)) == 1) {
		error = xrep_quota_item(&rqi, dq);
		xfs_qm_dqput(dq);
		if (error)
			break;
	}
	if (error)
		return error;

	/* Make a quotacheck happen. */
	if (rqi.need_quotacheck)
		xrep_force_quotacheck(sc, dqtype);
	return 0;
}

/* Repair all of a quota type's items. */
int
xrep_quota(
	struct xfs_scrub	*sc)
{
	xfs_dqtype_t		dqtype;
	int			error;

	dqtype = xchk_quota_to_dqtype(sc);

	/*
	 * Re-take the ILOCK so that we can fix any problems that we found
	 * with the data fork mappings, or with the dquot bufs themselves.
	 */
	if (!(sc->ilock_flags & XFS_ILOCK_EXCL))
		xchk_ilock(sc, XFS_ILOCK_EXCL);
	error = xrep_quota_data_fork(sc, dqtype);
	if (error)
		return error;

	/*
	 * Finish deferred items and roll the transaction to unjoin the quota
	 * inode from transaction so that we can unlock the quota inode; we
	 * play only with dquots from now on.
	 */
	error = xrep_defer_finish(sc);
	if (error)
		return error;
	error = xfs_trans_roll(&sc->tp);
	if (error)
		return error;
	xchk_iunlock(sc, sc->ilock_flags);

	/* Fix anything the dquot verifiers don't complain about. */
	error = xrep_quota_problems(sc, dqtype);
	if (error)
		return error;

	return xrep_trans_commit(sc);
}
