Commit d3537cf9 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: stop using q_core limits in the quota code



Add limits fields in the incore dquot, and use that instead of the ones
in qcore.  This eliminates a bunch of endian conversions and will
eventually allow us to remove qcore entirely.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChandan Babu R <chandanrlinux@gmail.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarAllison Collins <allison.henderson@oracle.com>
parent 784e80f5
Loading
Loading
Loading
Loading
+12 −24
Original line number Diff line number Diff line
@@ -82,12 +82,6 @@ xchk_quota_item(
	struct xfs_disk_dquot	*d = &dq->q_core;
	struct xfs_quotainfo	*qi = mp->m_quotainfo;
	xfs_fileoff_t		offset;
	unsigned long long	bsoft;
	unsigned long long	isoft;
	unsigned long long	rsoft;
	unsigned long long	bhard;
	unsigned long long	ihard;
	unsigned long long	rhard;
	unsigned long long	bcount;
	unsigned long long	icount;
	unsigned long long	rcount;
@@ -114,15 +108,6 @@ xchk_quota_item(
	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);

	/* Check the limits. */
	bhard = be64_to_cpu(d->d_blk_hardlimit);
	ihard = be64_to_cpu(d->d_ino_hardlimit);
	rhard = be64_to_cpu(d->d_rtb_hardlimit);

	bsoft = be64_to_cpu(d->d_blk_softlimit);
	isoft = be64_to_cpu(d->d_ino_softlimit);
	rsoft = be64_to_cpu(d->d_rtb_softlimit);

	/*
	 * Warn if the hard limits are larger than the fs.
	 * Administrators can do this, though in production this seems
@@ -131,19 +116,19 @@ xchk_quota_item(
	 * Complain about corruption if the soft limit is greater than
	 * the hard limit.
	 */
	if (bhard > mp->m_sb.sb_dblocks)
	if (dq->q_blk.hardlimit > mp->m_sb.sb_dblocks)
		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
	if (bsoft > bhard)
	if (dq->q_blk.softlimit > dq->q_blk.hardlimit)
		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);

	if (ihard > M_IGEO(mp)->maxicount)
	if (dq->q_ino.hardlimit > M_IGEO(mp)->maxicount)
		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
	if (isoft > ihard)
	if (dq->q_ino.softlimit > dq->q_ino.hardlimit)
		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);

	if (rhard > mp->m_sb.sb_rblocks)
	if (dq->q_rtb.hardlimit > mp->m_sb.sb_rblocks)
		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
	if (rsoft > rhard)
	if (dq->q_rtb.softlimit > dq->q_rtb.hardlimit)
		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);

	/* Check the resource counts. */
@@ -177,13 +162,16 @@ xchk_quota_item(
	if (dq->q_id == 0)
		goto out;

	if (bhard != 0 && bcount > bhard)
	if (dq->q_blk.hardlimit != 0 &&
	    bcount > dq->q_blk.hardlimit)
		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);

	if (ihard != 0 && icount > ihard)
	if (dq->q_ino.hardlimit != 0 &&
	    icount > dq->q_ino.hardlimit)
		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);

	if (rhard != 0 && rcount > rhard)
	if (dq->q_rtb.hardlimit != 0 &&
	    rcount > dq->q_rtb.hardlimit)
		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);

out:
+75 −60
Original line number Diff line number Diff line
@@ -71,29 +71,28 @@ xfs_qm_adjust_dqlimits(
	struct xfs_dquot	*dq)
{
	struct xfs_quotainfo	*q = mp->m_quotainfo;
	struct xfs_disk_dquot	*d = &dq->q_core;
	struct xfs_def_quota	*defq;
	int			prealloc = 0;

	ASSERT(dq->q_id);
	defq = xfs_get_defquota(q, xfs_dquot_type(dq));

