Пример #1
0
/*
 * Check the limits and timers of a dquot and start or reset timers
 * if necessary.
 * This gets called even when quota enforcement is OFF, which makes our
 * life a little less complicated. (We just don't reject any quota
 * reservations in that case, when enforcement is off).
 * We also return 0 as the values of the timers in Q_GETQUOTA calls, when
 * enforcement's off.
 * In contrast, warnings are a little different in that they don't
 * 'automatically' get started when limits get exceeded.
 */
void
xfs_qm_adjust_dqtimers(
	xfs_mount_t		*mp,
	xfs_disk_dquot_t	*d)
{
	/*
	 * The dquot had better be locked. We are modifying it here.
	 */

	/*
	 * root's limits are not real limits.
	 */
	if (INT_ISZERO(d->d_id, ARCH_CONVERT))
		return;

#ifdef QUOTADEBUG
	if (INT_GET(d->d_blk_hardlimit, ARCH_CONVERT))
		ASSERT(INT_GET(d->d_blk_softlimit, ARCH_CONVERT) <= INT_GET(d->d_blk_hardlimit, ARCH_CONVERT));
	if (INT_GET(d->d_ino_hardlimit, ARCH_CONVERT))
		ASSERT(INT_GET(d->d_ino_softlimit, ARCH_CONVERT) <= INT_GET(d->d_ino_hardlimit, ARCH_CONVERT));
#endif
	if (INT_ISZERO(d->d_btimer, ARCH_CONVERT)) {
		if ((INT_GET(d->d_blk_softlimit, ARCH_CONVERT) &&
		    (INT_GET(d->d_bcount, ARCH_CONVERT) >= INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) ||
		    (INT_GET(d->d_blk_hardlimit, ARCH_CONVERT) &&
		    (INT_GET(d->d_bcount, ARCH_CONVERT) >= INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
			INT_SET(d->d_btimer, ARCH_CONVERT, CURRENT_TIME + XFS_QI_BTIMELIMIT(mp));
		}
	} else {
		if ((INT_ISZERO(d->d_blk_softlimit, ARCH_CONVERT) ||
		    (INT_GET(d->d_bcount, ARCH_CONVERT) < INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) &&
		    (INT_ISZERO(d->d_blk_hardlimit, ARCH_CONVERT) ||
		    (INT_GET(d->d_bcount, ARCH_CONVERT) < INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
			INT_ZERO(d->d_btimer, ARCH_CONVERT);
		}
	}

	if (INT_ISZERO(d->d_itimer, ARCH_CONVERT)) {
		if ((INT_GET(d->d_ino_softlimit, ARCH_CONVERT) &&
		    (INT_GET(d->d_icount, ARCH_CONVERT) >= INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) ||
		    (INT_GET(d->d_ino_hardlimit, ARCH_CONVERT) &&
		    (INT_GET(d->d_icount, ARCH_CONVERT) >= INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
			INT_SET(d->d_itimer, ARCH_CONVERT, CURRENT_TIME + XFS_QI_ITIMELIMIT(mp));
		}
	} else {
		if ((INT_ISZERO(d->d_ino_softlimit, ARCH_CONVERT) ||
		    (INT_GET(d->d_icount, ARCH_CONVERT) < INT_GET(d->d_ino_softlimit, ARCH_CONVERT)))  &&
		    (INT_ISZERO(d->d_ino_hardlimit, ARCH_CONVERT) ||
		    (INT_GET(d->d_icount, ARCH_CONVERT) < INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
			INT_ZERO(d->d_itimer, ARCH_CONVERT);
		}
	}
}
Пример #2
0
/*
 * Return quota status information, such as uquota-off, enforcements, etc.
 */
STATIC int
xfs_qm_scall_getqstat(
	xfs_mount_t	*mp,
	fs_quota_stat_t *out)
{
	xfs_inode_t	*uip, *gip;
	boolean_t	tempuqip, tempgqip;

	uip = gip = NULL;
	tempuqip = tempgqip = B_FALSE;
	memset(out, 0, sizeof(fs_quota_stat_t));

	out->qs_version = FS_QSTAT_VERSION;
	if (! XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) {
		out->qs_uquota.qfs_ino = NULLFSINO;
		out->qs_gquota.qfs_ino = NULLFSINO;
		return (0);
	}
	out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
							(XFS_ALL_QUOTA_ACCT|
							 XFS_ALL_QUOTA_ENFD));
	out->qs_pad = 0;
	out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
	out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;

	if (mp->m_quotainfo) {
		uip = mp->m_quotainfo->qi_uquotaip;
		gip = mp->m_quotainfo->qi_gquotaip;
	}
	if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
		if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
					0, 0, &uip, 0) == 0)
			tempuqip = B_TRUE;
	}
	if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) {
		if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
					0, 0, &gip, 0) == 0)
			tempgqip = B_TRUE;
	}
	if (uip) {
		out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks;
		out->qs_uquota.qfs_nextents = uip->i_d.di_nextents;
		if (tempuqip)
			VN_RELE(XFS_ITOV(uip));
	}
	if (gip) {
		out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks;
		out->qs_gquota.qfs_nextents = gip->i_d.di_nextents;
		if (tempgqip)
			VN_RELE(XFS_ITOV(gip));
	}
	if (mp->m_quotainfo) {
		out->qs_incoredqs = XFS_QI_MPLNDQUOTS(mp);
		out->qs_btimelimit = XFS_QI_BTIMELIMIT(mp);
		out->qs_itimelimit = XFS_QI_ITIMELIMIT(mp);
		out->qs_rtbtimelimit = XFS_QI_RTBTIMELIMIT(mp);
		out->qs_bwarnlimit = XFS_QI_BWARNLIMIT(mp);
		out->qs_iwarnlimit = XFS_QI_IWARNLIMIT(mp);
	}
	return (0);
}
/*
 * Check the limits and timers of a dquot and start or reset timers
 * if necessary.
 * This gets called even when quota enforcement is OFF, which makes our
 * life a little less complicated. (We just don't reject any quota
 * reservations in that case, when enforcement is off).
 * We also return 0 as the values of the timers in Q_GETQUOTA calls, when
 * enforcement's off.
 * In contrast, warnings are a little different in that they don't
 * 'automatically' get started when limits get exceeded.  They do
 * get reset to zero, however, when we find the count to be under
 * the soft limit (they are only ever set non-zero via userspace).
 */
void
xfs_qm_adjust_dqtimers(
	xfs_mount_t		*mp,
	xfs_disk_dquot_t	*d)
{
	ASSERT(d->d_id);

#ifdef QUOTADEBUG
	if (d->d_blk_hardlimit)
		ASSERT(be64_to_cpu(d->d_blk_softlimit) <=
		       be64_to_cpu(d->d_blk_hardlimit));
	if (d->d_ino_hardlimit)
		ASSERT(be64_to_cpu(d->d_ino_softlimit) <=
		       be64_to_cpu(d->d_ino_hardlimit));
	if (d->d_rtb_hardlimit)
		ASSERT(be64_to_cpu(d->d_rtb_softlimit) <=
		       be64_to_cpu(d->d_rtb_hardlimit));
#endif
	if (!d->d_btimer) {
		if ((d->d_blk_softlimit &&
		     (be64_to_cpu(d->d_bcount) >=
		      be64_to_cpu(d->d_blk_softlimit))) ||
		    (d->d_blk_hardlimit &&
		     (be64_to_cpu(d->d_bcount) >=
		      be64_to_cpu(d->d_blk_hardlimit)))) {
			d->d_btimer = cpu_to_be32(get_seconds() +
					XFS_QI_BTIMELIMIT(mp));
		} else {
			d->d_bwarns = 0;
		}
	} else {
		if ((!d->d_blk_softlimit ||
		     (be64_to_cpu(d->d_bcount) <
		      be64_to_cpu(d->d_blk_softlimit))) &&
		    (!d->d_blk_hardlimit ||
		    (be64_to_cpu(d->d_bcount) <
		     be64_to_cpu(d->d_blk_hardlimit)))) {
			d->d_btimer = 0;
		}
	}

	if (!d->d_itimer) {
		if ((d->d_ino_softlimit &&
		     (be64_to_cpu(d->d_icount) >=
		      be64_to_cpu(d->d_ino_softlimit))) ||
		    (d->d_ino_hardlimit &&
		     (be64_to_cpu(d->d_icount) >=
		      be64_to_cpu(d->d_ino_hardlimit)))) {
			d->d_itimer = cpu_to_be32(get_seconds() +
					XFS_QI_ITIMELIMIT(mp));
		} else {
			d->d_iwarns = 0;
		}
	} else {
		if ((!d->d_ino_softlimit ||
		     (be64_to_cpu(d->d_icount) <
		      be64_to_cpu(d->d_ino_softlimit)))  &&
		    (!d->d_ino_hardlimit ||
		     (be64_to_cpu(d->d_icount) <
		      be64_to_cpu(d->d_ino_hardlimit)))) {
			d->d_itimer = 0;
		}
	}

	if (!d->d_rtbtimer) {
		if ((d->d_rtb_softlimit &&
		     (be64_to_cpu(d->d_rtbcount) >=
		      be64_to_cpu(d->d_rtb_softlimit))) ||
		    (d->d_rtb_hardlimit &&
		     (be64_to_cpu(d->d_rtbcount) >=
		      be64_to_cpu(d->d_rtb_hardlimit)))) {
			d->d_rtbtimer = cpu_to_be32(get_seconds() +
					XFS_QI_RTBTIMELIMIT(mp));
		} else {
			d->d_rtbwarns = 0;
		}
	} else {
		if ((!d->d_rtb_softlimit ||
		     (be64_to_cpu(d->d_rtbcount) <
		      be64_to_cpu(d->d_rtb_softlimit))) &&
		    (!d->d_rtb_hardlimit ||
		     (be64_to_cpu(d->d_rtbcount) <
		      be64_to_cpu(d->d_rtb_hardlimit)))) {
			d->d_rtbtimer = 0;
		}
	}
}
Пример #4
0
/*
 * Check the limits and timers of a dquot and start or reset timers
 * if necessary.
 * This gets called even when quota enforcement is OFF, which makes our
 * life a little less complicated. (We just don't reject any quota
 * reservations in that case, when enforcement is off).
 * We also return 0 as the values of the timers in Q_GETQUOTA calls, when
 * enforcement's off.
 * In contrast, warnings are a little different in that they don't
 * 'automatically' get started when limits get exceeded.
 */
void
xfs_qm_adjust_dqtimers(
	xfs_mount_t		*mp,
	xfs_disk_dquot_t	*d)
{
	ASSERT(!INT_ISZERO(d->d_id, ARCH_CONVERT));

#ifdef QUOTADEBUG
	if (INT_GET(d->d_blk_hardlimit, ARCH_CONVERT))
		ASSERT(INT_GET(d->d_blk_softlimit, ARCH_CONVERT) <=
			INT_GET(d->d_blk_hardlimit, ARCH_CONVERT));
	if (INT_GET(d->d_ino_hardlimit, ARCH_CONVERT))
		ASSERT(INT_GET(d->d_ino_softlimit, ARCH_CONVERT) <=
			INT_GET(d->d_ino_hardlimit, ARCH_CONVERT));
	if (INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT))
		ASSERT(INT_GET(d->d_rtb_softlimit, ARCH_CONVERT) <=
			INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT));
#endif
	if (INT_ISZERO(d->d_btimer, ARCH_CONVERT)) {
		if ((INT_GET(d->d_blk_softlimit, ARCH_CONVERT) &&
		    (INT_GET(d->d_bcount, ARCH_CONVERT) >=
				INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) ||
		    (INT_GET(d->d_blk_hardlimit, ARCH_CONVERT) &&
		    (INT_GET(d->d_bcount, ARCH_CONVERT) >=
				INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
			INT_SET(d->d_btimer, ARCH_CONVERT,
				get_seconds() + XFS_QI_BTIMELIMIT(mp));
		}
	} else {
		if ((INT_ISZERO(d->d_blk_softlimit, ARCH_CONVERT) ||
		    (INT_GET(d->d_bcount, ARCH_CONVERT) <
				INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) &&
		    (INT_ISZERO(d->d_blk_hardlimit, ARCH_CONVERT) ||
		    (INT_GET(d->d_bcount, ARCH_CONVERT) <
				INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
			INT_ZERO(d->d_btimer, ARCH_CONVERT);
		}
	}

	if (INT_ISZERO(d->d_itimer, ARCH_CONVERT)) {
		if ((INT_GET(d->d_ino_softlimit, ARCH_CONVERT) &&
		    (INT_GET(d->d_icount, ARCH_CONVERT) >=
				INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) ||
		    (INT_GET(d->d_ino_hardlimit, ARCH_CONVERT) &&
		    (INT_GET(d->d_icount, ARCH_CONVERT) >=
				INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
			INT_SET(d->d_itimer, ARCH_CONVERT,
				get_seconds() + XFS_QI_ITIMELIMIT(mp));
		}
	} else {
		if ((INT_ISZERO(d->d_ino_softlimit, ARCH_CONVERT) ||
		    (INT_GET(d->d_icount, ARCH_CONVERT) <
				INT_GET(d->d_ino_softlimit, ARCH_CONVERT)))  &&
		    (INT_ISZERO(d->d_ino_hardlimit, ARCH_CONVERT) ||
		    (INT_GET(d->d_icount, ARCH_CONVERT) <
				INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
			INT_ZERO(d->d_itimer, ARCH_CONVERT);
		}
	}

	if (INT_ISZERO(d->d_rtbtimer, ARCH_CONVERT)) {
		if ((INT_GET(d->d_rtb_softlimit, ARCH_CONVERT) &&
		    (INT_GET(d->d_rtbcount, ARCH_CONVERT) >=
				INT_GET(d->d_rtb_softlimit, ARCH_CONVERT))) ||
		    (INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT) &&
		    (INT_GET(d->d_rtbcount, ARCH_CONVERT) >=
				INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
			INT_SET(d->d_rtbtimer, ARCH_CONVERT,
				get_seconds() + XFS_QI_RTBTIMELIMIT(mp));
		}
	} else {
		if ((INT_ISZERO(d->d_rtb_softlimit, ARCH_CONVERT) ||
		    (INT_GET(d->d_rtbcount, ARCH_CONVERT) <
				INT_GET(d->d_rtb_softlimit, ARCH_CONVERT))) &&
		    (INT_ISZERO(d->d_rtb_hardlimit, ARCH_CONVERT) ||
		    (INT_GET(d->d_rtbcount, ARCH_CONVERT) <
				INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
			INT_ZERO(d->d_rtbtimer, ARCH_CONVERT);
		}
	}
}