^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-2005 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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "xfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "xfs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "xfs_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "xfs_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_sb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "xfs_quota.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "xfs_qm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "xfs_icache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) xfs_qm_log_quotaoff(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct xfs_qoff_logitem **qoffstartp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) uint flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct xfs_trans *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct xfs_qoff_logitem *qoffi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_quotaoff, 0, 0, 0, &tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) xfs_trans_log_quotaoff_item(tp, qoffi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) spin_lock(&mp->m_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) spin_unlock(&mp->m_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) xfs_log_sb(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * We have to make sure that the transaction is secure on disk before we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * return and actually stop quota accounting. So, make it synchronous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * We don't care about quotoff's performance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) xfs_trans_set_sync(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) error = xfs_trans_commit(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *qoffstartp = qoffi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) xfs_qm_log_quotaoff_end(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct xfs_qoff_logitem **startqoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) uint flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct xfs_trans *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct xfs_qoff_logitem *qoffi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_equotaoff, 0, 0, 0, &tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) qoffi = xfs_trans_get_qoff_item(tp, *startqoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) flags & XFS_ALL_QUOTA_ACCT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) xfs_trans_log_quotaoff_item(tp, qoffi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *startqoff = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * We have to make sure that the transaction is secure on disk before we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * return and actually stop quota accounting. So, make it synchronous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * We don't care about quotoff's performance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) xfs_trans_set_sync(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return xfs_trans_commit(tp);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * Turn off quota accounting and/or enforcement for all udquots and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * gdquots. Called only at unmount time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * This assumes that there are no dquots of this file system cached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * incore, and modifies the ondisk dquot directly. Therefore, for example,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * it is an error to call this twice, without purging the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) xfs_qm_scall_quotaoff(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) xfs_mount_t *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) uint flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct xfs_quotainfo *q = mp->m_quotainfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) uint dqtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) uint inactivate_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct xfs_qoff_logitem *qoffstart = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * No file system can have quotas enabled on disk but not in core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * Note that quota utilities (like quotaoff) _expect_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * errno == -EEXIST here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if ((mp->m_qflags & flags) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * We don't want to deal with two quotaoffs messing up each other,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * so we're going to serialize it. quotaoff isn't exactly a performance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * critical thing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * If quotaoff, then we must be dealing with the root filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ASSERT(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mutex_lock(&q->qi_quotaofflock);
^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) * If we're just turning off quota enforcement, change mp and go.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if ((flags & XFS_ALL_QUOTA_ACCT) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) mp->m_qflags &= ~(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) spin_lock(&mp->m_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) mp->m_sb.sb_qflags = mp->m_qflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) spin_unlock(&mp->m_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) mutex_unlock(&q->qi_quotaofflock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* XXX what to do if error ? Revert back to old vals incore ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return xfs_sync_sb(mp, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) dqtype = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) inactivate_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * If accounting is off, we must turn enforcement off, clear the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * quota 'CHKD' certificate to make it known that we have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * do a quotacheck the next time this quota is turned on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (flags & XFS_UQUOTA_ACCT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) dqtype |= XFS_QMOPT_UQUOTA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) flags |= (XFS_UQUOTA_CHKD | XFS_UQUOTA_ENFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) inactivate_flags |= XFS_UQUOTA_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (flags & XFS_GQUOTA_ACCT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) dqtype |= XFS_QMOPT_GQUOTA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) inactivate_flags |= XFS_GQUOTA_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (flags & XFS_PQUOTA_ACCT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) dqtype |= XFS_QMOPT_PQUOTA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) flags |= (XFS_PQUOTA_CHKD | XFS_PQUOTA_ENFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) inactivate_flags |= XFS_PQUOTA_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * Nothing to do? Don't complain. This happens when we're just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * turning off quota enforcement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if ((mp->m_qflags & flags) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * Write the LI_QUOTAOFF log record, and do SB changes atomically,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * and synchronously. If we fail to write, we should abort the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * operation as it cannot be recovered safely if we crash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) error = xfs_qm_log_quotaoff(mp, &qoffstart, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * Next we clear the XFS_MOUNT_*DQ_ACTIVE bit(s) in the mount struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * to take care of the race between dqget and quotaoff. We don't take
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * any special locks to reset these bits. All processes need to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * these bits *after* taking inode lock(s) to see if the particular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * quota type is in the process of being turned off. If *ACTIVE, it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * guaranteed that all dquot structures and all quotainode ptrs will all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * stay valid as long as that inode is kept locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * There is no turning back after this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) mp->m_qflags &= ~inactivate_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Give back all the dquot reference(s) held by inodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * Here we go thru every single incore inode in this file system, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * do a dqrele on the i_udquot/i_gdquot that it may have.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * Essentially, as long as somebody has an inode locked, this guarantees
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * that quotas will not be turned off. This is handy because in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * transaction once we lock the inode(s) and check for quotaon, we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * depend on the quota inodes (and other things) being valid as long as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * we keep the lock(s).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) xfs_qm_dqrele_all_inodes(mp, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Next we make the changes in the quota flag in the mount struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * This isn't protected by a particular lock directly, because we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * don't want to take a mrlock every time we depend on quotas being on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) mp->m_qflags &= ~flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * Go through all the dquots of this file system and purge them,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * according to what was turned off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) xfs_qm_dqpurge_all(mp, dqtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * Transactions that had started before ACTIVE state bit was cleared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * could have logged many dquots, so they'd have higher LSNs than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * the first QUOTAOFF log record does. If we happen to crash when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * the tail of the log has gone past the QUOTAOFF record, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * before the last dquot modification, those dquots __will__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * recover, and that's not good.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * So, we have QUOTAOFF start and end logitems; the start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * logitem won't get overwritten until the end logitem appears...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) error = xfs_qm_log_quotaoff_end(mp, &qoffstart, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* We're screwed now. Shutdown is the only option. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * If all quotas are completely turned off, close shop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (mp->m_qflags == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) mutex_unlock(&q->qi_quotaofflock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) xfs_qm_destroy_quotainfo(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * Release our quotainode references if we don't need them anymore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if ((dqtype & XFS_QMOPT_UQUOTA) && q->qi_uquotaip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) xfs_irele(q->qi_uquotaip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) q->qi_uquotaip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if ((dqtype & XFS_QMOPT_GQUOTA) && q->qi_gquotaip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) xfs_irele(q->qi_gquotaip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) q->qi_gquotaip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if ((dqtype & XFS_QMOPT_PQUOTA) && q->qi_pquotaip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) xfs_irele(q->qi_pquotaip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) q->qi_pquotaip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (error && qoffstart)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) xfs_qm_qoff_logitem_relse(qoffstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) mutex_unlock(&q->qi_quotaofflock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) xfs_qm_scall_trunc_qfile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) xfs_ino_t ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct xfs_inode *ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct xfs_trans *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (ino == NULLFSINO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) error = xfs_iget(mp, NULL, ino, 0, 0, &ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) xfs_ilock(ip, XFS_IOLOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) xfs_iunlock(ip, XFS_IOLOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) xfs_ilock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) xfs_trans_ijoin(tp, ip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ip->i_d.di_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) xfs_trans_cancel(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ASSERT(ip->i_df.if_nextents == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) error = xfs_trans_commit(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) xfs_irele(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) xfs_qm_scall_trunc_qfiles(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) xfs_mount_t *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) uint flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) (flags & ~XFS_QMOPT_QUOTALL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) xfs_debug(mp, "%s: flags=%x m_qflags=%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) __func__, flags, mp->m_qflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (flags & XFS_QMOPT_UQUOTA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (flags & XFS_QMOPT_GQUOTA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (flags & XFS_QMOPT_PQUOTA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * Switch on (a given) quota enforcement for a filesystem. This takes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * effect immediately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * (Switching on quota accounting must be done at mount time.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) xfs_qm_scall_quotaon(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) xfs_mount_t *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) uint flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) uint qf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * Switching on quota accounting must be done at mount time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * only consider quota enforcement stuff here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) flags &= XFS_ALL_QUOTA_ENFD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (flags == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) xfs_debug(mp, "%s: zero flags, m_qflags=%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) __func__, mp->m_qflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * Can't enforce without accounting. We check the superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * qflags here instead of m_qflags because rootfs can have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * quota acct on ondisk without m_qflags' knowing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) (flags & XFS_UQUOTA_ENFD)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) (flags & XFS_GQUOTA_ENFD)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) (flags & XFS_PQUOTA_ENFD))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) xfs_debug(mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) "%s: Can't enforce without acct, flags=%x sbflags=%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) __func__, flags, mp->m_sb.sb_qflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * If everything's up to-date incore, then don't waste time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if ((mp->m_qflags & flags) == flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * Change sb_qflags on disk but not incore mp->qflags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * if this is the root filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) spin_lock(&mp->m_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) qf = mp->m_sb.sb_qflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) mp->m_sb.sb_qflags = qf | flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) spin_unlock(&mp->m_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * There's nothing to change if it's the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if ((qf & flags) == flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) error = xfs_sync_sb(mp, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * If we aren't trying to switch on quota enforcement, we are done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) (mp->m_qflags & XFS_UQUOTA_ACCT)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) (mp->m_qflags & XFS_PQUOTA_ACCT)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) (mp->m_qflags & XFS_GQUOTA_ACCT)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (! XFS_IS_QUOTA_RUNNING(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * Switch on quota enforcement in core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) mutex_lock(&mp->m_quotainfo->qi_quotaofflock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) mutex_unlock(&mp->m_quotainfo->qi_quotaofflock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) #define XFS_QC_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * Adjust limits of this quota, and the defaults if passed in. Returns true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * if the new limits made sense and were applied, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) xfs_setqlim_limits(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct xfs_dquot_res *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct xfs_quota_limits *qlim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) xfs_qcnt_t hard,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) xfs_qcnt_t soft,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) const char *tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* The hard limit can't be less than the soft limit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (hard != 0 && hard < soft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) xfs_debug(mp, "%shard %lld < %ssoft %lld", tag, hard, tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) soft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) res->hardlimit = hard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) res->softlimit = soft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (qlim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) qlim->hard = hard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) qlim->soft = soft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) xfs_setqlim_warns(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct xfs_dquot_res *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct xfs_quota_limits *qlim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int warns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) res->warnings = warns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (qlim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) qlim->warn = warns;
^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) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) xfs_setqlim_timer(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct xfs_dquot_res *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct xfs_quota_limits *qlim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) s64 timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (qlim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* Set the length of the default grace period. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) res->timer = xfs_dquot_set_grace_period(timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) qlim->time = res->timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* Set the grace period expiration on a quota. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) res->timer = xfs_dquot_set_timeout(mp, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * Adjust quota limits, and start/stop timers accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) xfs_qm_scall_setqlim(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) xfs_dqid_t id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) xfs_dqtype_t type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct qc_dqblk *newlim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct xfs_quotainfo *q = mp->m_quotainfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct xfs_dquot *dqp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct xfs_trans *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct xfs_def_quota *defq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct xfs_dquot_res *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct xfs_quota_limits *qlim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) xfs_qcnt_t hard, soft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (newlim->d_fieldmask & ~XFS_QC_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if ((newlim->d_fieldmask & XFS_QC_MASK) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * We don't want to race with a quotaoff so take the quotaoff lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * We don't hold an inode lock, so there's nothing else to stop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * a quotaoff from happening.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) mutex_lock(&q->qi_quotaofflock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * Get the dquot (locked) before we start, as we need to do a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * transaction to allocate it if it doesn't exist. Once we have the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * dquot, unlock it so we can start the next transaction safely. We hold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * a reference to the dquot, so it's safe to do this unlock/lock without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * it being reclaimed in the mean time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) error = xfs_qm_dqget(mp, id, type, true, &dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ASSERT(error != -ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) xfs_dqunlock(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_setqlim, 0, 0, 0, &tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) goto out_rele;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) xfs_dqlock(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) xfs_trans_dqjoin(tp, dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * Update quota limits, warnings, and timers, and the defaults
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * if we're touching id == 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * Make sure that hardlimits are >= soft limits before changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * Update warnings counter(s) if requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * Timelimits for the super user set the relative time the other users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * can be over quota for this file system. If it is zero a default is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * used. Ditto for the default soft and hard limit values (already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * done, above), and for warnings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * For other IDs, userspace can bump out the grace period if over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * the soft limit.
^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) /* Blocks on the data device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) hard = (newlim->d_fieldmask & QC_SPC_HARD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) dqp->q_blk.hardlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) soft = (newlim->d_fieldmask & QC_SPC_SOFT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) dqp->q_blk.softlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) res = &dqp->q_blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) qlim = id == 0 ? &defq->blk : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (xfs_setqlim_limits(mp, res, qlim, hard, soft, "blk"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) xfs_dquot_set_prealloc_limits(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (newlim->d_fieldmask & QC_SPC_WARNS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) xfs_setqlim_warns(res, qlim, newlim->d_spc_warns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (newlim->d_fieldmask & QC_SPC_TIMER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) xfs_setqlim_timer(mp, res, qlim, newlim->d_spc_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* Blocks on the realtime device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) dqp->q_rtb.hardlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) dqp->q_rtb.softlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) res = &dqp->q_rtb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) qlim = id == 0 ? &defq->rtb : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) xfs_setqlim_limits(mp, res, qlim, hard, soft, "rtb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) xfs_setqlim_warns(res, qlim, newlim->d_rt_spc_warns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) xfs_setqlim_timer(mp, res, qlim, newlim->d_rt_spc_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* Inodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) hard = (newlim->d_fieldmask & QC_INO_HARD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) (xfs_qcnt_t) newlim->d_ino_hardlimit :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) dqp->q_ino.hardlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) soft = (newlim->d_fieldmask & QC_INO_SOFT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) (xfs_qcnt_t) newlim->d_ino_softlimit :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) dqp->q_ino.softlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) res = &dqp->q_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) qlim = id == 0 ? &defq->ino : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) xfs_setqlim_limits(mp, res, qlim, hard, soft, "ino");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (newlim->d_fieldmask & QC_INO_WARNS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) xfs_setqlim_warns(res, qlim, newlim->d_ino_warns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (newlim->d_fieldmask & QC_INO_TIMER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) xfs_setqlim_timer(mp, res, qlim, newlim->d_ino_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (id != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * If the user is now over quota, start the timelimit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * The user will not be 'warned'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * Note that we keep the timers ticking, whether enforcement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * is on or off. We don't really want to bother with iterating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * over all ondisk dquots and turning the timers on/off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) xfs_qm_adjust_dqtimers(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) dqp->q_flags |= XFS_DQFLAG_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) xfs_trans_log_dquot(tp, dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) error = xfs_trans_commit(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) out_rele:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) xfs_qm_dqrele(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) mutex_unlock(&q->qi_quotaofflock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /* Fill out the quota context. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) xfs_qm_scall_getquota_fill_qc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) xfs_dqtype_t type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) const struct xfs_dquot *dqp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct qc_dqblk *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) memset(dst, 0, sizeof(*dst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) dst->d_ino_hardlimit = dqp->q_ino.hardlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) dst->d_ino_softlimit = dqp->q_ino.softlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) dst->d_ino_count = dqp->q_ino.reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) dst->d_spc_timer = dqp->q_blk.timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) dst->d_ino_timer = dqp->q_ino.timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) dst->d_ino_warns = dqp->q_ino.warnings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) dst->d_spc_warns = dqp->q_blk.warnings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) dst->d_rt_spc_timer = dqp->q_rtb.timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) dst->d_rt_spc_warns = dqp->q_rtb.warnings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * Internally, we don't reset all the timers when quota enforcement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * gets turned off. No need to confuse the user level code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * so return zeroes in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (!xfs_dquot_is_enforced(dqp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) dst->d_spc_timer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) dst->d_ino_timer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) dst->d_rt_spc_timer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (xfs_dquot_is_enforced(dqp) && dqp->q_id != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if ((dst->d_space > dst->d_spc_softlimit) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) (dst->d_spc_softlimit > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ASSERT(dst->d_spc_timer != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if ((dst->d_ino_count > dqp->q_ino.softlimit) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) (dqp->q_ino.softlimit > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ASSERT(dst->d_ino_timer != 0);
^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) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /* Return the quota information for the dquot matching id. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) xfs_qm_scall_getquota(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) xfs_dqid_t id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) xfs_dqtype_t type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct qc_dqblk *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct xfs_dquot *dqp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * Try to get the dquot. We don't want it allocated on disk, so don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * set doalloc. If it doesn't exist, we'll get ENOENT back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) error = xfs_qm_dqget(mp, id, type, false, &dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * If everything's NULL, this dquot doesn't quite exist as far as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * our utility programs are concerned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (XFS_IS_DQUOT_UNINITIALIZED(dqp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) error = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) xfs_qm_dqput(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * Return the quota information for the first initialized dquot whose id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * is at least as high as id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) xfs_qm_scall_getquota_next(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) xfs_dqid_t *id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) xfs_dqtype_t type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct qc_dqblk *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct xfs_dquot *dqp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) error = xfs_qm_dqget_next(mp, *id, type, &dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /* Fill in the ID we actually read from disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) *id = dqp->q_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) xfs_qm_dqput(dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) xfs_dqrele_inode(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) void *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) uint *flags = args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /* skip quota inodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (ip == ip->i_mount->m_quotainfo->qi_uquotaip ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) ip == ip->i_mount->m_quotainfo->qi_gquotaip ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) ip == ip->i_mount->m_quotainfo->qi_pquotaip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) ASSERT(ip->i_udquot == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) ASSERT(ip->i_gdquot == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ASSERT(ip->i_pdquot == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) xfs_ilock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if ((*flags & XFS_UQUOTA_ACCT) && ip->i_udquot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) xfs_qm_dqrele(ip->i_udquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) ip->i_udquot = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if ((*flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) xfs_qm_dqrele(ip->i_gdquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ip->i_gdquot = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if ((*flags & XFS_PQUOTA_ACCT) && ip->i_pdquot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) xfs_qm_dqrele(ip->i_pdquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) ip->i_pdquot = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) xfs_iunlock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * Go thru all the inodes in the file system, releasing their dquots.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * Note that the mount structure gets modified to indicate that quotas are off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * AFTER this, in the case of quotaoff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) xfs_qm_dqrele_all_inodes(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) uint flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) ASSERT(mp->m_quotainfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) xfs_inode_walk(mp, XFS_INODE_WALK_INEW_WAIT, xfs_dqrele_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) &flags, XFS_ICI_NO_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }