/* * 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); } } }
/* * 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; } } }
/* * 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); } } }