STATIC struct xfs_dqtrx * xfs_trans_get_dqtrx( struct xfs_trans *tp, struct xfs_dquot *dqp) { int i; struct xfs_dqtrx *qa; if (XFS_QM_ISUDQ(dqp)) qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_USR]; else if (XFS_QM_ISGDQ(dqp)) qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_GRP]; else if (XFS_QM_ISPDQ(dqp)) qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_PRJ]; else return NULL; for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) { if (qa[i].qt_dquot == NULL || qa[i].qt_dquot == dqp) return &qa[i]; } return NULL; }
void xfs_qm_dqprint(xfs_dquot_t *dqp) { cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------"); cmn_err(CE_DEBUG, "---- dquotID = %d", (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT)); cmn_err(CE_DEBUG, "---- type = %s", XFS_QM_ISUDQ(dqp) ? "USR" : "GRP"); cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount); cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno); cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset); cmn_err(CE_DEBUG, "---- blkhlimit = %Lu (0x%x)", INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT), (int) INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT)); cmn_err(CE_DEBUG, "---- blkslimit = %Lu (0x%x)", INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT), (int)INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT)); cmn_err(CE_DEBUG, "---- inohlimit = %Lu (0x%x)", INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT), (int)INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT)); cmn_err(CE_DEBUG, "---- inoslimit = %Lu (0x%x)", INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT), (int)INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT)); cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)", INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT), (int)INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT)); cmn_err(CE_DEBUG, "---- icount = %Lu (0x%x)", INT_GET(dqp->q_core.d_icount, ARCH_CONVERT), (int)INT_GET(dqp->q_core.d_icount, ARCH_CONVERT)); cmn_err(CE_DEBUG, "---- btimer = %d", (int)INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT)); cmn_err(CE_DEBUG, "---- itimer = %d", (int)INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)); cmn_err(CE_DEBUG, "---------------------------"); }
STATIC void xfs_qm_dqtest_print( xfs_dqtest_t *d) { cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------"); cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id); cmn_err(CE_DEBUG, "---- type = %s", XFS_QM_ISUDQ(d)? "USR" : "GRP"); cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount); cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)", d->d_bcount, (int)d->d_bcount); cmn_err(CE_DEBUG, "---- icount = %Lu (0x%x)", d->d_icount, (int)d->d_icount); cmn_err(CE_DEBUG, "---------------------------"); }
STATIC int xfs_dqtest_cmp2( xfs_dqtest_t *d, xfs_dquot_t *dqp) { int err = 0; if (INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) != d->d_icount) { xfs_qm_dqtest_failed(d, dqp, "icount mismatch", INT_GET(dqp->q_core.d_icount, ARCH_CONVERT), d->d_icount, 0); err++; } if (INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT) != d->d_bcount) { xfs_qm_dqtest_failed(d, dqp, "bcount mismatch", INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT), d->d_bcount, 0); err++; } if (INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT) && INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT) >= INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT)) { if (INT_ISZERO(dqp->q_core.d_btimer, ARCH_CONVERT) && !INT_ISZERO(dqp->q_core.d_id, ARCH_CONVERT)) { cmn_err(CE_DEBUG, "%d [%s] [0x%p] BLK TIMER NOT STARTED", d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount); err++; } } if (INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT) && INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT)) { if (INT_ISZERO(dqp->q_core.d_itimer, ARCH_CONVERT) && !INT_ISZERO(dqp->q_core.d_id, ARCH_CONVERT)) { cmn_err(CE_DEBUG, "%d [%s] [0x%p] INO TIMER NOT STARTED", d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount); err++; } } #ifdef QUOTADEBUG if (!err) { cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked", d->d_id, XFS_QM_ISUDQ(d) ? "USR" : "GRP", d->q_mount); } #endif return (err); }
STATIC xfs_dqtrx_t * xfs_trans_get_dqtrx( xfs_trans_t *tp, xfs_dquot_t *dqp) { int i; xfs_dqtrx_t *qa; qa = XFS_QM_ISUDQ(dqp) ? tp->t_dqinfo->dqa_usrdquots : tp->t_dqinfo->dqa_grpdquots; for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) { if (qa[i].qt_dquot == NULL || qa[i].qt_dquot == dqp) return &qa[i]; } return NULL; }
/* * This reserves disk blocks and inodes against a dquot. * Flags indicate if the dquot is to be locked here and also * if the blk reservation is for RT or regular blocks. * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check. */ STATIC int xfs_trans_dqresv( xfs_trans_t *tp, xfs_mount_t *mp, xfs_dquot_t *dqp, long nblks, long ninos, uint flags) { xfs_qcnt_t hardlimit; xfs_qcnt_t softlimit; time_t timer; xfs_qwarncnt_t warns; xfs_qwarncnt_t warnlimit; xfs_qcnt_t total_count; xfs_qcnt_t *resbcountp; xfs_quotainfo_t *q = mp->m_quotainfo; struct xfs_def_quota *defq; xfs_dqlock(dqp); defq = xfs_get_defquota(dqp, q); if (flags & XFS_TRANS_DQ_RES_BLKS) { hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit); if (!hardlimit) hardlimit = defq->bhardlimit; softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit); if (!softlimit) softlimit = defq->bsoftlimit; timer = be32_to_cpu(dqp->q_core.d_btimer); warns = be16_to_cpu(dqp->q_core.d_bwarns); warnlimit = dqp->q_mount->m_quotainfo->qi_bwarnlimit; resbcountp = &dqp->q_res_bcount; } else { ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit); if (!hardlimit) hardlimit = defq->rtbhardlimit; softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit); if (!softlimit) softlimit = defq->rtbsoftlimit; timer = be32_to_cpu(dqp->q_core.d_rtbtimer); warns = be16_to_cpu(dqp->q_core.d_rtbwarns); warnlimit = dqp->q_mount->m_quotainfo->qi_rtbwarnlimit; resbcountp = &dqp->q_res_rtbcount; } if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_core.d_id && ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) || (XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) || (XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(dqp)))) { if (nblks > 0) { /* * dquot is locked already. See if we'd go over the * hardlimit or exceed the timelimit if we allocate * nblks. */ total_count = *resbcountp + nblks; if (hardlimit && total_count > hardlimit) { xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN); goto error_return; } if (softlimit && total_count > softlimit) { if ((timer != 0 && get_seconds() > timer) || (warns != 0 && warns >= warnlimit)) { xfs_quota_warn(mp, dqp, QUOTA_NL_BSOFTLONGWARN); goto error_return; } xfs_quota_warn(mp, dqp, QUOTA_NL_BSOFTWARN); } } if (ninos > 0) { total_count = be64_to_cpu(dqp->q_core.d_icount) + ninos; timer = be32_to_cpu(dqp->q_core.d_itimer); warns = be16_to_cpu(dqp->q_core.d_iwarns); warnlimit = dqp->q_mount->m_quotainfo->qi_iwarnlimit; hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); if (!hardlimit) hardlimit = defq->ihardlimit; softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); if (!softlimit) softlimit = defq->isoftlimit; if (hardlimit && total_count > hardlimit) { xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN); goto error_return; } if (softlimit && total_count > softlimit) { if ((timer != 0 && get_seconds() > timer) || (warns != 0 && warns >= warnlimit)) { xfs_quota_warn(mp, dqp, QUOTA_NL_ISOFTLONGWARN); goto error_return; } xfs_quota_warn(mp, dqp, QUOTA_NL_ISOFTWARN); } } } /* * Change the reservation, but not the actual usage. * Note that q_res_bcount = q_core.d_bcount + resv */ (*resbcountp) += (xfs_qcnt_t)nblks; if (ninos != 0) dqp->q_res_icount += (xfs_qcnt_t)ninos; /* * note the reservation amt in the trans struct too, * so that the transaction knows how much was reserved by * it against this particular dquot. * We don't do this when we are reserving for a delayed allocation, * because we don't have the luxury of a transaction envelope then. */ if (tp) { ASSERT(tp->t_dqinfo); ASSERT(flags & XFS_QMOPT_RESBLK_MASK); if (nblks != 0) xfs_trans_mod_dquot(tp, dqp, flags & XFS_QMOPT_RESBLK_MASK, nblks); if (ninos != 0) xfs_trans_mod_dquot(tp, dqp, XFS_TRANS_DQ_RES_INOS, ninos); } ASSERT(dqp->q_res_bcount >= be64_to_cpu(dqp->q_core.d_bcount)); ASSERT(dqp->q_res_rtbcount >= be64_to_cpu(dqp->q_core.d_rtbcount)); ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount)); xfs_dqunlock(dqp); return 0; error_return: xfs_dqunlock(dqp); if (flags & XFS_QMOPT_ENOSPC) return -ENOSPC; return -EDQUOT; }