	if (defq->bsoftlimit && !d->d_blk_softlimit) {
		d->d_blk_softlimit = cpu_to_be64(defq->bsoftlimit);
	if (defq->bsoftlimit && !dq->q_blk.softlimit) {
		dq->q_blk.softlimit = defq->bsoftlimit;
		prealloc = 1;
	}
	if (defq->bhardlimit && !d->d_blk_hardlimit) {
		d->d_blk_hardlimit = cpu_to_be64(defq->bhardlimit);
	if (defq->bhardlimit && !dq->q_blk.hardlimit) {
		dq->q_blk.hardlimit = defq->bhardlimit;
		prealloc = 1;
	}
	if (defq->isoftlimit && !d->d_ino_softlimit)
		d->d_ino_softlimit = cpu_to_be64(defq->isoftlimit);
	if (defq->ihardlimit && !d->d_ino_hardlimit)
		d->d_ino_hardlimit = cpu_to_be64(defq->ihardlimit);
	if (defq->rtbsoftlimit && !d->d_rtb_softlimit)
		d->d_rtb_softlimit = cpu_to_be64(defq->rtbsoftlimit);
	if (defq->rtbhardlimit && !d->d_rtb_hardlimit)
		d->d_rtb_hardlimit = cpu_to_be64(defq->rtbhardlimit);
	if (defq->isoftlimit && !dq->q_ino.softlimit)
		dq->q_ino.softlimit = defq->isoftlimit;
	if (defq->ihardlimit && !dq->q_ino.hardlimit)
		dq->q_ino.hardlimit = defq->ihardlimit;
	if (defq->rtbsoftlimit && !dq->q_rtb.softlimit)
		dq->q_rtb.softlimit = defq->rtbsoftlimit;
	if (defq->rtbhardlimit && !dq->q_rtb.hardlimit)
		dq->q_rtb.hardlimit = defq->rtbhardlimit;

	if (prealloc)
		xfs_dquot_set_prealloc_limits(dq);
@@ -125,82 +124,67 @@ xfs_qm_adjust_dqtimers(
	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));

#ifdef DEBUG
	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));
	if (dq->q_blk.hardlimit)
		ASSERT(dq->q_blk.softlimit <= dq->q_blk.hardlimit);
	if (dq->q_ino.hardlimit)
		ASSERT(dq->q_ino.softlimit <= dq->q_ino.hardlimit);
	if (dq->q_rtb.hardlimit)
		ASSERT(dq->q_rtb.softlimit <= dq->q_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)))) {
		if ((dq->q_blk.softlimit &&
		     (be64_to_cpu(d->d_bcount) > dq->q_blk.softlimit)) ||
		    (dq->q_blk.hardlimit &&
		     (be64_to_cpu(d->d_bcount) > dq->q_blk.hardlimit))) {
			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
					defq->btimelimit);
		} 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)))) {
		if ((!dq->q_blk.softlimit ||
		     (be64_to_cpu(d->d_bcount) <= dq->q_blk.softlimit)) &&
		    (!dq->q_blk.hardlimit ||
		    (be64_to_cpu(d->d_bcount) <= dq->q_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)))) {
		if ((dq->q_ino.softlimit &&
		     (be64_to_cpu(d->d_icount) > dq->q_ino.softlimit)) ||
		    (dq->q_ino.hardlimit &&
		     (be64_to_cpu(d->d_icount) > dq->q_ino.hardlimit))) {
			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
					defq->itimelimit);
		} 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)))) {
		if ((!dq->q_ino.softlimit ||
		     (be64_to_cpu(d->d_icount) <= dq->q_ino.softlimit))  &&
		    (!dq->q_ino.hardlimit ||
		     (be64_to_cpu(d->d_icount) <= dq->q_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)))) {
		if ((dq->q_rtb.softlimit &&
		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.softlimit)) ||
		    (dq->q_rtb.hardlimit &&
		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.hardlimit))) {
			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
					defq->rtbtimelimit);
		} 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)))) {
		if ((!dq->q_rtb.softlimit ||
		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.softlimit)) &&
		    (!dq->q_rtb.hardlimit ||
		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.hardlimit))) {
			d->d_rtbtimer = 0;
		}
	}
