^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2000-2002 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "xfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "xfs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "xfs_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "xfs_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "xfs_trans_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "xfs_quota.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "xfs_qm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "xfs_trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) STATIC void xfs_trans_alloc_dqinfo(xfs_trans_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Add the locked dquot to the transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * The dquot must be locked, and it cannot be associated with any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) xfs_trans_dqjoin(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct xfs_dquot *dqp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ASSERT(XFS_DQ_IS_LOCKED(dqp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ASSERT(dqp->q_logitem.qli_dquot == dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Get a log_item_desc to point at the new item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) xfs_trans_add_item(tp, &dqp->q_logitem.qli_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * This is called to mark the dquot as needing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * to be logged when the transaction is committed. The dquot must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * already be associated with the given transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * Note that it marks the entire transaction as dirty. In the ordinary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * case, this gets called via xfs_trans_commit, after the transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * is already dirty. However, there's nothing stop this from getting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * called directly, as done by xfs_qm_scall_setqlim. Hence, the TRANS_DIRTY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) xfs_trans_log_dquot(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct xfs_dquot *dqp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ASSERT(XFS_DQ_IS_LOCKED(dqp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Upgrade the dquot to bigtime format if possible. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (dqp->q_id != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) xfs_sb_version_hasbigtime(&tp->t_mountp->m_sb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) !(dqp->q_type & XFS_DQTYPE_BIGTIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) dqp->q_type |= XFS_DQTYPE_BIGTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) tp->t_flags |= XFS_TRANS_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) set_bit(XFS_LI_DIRTY, &dqp->q_logitem.qli_item.li_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * Carry forward whatever is left of the quota blk reservation to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * the spanky new transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) xfs_trans_dup_dqinfo(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct xfs_trans *otp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct xfs_trans *ntp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct xfs_dqtrx *oq, *nq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct xfs_dqtrx *oqa, *nqa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) uint64_t blk_res_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (!otp->t_dqinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) xfs_trans_alloc_dqinfo(ntp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * Because the quota blk reservation is carried forward,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * it is also necessary to carry forward the DQ_DIRTY flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (otp->t_flags & XFS_TRANS_DQ_DIRTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ntp->t_flags |= XFS_TRANS_DQ_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) oqa = otp->t_dqinfo->dqs[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) nqa = ntp->t_dqinfo->dqs[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) blk_res_used = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (oqa[i].qt_dquot == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) oq = &oqa[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) nq = &nqa[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (oq->qt_blk_res && oq->qt_bcount_delta > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) blk_res_used = oq->qt_bcount_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) nq->qt_dquot = oq->qt_dquot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) nq->qt_bcount_delta = nq->qt_icount_delta = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) nq->qt_rtbcount_delta = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * Transfer whatever is left of the reservations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) nq->qt_blk_res = oq->qt_blk_res - blk_res_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) oq->qt_blk_res = blk_res_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) nq->qt_rtblk_res = oq->qt_rtblk_res -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) oq->qt_rtblk_res_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) oq->qt_rtblk_res = oq->qt_rtblk_res_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) nq->qt_ino_res = oq->qt_ino_res - oq->qt_ino_res_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) oq->qt_ino_res = oq->qt_ino_res_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Wrap around mod_dquot to account for both user and group quotas.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) xfs_trans_mod_dquot_byino(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) xfs_trans_t *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) xfs_inode_t *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) uint field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int64_t delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) xfs_mount_t *mp = tp->t_mountp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!XFS_IS_QUOTA_RUNNING(mp) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) !XFS_IS_QUOTA_ON(mp) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) xfs_is_quota_inode(&mp->m_sb, ip->i_ino))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (tp->t_dqinfo == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) xfs_trans_alloc_dqinfo(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (XFS_IS_PQUOTA_ON(mp) && ip->i_pdquot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) (void) xfs_trans_mod_dquot(tp, ip->i_pdquot, field, delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) STATIC struct xfs_dqtrx *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) xfs_trans_get_dqtrx(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct xfs_dquot *dqp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct xfs_dqtrx *qa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) switch (xfs_dquot_type(dqp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case XFS_DQTYPE_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_USR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case XFS_DQTYPE_GROUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_GRP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case XFS_DQTYPE_PROJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_PRJ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (qa[i].qt_dquot == NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) qa[i].qt_dquot == dqp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return &qa[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * Make the changes in the transaction structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * The moral equivalent to xfs_trans_mod_sb().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * We don't touch any fields in the dquot, so we don't care
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * if it's locked or not (most of the time it won't be).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) xfs_trans_mod_dquot(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct xfs_dquot *dqp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) uint field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int64_t delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct xfs_dqtrx *qtrx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ASSERT(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) qtrx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (tp->t_dqinfo == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) xfs_trans_alloc_dqinfo(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Find either the first free slot or the slot that belongs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * to this dquot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) qtrx = xfs_trans_get_dqtrx(tp, dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ASSERT(qtrx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (qtrx->qt_dquot == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) qtrx->qt_dquot = dqp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (delta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) trace_xfs_trans_mod_dquot_before(qtrx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) trace_xfs_trans_mod_dquot(tp, dqp, field, delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) switch (field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* regular disk blk reservation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case XFS_TRANS_DQ_RES_BLKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) qtrx->qt_blk_res += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* inode reservation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) case XFS_TRANS_DQ_RES_INOS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) qtrx->qt_ino_res += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* disk blocks used. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case XFS_TRANS_DQ_BCOUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) qtrx->qt_bcount_delta += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) case XFS_TRANS_DQ_DELBCOUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) qtrx->qt_delbcnt_delta += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* Inode Count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case XFS_TRANS_DQ_ICOUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (qtrx->qt_ino_res && delta > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) qtrx->qt_ino_res_used += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) qtrx->qt_icount_delta += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* rtblk reservation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case XFS_TRANS_DQ_RES_RTBLKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) qtrx->qt_rtblk_res += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* rtblk count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) case XFS_TRANS_DQ_RTBCOUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (qtrx->qt_rtblk_res && delta > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) qtrx->qt_rtblk_res_used += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ASSERT(qtrx->qt_rtblk_res >= qtrx->qt_rtblk_res_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) qtrx->qt_rtbcount_delta += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) case XFS_TRANS_DQ_DELRTBCOUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) qtrx->qt_delrtb_delta += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) trace_xfs_trans_mod_dquot_after(qtrx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) tp->t_flags |= XFS_TRANS_DQ_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * Given an array of dqtrx structures, lock all the dquots associated and join
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * them to the transaction, provided they have been modified. We know that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * highest number of dquots of one type - usr, grp and prj - involved in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * transaction is 3 so we don't need to make this very generic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) xfs_trans_dqlockedjoin(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct xfs_dqtrx *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ASSERT(q[0].qt_dquot != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (q[1].qt_dquot == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) xfs_dqlock(q[0].qt_dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) xfs_trans_dqjoin(tp, q[0].qt_dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ASSERT(XFS_QM_TRANS_MAXDQS == 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) xfs_dqlock2(q[0].qt_dquot, q[1].qt_dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) xfs_trans_dqjoin(tp, q[0].qt_dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) xfs_trans_dqjoin(tp, q[1].qt_dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* Apply dqtrx changes to the quota reservation counters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) xfs_apply_quota_reservation_deltas(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct xfs_dquot_res *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) uint64_t reserved,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int64_t res_used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) int64_t count_delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (reserved != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * Subtle math here: If reserved > res_used (the normal case),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * we're simply subtracting the unused transaction quota
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * reservation from the dquot reservation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * If, however, res_used > reserved, then we have allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * more quota blocks than were reserved for the transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * We must add that excess to the dquot reservation since it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * tracks (usage + resv) and by definition we didn't reserve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * that excess.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) res->reserved -= abs(reserved - res_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) } else if (count_delta != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * These blks were never reserved, either inside a transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * or outside one (in a delayed allocation). Also, this isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * always a negative number since we sometimes deliberately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * skip quota reservations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) res->reserved += count_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * Called by xfs_trans_commit() and similar in spirit to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * xfs_trans_apply_sb_deltas().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * Go thru all the dquots belonging to this transaction and modify the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * INCORE dquot to reflect the actual usages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * Unreserve just the reservations done by this transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * dquot is still left locked at exit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) xfs_trans_apply_dquot_deltas(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct xfs_trans *tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct xfs_dquot *dqp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct xfs_dqtrx *qtrx, *qa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int64_t totalbdelta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int64_t totalrtbdelta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (!(tp->t_flags & XFS_TRANS_DQ_DIRTY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ASSERT(tp->t_dqinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) qa = tp->t_dqinfo->dqs[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (qa[0].qt_dquot == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * Lock all of the dquots and join them to the transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) xfs_trans_dqlockedjoin(tp, qa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) uint64_t blk_res_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) qtrx = &qa[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * The array of dquots is filled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * sequentially, not sparsely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if ((dqp = qtrx->qt_dquot) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ASSERT(XFS_DQ_IS_LOCKED(dqp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * adjust the actual number of blocks used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * The issue here is - sometimes we don't make a blkquota
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * reservation intentionally to be fair to users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * (when the amount is small). On the other hand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * delayed allocs do make reservations, but that's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * outside of a transaction, so we have no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * idea how much was really reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * So, here we've accumulated delayed allocation blks and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * non-delay blks. The assumption is that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * delayed ones are always reserved (outside of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * transaction), and the others may or may not have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * quota reservations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) totalbdelta = qtrx->qt_bcount_delta +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) qtrx->qt_delbcnt_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) totalrtbdelta = qtrx->qt_rtbcount_delta +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) qtrx->qt_delrtb_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (totalbdelta != 0 || totalrtbdelta != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) qtrx->qt_icount_delta != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) trace_xfs_trans_apply_dquot_deltas_before(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) trace_xfs_trans_apply_dquot_deltas(qtrx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (totalbdelta < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ASSERT(dqp->q_blk.count >= -totalbdelta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (totalrtbdelta < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ASSERT(dqp->q_rtb.count >= -totalrtbdelta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (qtrx->qt_icount_delta < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ASSERT(dqp->q_ino.count >= -qtrx->qt_icount_delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (totalbdelta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) dqp->q_blk.count += totalbdelta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (qtrx->qt_icount_delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) dqp->q_ino.count += qtrx->qt_icount_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (totalrtbdelta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dqp->q_rtb.count += totalrtbdelta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (totalbdelta != 0 || totalrtbdelta != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) qtrx->qt_icount_delta != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) trace_xfs_trans_apply_dquot_deltas_after(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * Get any default limits in use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * Start/reset the timer(s) if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (dqp->q_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) xfs_qm_adjust_dqlimits(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) xfs_qm_adjust_dqtimers(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dqp->q_flags |= XFS_DQFLAG_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * add this to the list of items to get logged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) xfs_trans_log_dquot(tp, dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * Take off what's left of the original reservation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * In case of delayed allocations, there's no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * reservation that a transaction structure knows of.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) blk_res_used = max_t(int64_t, 0, qtrx->qt_bcount_delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) xfs_apply_quota_reservation_deltas(&dqp->q_blk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) qtrx->qt_blk_res, blk_res_used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) qtrx->qt_bcount_delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * Adjust the RT reservation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) xfs_apply_quota_reservation_deltas(&dqp->q_rtb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) qtrx->qt_rtblk_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) qtrx->qt_rtblk_res_used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) qtrx->qt_rtbcount_delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * Adjust the inode reservation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) xfs_apply_quota_reservation_deltas(&dqp->q_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) qtrx->qt_ino_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) qtrx->qt_ino_res_used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) qtrx->qt_icount_delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * Release the reservations, and adjust the dquots accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * This is called only when the transaction is being aborted. If by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * any chance we have done dquot modifications incore (ie. deltas) already,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * we simply throw those away, since that's the expected behavior
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * when a transaction is curtailed without a commit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) xfs_trans_unreserve_and_mod_dquots(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct xfs_trans *tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct xfs_dquot *dqp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct xfs_dqtrx *qtrx, *qa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) bool locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (!tp->t_dqinfo || !(tp->t_flags & XFS_TRANS_DQ_DIRTY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) qa = tp->t_dqinfo->dqs[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) qtrx = &qa[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * We assume that the array of dquots is filled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * sequentially, not sparsely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if ((dqp = qtrx->qt_dquot) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * Unreserve the original reservation. We don't care
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * about the number of blocks used field, or deltas.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * Also we don't bother to zero the fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) locked = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (qtrx->qt_blk_res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) xfs_dqlock(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) locked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) dqp->q_blk.reserved -=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) (xfs_qcnt_t)qtrx->qt_blk_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (qtrx->qt_ino_res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (!locked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) xfs_dqlock(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) locked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) dqp->q_ino.reserved -=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) (xfs_qcnt_t)qtrx->qt_ino_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (qtrx->qt_rtblk_res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (!locked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) xfs_dqlock(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) locked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) dqp->q_rtb.reserved -=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) (xfs_qcnt_t)qtrx->qt_rtblk_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) xfs_dqunlock(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) xfs_quota_warn(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct xfs_dquot *dqp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) enum quota_type qtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) switch (xfs_dquot_type(dqp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) case XFS_DQTYPE_PROJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) qtype = PRJQUOTA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) case XFS_DQTYPE_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) qtype = USRQUOTA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) case XFS_DQTYPE_GROUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) qtype = GRPQUOTA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) quota_send_warning(make_kqid(&init_user_ns, qtype, dqp->q_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) mp->m_super->s_dev, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * Decide if we can make an additional reservation against a quota resource.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * Returns an inode QUOTA_NL_ warning code and whether or not it's fatal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * Note that we assume that the numeric difference between the inode and block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * warning codes will always be 3 since it's userspace ABI now, and will never
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * decrease the quota reservation, so the *BELOW messages are irrelevant.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) xfs_dqresv_check(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct xfs_dquot_res *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct xfs_quota_limits *qlim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int64_t delta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) bool *fatal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) xfs_qcnt_t hardlimit = res->hardlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) xfs_qcnt_t softlimit = res->softlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) xfs_qcnt_t total_count = res->reserved + delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) BUILD_BUG_ON(QUOTA_NL_BHARDWARN != QUOTA_NL_IHARDWARN + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) BUILD_BUG_ON(QUOTA_NL_BSOFTLONGWARN != QUOTA_NL_ISOFTLONGWARN + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) BUILD_BUG_ON(QUOTA_NL_BSOFTWARN != QUOTA_NL_ISOFTWARN + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) *fatal = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (delta <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return QUOTA_NL_NOWARN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (!hardlimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) hardlimit = qlim->hard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (!softlimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) softlimit = qlim->soft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (hardlimit && total_count > hardlimit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) *fatal = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return QUOTA_NL_IHARDWARN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (softlimit && total_count > softlimit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) time64_t now = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if ((res->timer != 0 && now > res->timer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) (res->warnings != 0 && res->warnings >= qlim->warn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) *fatal = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return QUOTA_NL_ISOFTLONGWARN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) res->warnings++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return QUOTA_NL_ISOFTWARN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return QUOTA_NL_NOWARN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * This reserves disk blocks and inodes against a dquot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * Flags indicate if the dquot is to be locked here and also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * if the blk reservation is for RT or regular blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) xfs_trans_dqresv(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct xfs_dquot *dqp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) int64_t nblks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) long ninos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) uint flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct xfs_quotainfo *q = mp->m_quotainfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct xfs_def_quota *defq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct xfs_dquot_res *blkres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct xfs_quota_limits *qlim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) xfs_dqlock(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (flags & XFS_TRANS_DQ_RES_BLKS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) blkres = &dqp->q_blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) qlim = &defq->blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) blkres = &dqp->q_rtb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) qlim = &defq->rtb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) xfs_dquot_is_enforced(dqp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) int quota_nl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) bool fatal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * dquot is locked already. See if we'd go over the hardlimit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * or exceed the timelimit if we'd reserve resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) quota_nl = xfs_dqresv_check(blkres, qlim, nblks, &fatal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (quota_nl != QUOTA_NL_NOWARN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * Quota block warning codes are 3 more than the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * codes, which we check above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) xfs_quota_warn(mp, dqp, quota_nl + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (fatal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) goto error_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->ino, ninos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) &fatal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (quota_nl != QUOTA_NL_NOWARN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) xfs_quota_warn(mp, dqp, quota_nl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (fatal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) goto error_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * Change the reservation, but not the actual usage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * Note that q_blk.reserved = q_blk.count + resv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) blkres->reserved += (xfs_qcnt_t)nblks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * note the reservation amt in the trans struct too,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * so that the transaction knows how much was reserved by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * it against this particular dquot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * We don't do this when we are reserving for a delayed allocation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * because we don't have the luxury of a transaction envelope then.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (tp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ASSERT(tp->t_dqinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (nblks != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) xfs_trans_mod_dquot(tp, dqp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) flags & XFS_QMOPT_RESBLK_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) nblks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (ninos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) xfs_trans_mod_dquot(tp, dqp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) XFS_TRANS_DQ_RES_INOS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ninos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) xfs_dqunlock(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) error_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) xfs_dqunlock(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (xfs_dquot_type(dqp) == XFS_DQTYPE_PROJ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return -EDQUOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * Given dquot(s), make disk block and/or inode reservations against them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * The fact that this does the reservation against user, group and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * project quotas is important, because this follows a all-or-nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * approach.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * dquots are unlocked on return, if they were not locked by caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) xfs_trans_reserve_quota_bydquots(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct xfs_dquot *udqp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) struct xfs_dquot *gdqp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct xfs_dquot *pdqp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) int64_t nblks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) long ninos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) uint flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (tp && tp->t_dqinfo == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) xfs_trans_alloc_dqinfo(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (udqp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (gdqp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) goto unwind_usr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (pdqp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) error = xfs_trans_dqresv(tp, mp, pdqp, nblks, ninos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) goto unwind_grp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * Didn't change anything critical, so, no need to log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) unwind_grp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) flags |= XFS_QMOPT_FORCE_RES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (gdqp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) xfs_trans_dqresv(tp, mp, gdqp, -nblks, -ninos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) unwind_usr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) flags |= XFS_QMOPT_FORCE_RES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (udqp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) xfs_trans_dqresv(tp, mp, udqp, -nblks, -ninos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * Lock the dquot and change the reservation if we can.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * This doesn't change the actual usage, just the reservation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * The inode sent in is locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) xfs_trans_reserve_quota_nblks(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) int64_t nblks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) long ninos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) uint flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ASSERT(!xfs_is_quota_inode(&mp->m_sb, ip->i_ino));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) ASSERT((flags & ~(XFS_QMOPT_FORCE_RES)) == XFS_TRANS_DQ_RES_RTBLKS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) (flags & ~(XFS_QMOPT_FORCE_RES)) == XFS_TRANS_DQ_RES_BLKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * Reserve nblks against these dquots, with trans as the mediator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return xfs_trans_reserve_quota_bydquots(tp, mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) ip->i_udquot, ip->i_gdquot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) ip->i_pdquot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) nblks, ninos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * This routine is called to allocate a quotaoff log item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct xfs_qoff_logitem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) xfs_trans_get_qoff_item(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) struct xfs_qoff_logitem *startqoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) uint flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) struct xfs_qoff_logitem *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) ASSERT(tp != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) q = xfs_qm_qoff_logitem_init(tp->t_mountp, startqoff, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ASSERT(q != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * Get a log_item_desc to point at the new item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) xfs_trans_add_item(tp, &q->qql_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * This is called to mark the quotaoff logitem as needing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * to be logged when the transaction is committed. The logitem must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * already be associated with the given transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) xfs_trans_log_quotaoff_item(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct xfs_qoff_logitem *qlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) tp->t_flags |= XFS_TRANS_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) set_bit(XFS_LI_DIRTY, &qlp->qql_item.li_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) xfs_trans_alloc_dqinfo(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) xfs_trans_t *tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) tp->t_dqinfo = kmem_cache_zalloc(xfs_qm_dqtrxzone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) GFP_KERNEL | __GFP_NOFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) xfs_trans_free_dqinfo(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) xfs_trans_t *tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (!tp->t_dqinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) kmem_cache_free(xfs_qm_dqtrxzone, tp->t_dqinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) tp->t_dqinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }