linux/fs/xfs/xfs_trans_dquot.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2002 Silicon Graphics, Inc.
 * All Rights Reserved.
 */
#include "xfs.h"
#include "xfs_fs.h"
#include "xfs_shared.h"
#include "xfs_format.h"
#include "xfs_log_format.h"
#include "xfs_trans_resv.h"
#include "xfs_mount.h"
#include "xfs_inode.h"
#include "xfs_trans.h"
#include "xfs_trans_priv.h"
#include "xfs_quota.h"
#include "xfs_qm.h"
#include "xfs_trace.h"
#include "xfs_error.h"
#include "xfs_health.h"

STATIC void	xfs_trans_alloc_dqinfo(xfs_trans_t *);

/*
 * Add the locked dquot to the transaction.
 * The dquot must be locked, and it cannot be associated with any
 * transaction.
 */
void
xfs_trans_dqjoin(
	struct xfs_trans	*tp,
	struct xfs_dquot	*dqp)
{}

/*
 * This is called to mark the dquot as needing
 * to be logged when the transaction is committed.  The dquot must
 * already be associated with the given transaction.
 * Note that it marks the entire transaction as dirty. In the ordinary
 * case, this gets called via xfs_trans_commit, after the transaction
 * is already dirty. However, there's nothing stop this from getting
 * called directly, as done by xfs_qm_scall_setqlim. Hence, the TRANS_DIRTY
 * flag.
 */
void
xfs_trans_log_dquot(
	struct xfs_trans	*tp,
	struct xfs_dquot	*dqp)
{}

/*
 * Carry forward whatever is left of the quota blk reservation to
 * the spanky new transaction
 */
void
xfs_trans_dup_dqinfo(
	struct xfs_trans	*otp,
	struct xfs_trans	*ntp)
{}

#ifdef CONFIG_XFS_LIVE_HOOKS
/*
 * Use a static key here to reduce the overhead of quota live updates.  If the
 * compiler supports jump labels, the static branch will be replaced by a nop
 * sled when there are no hook users.  Online fsck is currently the only
 * caller, so this is a reasonable tradeoff.
 *
 * Note: Patching the kernel code requires taking the cpu hotplug lock.  Other
 * parts of the kernel allocate memory with that lock held, which means that
 * XFS callers cannot hold any locks that might be used by memory reclaim or
 * writeback when calling the static_branch_{inc,dec} functions.
 */
DEFINE_STATIC_XFS_HOOK_SWITCH(xfs_dqtrx_hooks_switch);

void
xfs_dqtrx_hook_disable(void)
{}

void
xfs_dqtrx_hook_enable(void)
{}

/* Schedule a transactional dquot update on behalf of an inode. */
void
xfs_trans_mod_ino_dquot(
	struct xfs_trans		*tp,
	struct xfs_inode		*ip,
	struct xfs_dquot		*dqp,
	unsigned int			field,
	int64_t				delta)
{}

/* Call the specified functions during a dquot counter update. */
int
xfs_dqtrx_hook_add(
	struct xfs_quotainfo	*qi,
	struct xfs_dqtrx_hook	*hook)
{}

/* Stop calling the specified function during a dquot counter update. */
void
xfs_dqtrx_hook_del(
	struct xfs_quotainfo	*qi,
	struct xfs_dqtrx_hook	*hook)
{}

/* Configure dquot update hook functions. */
void
xfs_dqtrx_hook_setup(
	struct xfs_dqtrx_hook	*hook,
	notifier_fn_t		mod_fn,
	notifier_fn_t		apply_fn)
{}
#endif /* CONFIG_XFS_LIVE_HOOKS */

/*
 * Wrap around mod_dquot to account for both user and group quotas.
 */
void
xfs_trans_mod_dquot_byino(
	xfs_trans_t	*tp,
	xfs_inode_t	*ip,
	uint		field,
	int64_t		delta)
{}

STATIC struct xfs_dqtrx *
xfs_trans_get_dqtrx(
	struct xfs_trans	*tp,
	struct xfs_dquot	*dqp)
{}

/*
 * Make the changes in the transaction structure.
 * The moral equivalent to xfs_trans_mod_sb().
 * We don't touch any fields in the dquot, so we don't care
 * if it's locked or not (most of the time it won't be).
 */
void
xfs_trans_mod_dquot(
	struct xfs_trans	*tp,
	struct xfs_dquot	*dqp,
	uint			field,
	int64_t			delta)
{}


/*
 * Given an array of dqtrx structures, lock all the dquots associated and join
 * them to the transaction, provided they have been modified.
 */
STATIC void
xfs_trans_dqlockedjoin(
	struct xfs_trans	*tp,
	struct xfs_dqtrx	*q)
{}

/* Apply dqtrx changes to the quota reservation counters. */
static inline void
xfs_apply_quota_reservation_deltas(
	struct xfs_dquot_res	*res,
	uint64_t		reserved,
	int64_t			res_used,
	int64_t			count_delta)
{}

#ifdef CONFIG_XFS_LIVE_HOOKS
/* Call downstream hooks now that it's time to apply dquot deltas. */
static inline void
xfs_trans_apply_dquot_deltas_hook(
	struct xfs_trans		*tp,
	struct xfs_dquot		*dqp)
{}
#else
#define xfs_trans_apply_dquot_deltas_hook
#endif /* CONFIG_XFS_LIVE_HOOKS */

/*
 * Called by xfs_trans_commit() and similar in spirit to
 * xfs_trans_apply_sb_deltas().
 * Go thru all the dquots belonging to this transaction and modify the
 * INCORE dquot to reflect the actual usages.
 * Unreserve just the reservations done by this transaction.
 * dquot is still left locked at exit.
 */
void
xfs_trans_apply_dquot_deltas(
	struct xfs_trans	*tp)
{}

#ifdef CONFIG_XFS_LIVE_HOOKS
/* Call downstream hooks now that it's time to cancel dquot deltas. */
static inline void
xfs_trans_unreserve_and_mod_dquots_hook(
	struct xfs_trans		*tp,
	struct xfs_dquot		*dqp)
{}
#else
#define xfs_trans_unreserve_and_mod_dquots_hook
#endif /* CONFIG_XFS_LIVE_HOOKS */

/*
 * Release the reservations, and adjust the dquots accordingly.
 * This is called only when the transaction is being aborted. If by
 * any chance we have done dquot modifications incore (ie. deltas) already,
 * we simply throw those away, since that's the expected behavior
 * when a transaction is curtailed without a commit.
 */
void
xfs_trans_unreserve_and_mod_dquots(
	struct xfs_trans	*tp)
{}

STATIC void
xfs_quota_warn(
	struct xfs_mount	*mp,
	struct xfs_dquot	*dqp,
	int			type)
{}

/*
 * Decide if we can make an additional reservation against a quota resource.
 * Returns an inode QUOTA_NL_ warning code and whether or not it's fatal.
 *
 * Note that we assume that the numeric difference between the inode and block
 * warning codes will always be 3 since it's userspace ABI now, and will never
 * decrease the quota reservation, so the *BELOW messages are irrelevant.
 */
static inline int
xfs_dqresv_check(
	struct xfs_dquot_res	*res,
	struct xfs_quota_limits	*qlim,
	int64_t			delta,
	bool			*fatal)
{}

/*
 * This reserves disk blocks and inodes against a dquot.
 * Flags indicate if the dquot is to be locked here and also
 * if the blk reservation is for RT or regular blocks.
 * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
 */
STATIC int
xfs_trans_dqresv(
	struct xfs_trans	*tp,
	struct xfs_mount	*mp,
	struct xfs_dquot	*dqp,
	int64_t			nblks,
	long			ninos,
	uint			flags)
{}


/*
 * Given dquot(s), make disk block and/or inode reservations against them.
 * The fact that this does the reservation against user, group and
 * project quotas is important, because this follows a all-or-nothing
 * approach.
 *
 * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
 *	   XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT.  Used by pquota.
 *	   XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
 *	   XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
 * dquots are unlocked on return, if they were not locked by caller.
 */
int
xfs_trans_reserve_quota_bydquots(
	struct xfs_trans	*tp,
	struct xfs_mount	*mp,
	struct xfs_dquot	*udqp,
	struct xfs_dquot	*gdqp,
	struct xfs_dquot	*pdqp,
	int64_t			nblks,
	long			ninos,
	uint			flags)
{}


/*
 * Lock the dquot and change the reservation if we can.
 * This doesn't change the actual usage, just the reservation.
 * The inode sent in is locked.
 */
int
xfs_trans_reserve_quota_nblks(
	struct xfs_trans	*tp,
	struct xfs_inode	*ip,
	int64_t			dblocks,
	int64_t			rblocks,
	bool			force)
{}

/* Change the quota reservations for an inode creation activity. */
int
xfs_trans_reserve_quota_icreate(
	struct xfs_trans	*tp,
	struct xfs_dquot	*udqp,
	struct xfs_dquot	*gdqp,
	struct xfs_dquot	*pdqp,
	int64_t			dblocks)
{}

STATIC void
xfs_trans_alloc_dqinfo(
	xfs_trans_t	*tp)
{}

void
xfs_trans_free_dqinfo(
	xfs_trans_t	*tp)
{}