@@ -291,8 +275,8 @@ xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
{
	uint64_t space;

	dqp->q_prealloc_hi_wmark = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
	dqp->q_prealloc_lo_wmark = be64_to_cpu(dqp->q_core.d_blk_softlimit);
	dqp->q_prealloc_hi_wmark = dqp->q_blk.hardlimit;
	dqp->q_prealloc_lo_wmark = dqp->q_blk.softlimit;
	if (!dqp->q_prealloc_lo_wmark) {
		dqp->q_prealloc_lo_wmark = dqp->q_prealloc_hi_wmark;
		do_div(dqp->q_prealloc_lo_wmark, 100);
@@ -547,6 +531,12 @@ xfs_dquot_from_disk(

	/* copy everything from disk dquot to the incore dquot */
	memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot));
	dqp->q_blk.hardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
	dqp->q_blk.softlimit = be64_to_cpu(ddqp->d_blk_softlimit);
	dqp->q_ino.hardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
	dqp->q_ino.softlimit = be64_to_cpu(ddqp->d_ino_softlimit);
	dqp->q_rtb.hardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
	dqp->q_rtb.softlimit = be64_to_cpu(ddqp->d_rtb_softlimit);

	/*
	 * Reservation counters are defined as reservation plus current usage
@@ -568,6 +558,12 @@ xfs_dquot_to_disk(
	struct xfs_dquot	*dqp)
{
	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
	ddqp->d_blk_hardlimit = cpu_to_be64(dqp->q_blk.hardlimit);
	ddqp->d_blk_softlimit = cpu_to_be64(dqp->q_blk.softlimit);
	ddqp->d_ino_hardlimit = cpu_to_be64(dqp->q_ino.hardlimit);
	ddqp->d_ino_softlimit = cpu_to_be64(dqp->q_ino.softlimit);
	ddqp->d_rtb_hardlimit = cpu_to_be64(dqp->q_rtb.hardlimit);
	ddqp->d_rtb_softlimit = cpu_to_be64(dqp->q_rtb.softlimit);
}

/* Allocate and initialize the dquot buffer for this in-core dquot. */
@@ -1129,6 +1125,7 @@ static xfs_failaddr_t
xfs_qm_dqflush_check(
	struct xfs_dquot	*dqp)
{
	struct xfs_disk_dquot	*ddq = &dqp->q_core;
	__u8			type = dqp->dq_flags & XFS_DQ_ALLTYPES;

	if (type != XFS_DQ_USER &&
@@ -1136,6 +1133,24 @@ xfs_qm_dqflush_check(
	    type != XFS_DQ_PROJ)
		return __this_address;

	if (dqp->q_id == 0)
		return NULL;

	if (dqp->q_blk.softlimit &&
	    be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit &&
	    !ddq->d_btimer)
		return __this_address;

	if (dqp->q_ino.softlimit &&
	    be64_to_cpu(ddq->d_icount) > dqp->q_ino.softlimit &&
	    !ddq->d_itimer)
		return __this_address;

	if (dqp->q_rtb.softlimit &&
	    be64_to_cpu(ddq->d_rtbcount) > dqp->q_rtb.softlimit &&
	    !ddq->d_rtbtimer)
		return __this_address;

	return NULL;
}

+5 −1
Original line number Diff line number Diff line
@@ -30,6 +30,10 @@ enum {
struct xfs_dquot_res {
	/* Total resources allocated and reserved. */
	xfs_qcnt_t		reserved;

	/* Absolute and preferred limits. */
	xfs_qcnt_t		hardlimit;
	xfs_qcnt_t		softlimit;
};

/*
@@ -143,7 +147,7 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
{
	int64_t freesp;

	freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_blk.reserved;
	freesp = dqp->q_blk.hardlimit - dqp->q_blk.reserved;
	if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT])
		return true;

+6 −8
Original line number Diff line number Diff line
@@ -550,26 +550,24 @@ xfs_qm_set_defquota(
{
	struct xfs_dquot	*dqp;
	struct xfs_def_quota	*defq;
	struct xfs_disk_dquot	*ddqp;
	int			error;

	error = xfs_qm_dqget_uncached(mp, 0, type, &dqp);
	if (error)
		return;

	ddqp = &dqp->q_core;
	defq = xfs_get_defquota(qinf, xfs_dquot_type(dqp));

	/*
	 * Timers and warnings have been already set, let's just set the
	 * default limits for this quota type
	 */
	defq->bhardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
	defq->bsoftlimit = be64_to_cpu(ddqp->d_blk_softlimit);
	defq->ihardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
	defq->isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit);
	defq->rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
	defq->rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
	defq->bhardlimit = dqp->q_blk.hardlimit;
	defq->bsoftlimit = dqp->q_blk.softlimit;
	defq->ihardlimit = dqp->q_ino.hardlimit;
	defq->isoftlimit = dqp->q_ino.softlimit;
	defq->rtbhardlimit = dqp->q_rtb.hardlimit;
	defq->rtbsoftlimit = dqp->q_rtb.softlimit;
	xfs_qm_dqdestroy(dqp);
}

+6 −6
Original line number Diff line number Diff line
@@ -20,12 +20,12 @@ extern struct kmem_zone *xfs_qm_dqtrxzone;
#define XFS_DQITER_MAP_SIZE	10

#define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
	!dqp->q_core.d_blk_hardlimit && \
	!dqp->q_core.d_blk_softlimit && \
	!dqp->q_core.d_rtb_hardlimit && \
	!dqp->q_core.d_rtb_softlimit && \
	!dqp->q_core.d_ino_hardlimit && \
	!dqp->q_core.d_ino_softlimit && \
	!dqp->q_blk.hardlimit && \
	!dqp->q_blk.softlimit && \
	!dqp->q_rtb.hardlimit && \
	!dqp->q_rtb.softlimit && \
	!dqp->q_ino.hardlimit && \
	!dqp->q_ino.softlimit && \
	!dqp->q_core.d_bcount && \
	!dqp->q_core.d_rtbcount && \
	!dqp->q_core.d_icount)
Loading