示例#1
0
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;
}
示例#2
0
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;
}
示例#6
0
/*
 * 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;
}