// 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_log_format.h"
#include "xfs_trans.h"
#include "xfs_inode.h"
#include "xfs_quota.h"
#include "xfs_qm.h"
#include "xfs_icache.h"
#include "xfs_bmap_util.h"
#include "xfs_ialloc.h"
#include "xfs_ag.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/repair.h"
#include "scrub/xfile.h"
#include "scrub/xfarray.h"
#include "scrub/iscan.h"
#include "scrub/quota.h"
#include "scrub/quotacheck.h"
#include "scrub/trace.h"

/*
 * Live Quotacheck
 * ===============
 *
 * Quota counters are "summary" metadata, in the sense that they are computed
 * as the summation of the block usage counts for every file on the filesystem.
 * Therefore, we compute the correct icount, bcount, and rtbcount values by
 * creating a shadow quota counter structure and walking every inode.
 */

/* Track the quota deltas for a dquot in a transaction. */
struct xqcheck_dqtrx {
	xfs_dqtype_t		q_type;
	xfs_dqid_t		q_id;

	int64_t			icount_delta;

	int64_t			bcount_delta;
	int64_t			delbcnt_delta;

	int64_t			rtbcount_delta;
	int64_t			delrtb_delta;
};

#define XQCHECK_MAX_NR_DQTRXS	(XFS_QM_TRANS_DQTYPES * XFS_QM_TRANS_MAXDQS)

/*
 * Track the quota deltas for all dquots attached to a transaction if the
 * quota deltas are being applied to an inode that we already scanned.
 */
struct xqcheck_dqacct {
	struct rhash_head	hash;
	uintptr_t		tx_id;
	struct xqcheck_dqtrx	dqtrx[XQCHECK_MAX_NR_DQTRXS];
	unsigned int		refcount;
};

/* Free a shadow dquot accounting structure. */
static void
xqcheck_dqacct_free(
	void			*ptr,
	void			*arg)
{
	struct xqcheck_dqacct	*dqa = ptr;

	kfree(dqa);
}

/* Set us up to scrub quota counters. */
int
xchk_setup_quotacheck(
	struct xfs_scrub	*sc)
{
	if (!XFS_IS_QUOTA_ON(sc->mp))
		return -ENOENT;

	xchk_fsgates_enable(sc, XCHK_FSGATES_QUOTA);

	sc->buf = kzalloc(sizeof(struct xqcheck), XCHK_GFP_FLAGS);
	if (!sc->buf)
		return -ENOMEM;

	return xchk_setup_fs(sc);
}

/*
 * Part 1: Collecting dquot resource usage counts.  For each xfs_dquot attached
 * to each inode, we create a shadow dquot, and compute the inode count and add
 * the data/rt block usage from what we see.
 *
 * To avoid false corruption reports in part 2, any failure in this part must
 * set the INCOMPLETE flag even when a negative errno is returned.  This care
 * must be taken with certain errno values (i.e. EFSBADCRC, EFSCORRUPTED,
 * ECANCELED) that are absorbed into a scrub state flag update by
 * xchk_*_process_error.  Scrub and repair share the same incore data
 * structures, so the INCOMPLETE flag is critical to prevent a repair based on
 * insufficient information.
 *
 * Because we are scanning a live filesystem, it's possible that another thread
 * will try to update the quota counters for an inode that we've already
 * scanned.  This will cause our counts to be incorrect.  Therefore, we hook
 * the live transaction code in two places: (1) when the callers update the
 * per-transaction dqtrx structure to log quota counter updates; and (2) when
 * transaction commit actually logs those updates to the incore dquot.  By
 * shadowing transaction updates in this manner, live quotacheck can ensure
 * by locking the dquot and the shadow structure that its own copies are not
 * out of date.  Because the hook code runs in a different process context from
 * the scrub code and the scrub state flags are not accessed atomically,
 * failures in the hook code must abort the iscan and the scrubber must notice
 * the aborted scan and set the incomplete flag.
 *
 * Note that we use srcu notifier hooks to minimize the overhead when live
 * quotacheck is /not/ running.
 */

/* Update an incore dquot counter information from a live update. */
static int
xqcheck_update_incore_counts(
	struct xqcheck		*xqc,
	struct xfarray		*counts,
	xfs_dqid_t		id,
	int64_t			inodes,
	int64_t			nblks,
	int64_t			rtblks)
{
	struct xqcheck_dquot	xcdq;
	int			error;

	error = xfarray_load_sparse(counts, id, &xcdq);
	if (error)
		return error;

	xcdq.flags |= XQCHECK_DQUOT_WRITTEN;
	xcdq.icount += inodes;
	xcdq.bcount += nblks;
	xcdq.rtbcount += rtblks;

	error = xfarray_store(counts, id, &xcdq);
	if (error == -EFBIG) {
		/*
		 * EFBIG means we tried to store data at too high a byte offset
		 * in the sparse array.  IOWs, we cannot complete the check and
		 * must notify userspace that the check was incomplete.
		 */
		error = -ECANCELED;
	}
	return error;
}

/* Decide if this is the shadow dquot accounting structure for a transaction. */
static int
xqcheck_dqacct_obj_cmpfn(
	struct rhashtable_compare_arg	*arg,
	const void			*obj)
{
	const uintptr_t			*tx_idp = arg->key;
	const struct xqcheck_dqacct	*dqa = obj;

	if (dqa->tx_id != *tx_idp)
		return 1;
	return 0;
}

static const struct rhashtable_params xqcheck_dqacct_hash_params = {
	.min_size		= 32,
	.key_len		= sizeof(uintptr_t),
	.key_offset		= offsetof(struct xqcheck_dqacct, tx_id),
	.head_offset		= offsetof(struct xqcheck_dqacct, hash),
	.automatic_shrinking	= true,
	.obj_cmpfn		= xqcheck_dqacct_obj_cmpfn,
};

/* Find a shadow dqtrx slot for the given dquot. */
STATIC struct xqcheck_dqtrx *
xqcheck_get_dqtrx(
	struct xqcheck_dqacct	*dqa,
	xfs_dqtype_t		q_type,
	xfs_dqid_t		q_id)
{
	int			i;

	for (i = 0; i < XQCHECK_MAX_NR_DQTRXS; i++) {
		if (dqa->dqtrx[i].q_type == 0 ||
		    (dqa->dqtrx[i].q_type == q_type &&
		     dqa->dqtrx[i].q_id == q_id))
			return &dqa->dqtrx[i];
	}

	return NULL;
}

/*
 * Create and fill out a quota delta tracking structure to shadow the updates
 * going on in the regular quota code.
 */
static int
xqcheck_mod_live_ino_dqtrx(
	struct notifier_block		*nb,
	unsigned long			action,
	void				*data)
{
	struct xfs_mod_ino_dqtrx_params *p = data;
	struct xqcheck			*xqc;
	struct xqcheck_dqacct		*dqa;
	struct xqcheck_dqtrx		*dqtrx;
	int				error;

	xqc = container_of(nb, struct xqcheck, qhook.mod_hook.nb);

	/* Skip quota reservation fields. */
	switch (action) {
	case XFS_TRANS_DQ_BCOUNT:
	case XFS_TRANS_DQ_DELBCOUNT:
	case XFS_TRANS_DQ_ICOUNT:
	case XFS_TRANS_DQ_RTBCOUNT:
	case XFS_TRANS_DQ_DELRTBCOUNT:
		break;
	default:
		return NOTIFY_DONE;
	}

	/* Ignore dqtrx updates for quota types we don't care about. */
	switch (p->q_type) {
	case XFS_DQTYPE_USER:
		if (!xqc->ucounts)
			return NOTIFY_DONE;
		break;
	case XFS_DQTYPE_GROUP:
		if (!xqc->gcounts)
			return NOTIFY_DONE;
		break;
	case XFS_DQTYPE_PROJ:
		if (!xqc->pcounts)
			return NOTIFY_DONE;
		break;
	default:
		return NOTIFY_DONE;
	}

	/* Skip inodes that haven't been scanned yet. */
	if (!xchk_iscan_want_live_update(&xqc->iscan, p->ino))
		return NOTIFY_DONE;

	/* Make a shadow quota accounting tracker for this transaction. */
	mutex_lock(&xqc->lock);
	dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id,
			xqcheck_dqacct_hash_params);
	if (!dqa) {
		dqa = kzalloc(sizeof(struct xqcheck_dqacct), XCHK_GFP_FLAGS);
		if (!dqa)
			goto out_abort;

		dqa->tx_id = p->tx_id;
		error = rhashtable_insert_fast(&xqc->shadow_dquot_acct,
				&dqa->hash, xqcheck_dqacct_hash_params);
		if (error)
			goto out_abort;
	}

	/* Find the shadow dqtrx (or an empty slot) here. */
	dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id);
	if (!dqtrx)
		goto out_abort;
	if (dqtrx->q_type == 0) {
		dqtrx->q_type = p->q_type;
		dqtrx->q_id = p->q_id;
		dqa->refcount++;
	}

	/* Update counter */
	switch (action) {
	case XFS_TRANS_DQ_BCOUNT:
		dqtrx->bcount_delta += p->delta;
		break;
	case XFS_TRANS_DQ_DELBCOUNT:
		dqtrx->delbcnt_delta += p->delta;
		break;
	case XFS_TRANS_DQ_ICOUNT:
		dqtrx->icount_delta += p->delta;
		break;
	case XFS_TRANS_DQ_RTBCOUNT:
		dqtrx->rtbcount_delta += p->delta;
		break;
	case XFS_TRANS_DQ_DELRTBCOUNT:
		dqtrx->delrtb_delta += p->delta;
		break;
	}

	mutex_unlock(&xqc->lock);
	return NOTIFY_DONE;

out_abort:
	xchk_iscan_abort(&xqc->iscan);
	mutex_unlock(&xqc->lock);
	return NOTIFY_DONE;
}

/*
 * Apply the transaction quota deltas to our shadow quota accounting info when
 * the regular quota code are doing the same.
 */
static int
xqcheck_apply_live_dqtrx(
	struct notifier_block		*nb,
	unsigned long			action,
	void				*data)
{
	struct xfs_apply_dqtrx_params	*p = data;
	struct xqcheck			*xqc;
	struct xqcheck_dqacct		*dqa;
	struct xqcheck_dqtrx		*dqtrx;
	struct xfarray			*counts;
	int				error;

	xqc = container_of(nb, struct xqcheck, qhook.apply_hook.nb);

	/* Map the dquot type to an incore counter object. */
	switch (p->q_type) {
	case XFS_DQTYPE_USER:
		counts = xqc->ucounts;
		break;
	case XFS_DQTYPE_GROUP:
		counts = xqc->gcounts;
		break;
	case XFS_DQTYPE_PROJ:
		counts = xqc->pcounts;
		break;
	default:
		return NOTIFY_DONE;
	}

	if (xchk_iscan_aborted(&xqc->iscan) || counts == NULL)
		return NOTIFY_DONE;

	/*
	 * Find the shadow dqtrx for this transaction and dquot, if any deltas
	 * need to be applied here.  If not, we're finished early.
	 */
	mutex_lock(&xqc->lock);
	dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id,
			xqcheck_dqacct_hash_params);
	if (!dqa)
		goto out_unlock;
	dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id);
	if (!dqtrx || dqtrx->q_type == 0)
		goto out_unlock;

	/* Update our shadow dquot if we're committing. */
	if (action == XFS_APPLY_DQTRX_COMMIT) {
		error = xqcheck_update_incore_counts(xqc, counts, p->q_id,
				dqtrx->icount_delta,
				dqtrx->bcount_delta + dqtrx->delbcnt_delta,
				dqtrx->rtbcount_delta + dqtrx->delrtb_delta);
		if (error)
			goto out_abort;
	}

	/* Free the shadow accounting structure if that was the last user. */
	dqa->refcount--;
	if (dqa->refcount == 0) {
		error = rhashtable_remove_fast(&xqc->shadow_dquot_acct,
				&dqa->hash, xqcheck_dqacct_hash_params);
		if (error)
			goto out_abort;
		xqcheck_dqacct_free(dqa, NULL);
	}

	mutex_unlock(&xqc->lock);
	return NOTIFY_DONE;

out_abort:
	xchk_iscan_abort(&xqc->iscan);
out_unlock:
	mutex_unlock(&xqc->lock);
	return NOTIFY_DONE;
}

/* Record this inode's quota usage in our shadow quota counter data. */
STATIC int
xqcheck_collect_inode(
	struct xqcheck		*xqc,
	struct xfs_inode	*ip)
{
	struct xfs_trans	*tp = xqc->sc->tp;
	xfs_filblks_t		nblks, rtblks;
	uint			ilock_flags = 0;
	xfs_dqid_t		id;
	bool			isreg = S_ISREG(VFS_I(ip)->i_mode);
	int			error = 0;

	if (xfs_is_quota_inode(&tp->t_mountp->m_sb, ip->i_ino)) {
		/*
		 * Quota files are never counted towards quota, so we do not
		 * need to take the lock.
		 */
		xchk_iscan_mark_visited(&xqc->iscan, ip);
		return 0;
	}

	/* Figure out the data / rt device block counts. */
	xfs_ilock(ip, XFS_IOLOCK_SHARED);
	if (isreg)
		xfs_ilock(ip, XFS_MMAPLOCK_SHARED);
	if (XFS_IS_REALTIME_INODE(ip)) {
		/*
		 * Read in the data fork for rt files so that _count_blocks
		 * can count the number of blocks allocated from the rt volume.
		 * Inodes do not track that separately.
		 */
		ilock_flags = xfs_ilock_data_map_shared(ip);
		error = xfs_iread_extents(tp, ip, XFS_DATA_FORK);
		if (error)
			goto out_abort;
	} else {
		ilock_flags = XFS_ILOCK_SHARED;
		xfs_ilock(ip, XFS_ILOCK_SHARED);
	}
	xfs_inode_count_blocks(tp, ip, &nblks, &rtblks);

	if (xchk_iscan_aborted(&xqc->iscan)) {
		error = -ECANCELED;
		goto out_incomplete;
	}

	/* Update the shadow dquot counters. */
	mutex_lock(&xqc->lock);
	if (xqc->ucounts) {
		id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_USER);
		error = xqcheck_update_incore_counts(xqc, xqc->ucounts, id, 1,
				nblks, rtblks);
		if (error)
			goto out_mutex;
	}

	if (xqc->gcounts) {
		id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_GROUP);
		error = xqcheck_update_incore_counts(xqc, xqc->gcounts, id, 1,
				nblks, rtblks);
		if (error)
			goto out_mutex;
	}

	if (xqc->pcounts) {
		id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_PROJ);
		error = xqcheck_update_incore_counts(xqc, xqc->pcounts, id, 1,
				nblks, rtblks);
		if (error)
			goto out_mutex;
	}
	mutex_unlock(&xqc->lock);

	xchk_iscan_mark_visited(&xqc->iscan, ip);
	goto out_ilock;

out_mutex:
	mutex_unlock(&xqc->lock);
out_abort:
	xchk_iscan_abort(&xqc->iscan);
out_incomplete:
	xchk_set_incomplete(xqc->sc);
out_ilock:
	xfs_iunlock(ip, ilock_flags);
	if (isreg)
		xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);
	xfs_iunlock(ip, XFS_IOLOCK_SHARED);
	return error;
}

/* Walk all the allocated inodes and run a quota scan on them. */
STATIC int
xqcheck_collect_counts(
	struct xqcheck		*xqc)
{
	struct xfs_scrub	*sc = xqc->sc;
	struct xfs_inode	*ip;
	int			error;

	/*
	 * Set up for a potentially lengthy filesystem scan by reducing our
	 * transaction resource usage for the duration.  Specifically:
	 *
	 * Cancel the transaction to release the log grant space while we scan
	 * the filesystem.
	 *
	 * Create a new empty transaction to eliminate the possibility of the
	 * inode scan deadlocking on cyclical metadata.
	 *
	 * We pass the empty transaction to the file scanning function to avoid
	 * repeatedly cycling empty transactions.  This can be done without
	 * risk of deadlock between sb_internal and the IOLOCK (we take the
	 * IOLOCK to quiesce the file before scanning) because empty
	 * transactions do not take sb_internal.
	 */
	xchk_trans_cancel(sc);
	error = xchk_trans_alloc_empty(sc);
	if (error)
		return error;

	while ((error = xchk_iscan_iter(&xqc->iscan, &ip)) == 1) {
		error = xqcheck_collect_inode(xqc, ip);
		xchk_irele(sc, ip);
		if (error)
			break;

		if (xchk_should_terminate(sc, &error))
			break;
	}
	xchk_iscan_iter_finish(&xqc->iscan);
	if (error) {
		xchk_set_incomplete(sc);
		/*
		 * 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;
	}

	/*
	 * Switch out for a real transaction in preparation for building a new
	 * tree.
	 */
	xchk_trans_cancel(sc);
	return xchk_setup_fs(sc);
}

/*
 * Part 2: Comparing dquot resource counters.  Walk each xfs_dquot, comparing
 * the resource usage counters against our shadow dquots; and then walk each
 * shadow dquot (that wasn't covered in the first part), comparing it against
 * the xfs_dquot.
 */

/*
 * Check the dquot data against what we observed.  Caller must hold the dquot
 * lock.
 */
STATIC int
xqcheck_compare_dquot(
	struct xqcheck		*xqc,
	xfs_dqtype_t		dqtype,
	struct xfs_dquot	*dq)
{
	struct xqcheck_dquot	xcdq;
	struct xfarray		*counts = xqcheck_counters_for(xqc, dqtype);
	int			error;

	if (xchk_iscan_aborted(&xqc->iscan)) {
		xchk_set_incomplete(xqc->sc);
		return -ECANCELED;
	}

	mutex_lock(&xqc->lock);
	error = xfarray_load_sparse(counts, dq->q_id, &xcdq);
	if (error)
		goto out_unlock;

	if (xcdq.icount != dq->q_ino.count)
		xchk_qcheck_set_corrupt(xqc->sc, dqtype, dq->q_id);

	if (xcdq.bcount != dq->q_blk.count)
		xchk_qcheck_set_corrupt(xqc->sc, dqtype, dq->q_id);

	if (xcdq.rtbcount != dq->q_rtb.count)
		xchk_qcheck_set_corrupt(xqc->sc, dqtype, dq->q_id);

	xcdq.flags |= (XQCHECK_DQUOT_COMPARE_SCANNED | XQCHECK_DQUOT_WRITTEN);
	error = xfarray_store(counts, dq->q_id, &xcdq);
	if (error == -EFBIG) {
		/*
		 * EFBIG means we tried to store data at too high a byte offset
		 * in the sparse array.  IOWs, we cannot complete the check and
		 * must notify userspace that the check was incomplete.  This
		 * should never happen outside of the collection phase.
		 */
		xchk_set_incomplete(xqc->sc);
		error = -ECANCELED;
	}
	mutex_unlock(&xqc->lock);
	if (error)
		return error;

	if (xqc->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
		return -ECANCELED;

	return 0;

out_unlock:
	mutex_unlock(&xqc->lock);
	return error;
}

/*
 * Walk all the observed dquots, and make sure there's a matching incore
 * dquot and that its counts match ours.
 */
STATIC int
xqcheck_walk_observations(
	struct xqcheck		*xqc,
	xfs_dqtype_t		dqtype)
{
	struct xqcheck_dquot	xcdq;
	struct xfs_dquot	*dq;
	struct xfarray		*counts = xqcheck_counters_for(xqc, dqtype);
	xfarray_idx_t		cur = XFARRAY_CURSOR_INIT;
	int			error;

	mutex_lock(&xqc->lock);
	while ((error = xfarray_iter(counts, &cur, &xcdq)) == 1) {
		xfs_dqid_t	id = cur - 1;

		if (xcdq.flags & XQCHECK_DQUOT_COMPARE_SCANNED)
			continue;

		mutex_unlock(&xqc->lock);

		error = xfs_qm_dqget(xqc->sc->mp, id, dqtype, false, &dq);
		if (error == -ENOENT) {
			xchk_qcheck_set_corrupt(xqc->sc, dqtype, id);
			return 0;
		}
		if (error)
			return error;

		error = xqcheck_compare_dquot(xqc, dqtype, dq);
		xfs_qm_dqput(dq);
		if (error)
			return error;

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

		mutex_lock(&xqc->lock);
	}
	mutex_unlock(&xqc->lock);

	return error;
}

/* Compare the quota counters we observed against the live dquots. */
STATIC int
xqcheck_compare_dqtype(
	struct xqcheck		*xqc,
	xfs_dqtype_t		dqtype)
{
	struct xchk_dqiter	cursor = { };
	struct xfs_scrub	*sc = xqc->sc;
	struct xfs_dquot	*dq;
	int			error;

	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
		return 0;

	/* If the quota CHKD flag is cleared, we need to repair this quota. */
	if (!(xfs_quota_chkd_flag(dqtype) & sc->mp->m_qflags)) {
		xchk_qcheck_set_corrupt(xqc->sc, dqtype, 0);
		return 0;
	}

	/* Compare what we observed against the actual dquots. */
	xchk_dqiter_init(&cursor, sc, dqtype);
	while ((error = xchk_dquot_iter(&cursor, &dq)) == 1) {
		error = xqcheck_compare_dquot(xqc, dqtype, dq);
		xfs_qm_dqput(dq);
		if (error)
			break;
	}
	if (error)
		return error;

	/* Walk all the observed dquots and compare to the incore ones. */
	return xqcheck_walk_observations(xqc, dqtype);
}

/* Tear down everything associated with a quotacheck. */
static void
xqcheck_teardown_scan(
	void			*priv)
{
	struct xqcheck		*xqc = priv;
	struct xfs_quotainfo	*qi = xqc->sc->mp->m_quotainfo;

	/* Discourage any hook functions that might be running. */
	xchk_iscan_abort(&xqc->iscan);

	/*
	 * As noted above, the apply hook is responsible for cleaning up the
	 * shadow dquot accounting data when a transaction completes.  The mod
	 * hook must be removed before the apply hook so that we don't
	 * mistakenly leave an active shadow account for the mod hook to get
	 * its hands on.  No hooks should be running after these functions
	 * return.
	 */
	xfs_dqtrx_hook_del(qi, &xqc->qhook);

	if (xqc->shadow_dquot_acct.key_len) {
		rhashtable_free_and_destroy(&xqc->shadow_dquot_acct,
				xqcheck_dqacct_free, NULL);
		xqc->shadow_dquot_acct.key_len = 0;
	}

	if (xqc->pcounts) {
		xfarray_destroy(xqc->pcounts);
		xqc->pcounts = NULL;
	}

	if (xqc->gcounts) {
		xfarray_destroy(xqc->gcounts);
		xqc->gcounts = NULL;
	}

	if (xqc->ucounts) {
		xfarray_destroy(xqc->ucounts);
		xqc->ucounts = NULL;
	}

	xchk_iscan_teardown(&xqc->iscan);
	mutex_destroy(&xqc->lock);
	xqc->sc = NULL;
}

/*
 * Scan all inodes in the entire filesystem to generate quota counter data.
 * If the scan is successful, the quota data will be left alive for a repair.
 * If any error occurs, we'll tear everything down.
 */
STATIC int
xqcheck_setup_scan(
	struct xfs_scrub	*sc,
	struct xqcheck		*xqc)
{
	char			*descr;
	struct xfs_quotainfo	*qi = sc->mp->m_quotainfo;
	unsigned long long	max_dquots = XFS_DQ_ID_MAX + 1ULL;
	int			error;

	ASSERT(xqc->sc == NULL);
	xqc->sc = sc;

	mutex_init(&xqc->lock);

	/* Retry iget every tenth of a second for up to 30 seconds. */
	xchk_iscan_start(sc, 30000, 100, &xqc->iscan);

	error = -ENOMEM;
	if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_USER)) {
		descr = xchk_xfile_descr(sc, "user dquot records");
		error = xfarray_create(descr, max_dquots,
				sizeof(struct xqcheck_dquot), &xqc->ucounts);
		kfree(descr);
		if (error)
			goto out_teardown;
	}

	if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_GROUP)) {
		descr = xchk_xfile_descr(sc, "group dquot records");
		error = xfarray_create(descr, max_dquots,
				sizeof(struct xqcheck_dquot), &xqc->gcounts);
		kfree(descr);
		if (error)
			goto out_teardown;
	}

	if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_PROJ)) {
		descr = xchk_xfile_descr(sc, "project dquot records");
		error = xfarray_create(descr, max_dquots,
				sizeof(struct xqcheck_dquot), &xqc->pcounts);
		kfree(descr);
		if (error)
			goto out_teardown;
	}

	/*
	 * Set up hash table to map transactions to our internal shadow dqtrx
	 * structures.
	 */
	error = rhashtable_init(&xqc->shadow_dquot_acct,
			&xqcheck_dqacct_hash_params);
	if (error)
		goto out_teardown;

	/*
	 * Hook into the quota code.  The hook only triggers for 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.
	 *
	 * The apply hook (which removes the shadow dquot accounting struct)
	 * must be installed before the mod hook so that we never fail to catch
	 * the end of a quota update sequence and leave stale shadow data.
	 */
	ASSERT(sc->flags & XCHK_FSGATES_QUOTA);
	xfs_dqtrx_hook_setup(&xqc->qhook, xqcheck_mod_live_ino_dqtrx,
			xqcheck_apply_live_dqtrx);

	error = xfs_dqtrx_hook_add(qi, &xqc->qhook);
	if (error)
		goto out_teardown;

	/* Use deferred cleanup to pass the quota count data to repair. */
	sc->buf_cleanup = xqcheck_teardown_scan;
	return 0;

out_teardown:
	xqcheck_teardown_scan(xqc);
	return error;
}

/* Scrub all counters for a given quota type. */
int
xchk_quotacheck(
	struct xfs_scrub	*sc)
{
	struct xqcheck		*xqc = sc->buf;
	int			error = 0;

	/* Check quota counters on the live filesystem. */
	error = xqcheck_setup_scan(sc, xqc);
	if (error)
		return error;

	/* Walk all inodes, picking up quota information. */
	error = xqcheck_collect_counts(xqc);
	if (!xchk_xref_process_error(sc, 0, 0, &error))
		return error;

	/* Fail fast if we're not playing with a full dataset. */
	if (xchk_iscan_aborted(&xqc->iscan))
		xchk_set_incomplete(sc);
	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE)
		return 0;

	/* Compare quota counters. */
	if (xqc->ucounts) {
		error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_USER);
		if (!xchk_xref_process_error(sc, 0, 0, &error))
			return error;
	}
	if (xqc->gcounts) {
		error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_GROUP);
		if (!xchk_xref_process_error(sc, 0, 0, &error))
			return error;
	}
	if (xqc->pcounts) {
		error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_PROJ);
		if (!xchk_xref_process_error(sc, 0, 0, &error))
			return error;
	}

	/* Check one last time for an incomplete dataset. */
	if (xchk_iscan_aborted(&xqc->iscan))
		xchk_set_incomplete(sc);

	return 0;
}
