Source
x
* Note that the mount structure gets modified to indicate that quotas are off
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
* All Rights Reserved.
*/
STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint);
STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *,
uint);
/*
* Turn off quota accounting and/or enforcement for all udquots and/or
* gdquots. Called only at unmount time.
*
* This assumes that there are no dquots of this file system cached
* incore, and modifies the ondisk dquot directly. Therefore, for example,
* it is an error to call this twice, without purging the cache.
*/
int
xfs_qm_scall_quotaoff(
xfs_mount_t *mp,
uint flags)
{
struct xfs_quotainfo *q = mp->m_quotainfo;
uint dqtype;
int error;
uint inactivate_flags;
xfs_qoff_logitem_t *qoffstart;
/*
* No file system can have quotas enabled on disk but not in core.
* Note that quota utilities (like quotaoff) _expect_
* errno == -EEXIST here.
*/
if ((mp->m_qflags & flags) == 0)
return -EEXIST;
error = 0;
flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
/*
* We don't want to deal with two quotaoffs messing up each other,
* so we're going to serialize it. quotaoff isn't exactly a performance
* critical thing.
* If quotaoff, then we must be dealing with the root filesystem.
*/
ASSERT(q);
mutex_lock(&q->qi_quotaofflock);
/*
* If we're just turning off quota enforcement, change mp and go.
*/
if ((flags & XFS_ALL_QUOTA_ACCT) == 0) {
mp->m_qflags &= ~(flags);
spin_lock(&mp->m_sb_lock);
mp->m_sb.sb_qflags = mp->m_qflags;
spin_unlock(&mp->m_sb_lock);
mutex_unlock(&q->qi_quotaofflock);
/* XXX what to do if error ? Revert back to old vals incore ? */
return xfs_sync_sb(mp, false);
}
dqtype = 0;
inactivate_flags = 0;
/*
* If accounting is off, we must turn enforcement off, clear the
* quota 'CHKD' certificate to make it known that we have to
* do a quotacheck the next time this quota is turned on.
*/
if (flags & XFS_UQUOTA_ACCT) {