^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-2006 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_quota.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "xfs_qm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) xfs_fill_statvfs_from_dquot(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct kstatfs *statp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct xfs_dquot *dqp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) uint64_t limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) limit = dqp->q_blk.softlimit ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) dqp->q_blk.softlimit :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) dqp->q_blk.hardlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (limit && statp->f_blocks > limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) statp->f_blocks = limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) statp->f_bfree = statp->f_bavail =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) (statp->f_blocks > dqp->q_blk.reserved) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) (statp->f_blocks - dqp->q_blk.reserved) : 0;
^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) limit = dqp->q_ino.softlimit ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) dqp->q_ino.softlimit :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) dqp->q_ino.hardlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (limit && statp->f_files > limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) statp->f_files = limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) statp->f_ffree =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) (statp->f_files > dqp->q_ino.reserved) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) (statp->f_files - dqp->q_ino.reserved) : 0;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Directory tree accounting is implemented using project quotas, where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * the project identifier is inherited from parent directories.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * A statvfs (df, etc.) of a directory that is using project quota should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * return a statvfs of the project, not the entire filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * This makes such trees appear as if they are filesystems in themselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) xfs_qm_statvfs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct kstatfs *statp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct xfs_dquot *dqp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (!xfs_qm_dqget(mp, ip->i_d.di_projid, XFS_DQTYPE_PROJ, false, &dqp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) xfs_fill_statvfs_from_dquot(statp, dqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) xfs_qm_dqput(dqp);
^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) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) xfs_qm_newmount(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) xfs_mount_t *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) uint *needquotamount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) uint *quotaflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) uint quotaondisk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) quotaondisk = xfs_sb_version_hasquota(&mp->m_sb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (quotaondisk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) pquotaondisk = mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^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) * If the device itself is read-only, we can't allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * the user to change the state of quota on the mount -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * this would generate a transaction on the ro device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * which would lead to an I/O error and shutdown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) (!gquotaondisk && XFS_IS_GQUOTA_ON(mp)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) (!pquotaondisk && XFS_IS_PQUOTA_ON(mp))) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) xfs_dev_is_read_only(mp, "changing quota state")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) xfs_warn(mp, "please mount with%s%s%s%s.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) (!quotaondisk ? "out quota" : ""),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) (uquotaondisk ? " usrquota" : ""),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) (gquotaondisk ? " grpquota" : ""),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) (pquotaondisk ? " prjquota" : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (XFS_IS_QUOTA_ON(mp) || quotaondisk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * Call mount_quotas at this point only if we won't have to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * a quotacheck.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (quotaondisk && !XFS_QM_NEED_QUOTACHECK(mp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * If an error occurred, qm_mount_quotas code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * has already disabled quotas. So, just finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * mounting, and get on with the boring life
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * without disk quotas.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) xfs_qm_mount_quotas(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * Clear the quota flags, but remember them. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * is so that the quota code doesn't get invoked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * before we're ready. This can happen when an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * inode goes inactive and wants to free blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * or via xfs_log_mount_finish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *needquotamount = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) *quotaflags = mp->m_qflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) mp->m_qflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }