Hi all, This series replaces q_core (the ondisk quota structure) in the incore dquot structure with a quota resource control structure containing the count, reservation, limits, timers, and warnings. Each dquot gets three of these resource control structures (blocks, inodes, rt blocks). Doing this enables us to remove a whole lot of noisy endian conversions in the quota code, and enables us to refactor a bunch of open-coded logic to pass around pointers to quota resource control structs. Note that these cleanups are a prerequisite for the bigtime patchset, as it depends on incore quota timers being time64_t to take advantage of the 64-bit time functions in the kernel with fewer places to trip over the ondisk format. If you're going to start using this mess, you probably ought to just pull from my git trees, which are linked below. This is an extraordinary way to destroy everything. Enjoy! Comments and questions are, as always, welcome. --D kernel git tree: https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=remove-quota-qcore xfsprogs git tree: https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=remove-quota-qcore --- fs/xfs/libxfs/xfs_quota_defs.h | 2 fs/xfs/scrub/quota.c | 69 +++----- fs/xfs/xfs_dquot.c | 283 +++++++++++++++++++--------------- fs/xfs/xfs_dquot.h | 54 +++++-- fs/xfs/xfs_dquot_item.c | 8 + fs/xfs/xfs_iomap.c | 6 - fs/xfs/xfs_qm.c | 92 +++++------ fs/xfs/xfs_qm.h | 42 ++--- fs/xfs/xfs_qm_bhv.c | 20 +- fs/xfs/xfs_qm_syscalls.c | 231 +++++++++++++++------------- fs/xfs/xfs_quotaops.c | 12 + fs/xfs/xfs_trace.h | 160 ++++++++++++++++++- fs/xfs/xfs_trans_dquot.c | 329 ++++++++++++++++++++-------------------- 13 files changed, 744 insertions(+), 564 deletions(-)
From: Darrick J. Wong <darrick.wong@oracle.com> In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we can't lock the dquot buf to flush the dquot. This prevents the AIL from blocking on the dquot, but it also forgets to clear the FREEING flag on its way out. A subsequent purge attempt will see the FREEING flag is set and bail out, which leads to dqpurge_all failing to purge all the dquots. This causes unmounts and quotaoff operations to hang. Fixes: 8d3d7e2b35ea ("xfs: trylock underlying buffer on dquot flush") Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_qm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index d6cd83317344..938023dd8ce5 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -148,6 +148,7 @@ xfs_qm_dqpurge( error = xfs_bwrite(bp); xfs_buf_relse(bp); } else if (error == -EAGAIN) { + dqp->dq_flags &= ~XFS_DQ_FREEING; goto out_unlock; } xfs_dqflock(dqp);
From: Darrick J. Wong <darrick.wong@oracle.com> xfs_trans_dqresv is the function that we use to make reservations against resource quotas. Each resource contains two counters: the q_core counter, which tracks resources allocated on disk; and the dquot reservation counter, which tracks how much of that resource has either been allocated or reserved by threads that are working on metadata updates. For disk blocks, we compare the proposed reservation counter against the hard and soft limits to decide if we're going to fail the operation. However, for inodes we inexplicably compare against the q_core counter, not the incore reservation count. Since the q_core counter is always lower than the reservation count and we unlock the dquot between reservation and transaction commit, this means that multiple threads can reserve the last inode count before we hit the hard limit, and when they commit, we'll be well over the hard limit. Fix this by checking against the incore inode reservation counter, since we would appear to maintain that correctly (and that's what we report in GETQUOTA). Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_trans_dquot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index c0f73b82c055..ed0ce8b301b4 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -647,7 +647,7 @@ xfs_trans_dqresv( } } if (ninos > 0) { - total_count = be64_to_cpu(dqp->q_core.d_icount) + ninos; + total_count = dqp->q_res_icount + ninos; timer = be32_to_cpu(dqp->q_core.d_itimer); warns = be16_to_cpu(dqp->q_core.d_iwarns); warnlimit = defq->iwarnlimit;
From: Darrick J. Wong <darrick.wong@oracle.com> While loading dquot records off disk, make sure that the quota type flags are the same between the incore dquot and the ondisk dquot. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_dquot.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index d5b7f03e93c8..46c8ca83c04d 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -524,13 +524,27 @@ xfs_dquot_alloc( } /* Copy the in-core quota fields in from the on-disk buffer. */ -STATIC void +STATIC int xfs_dquot_from_disk( struct xfs_dquot *dqp, struct xfs_buf *bp) { struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset; + /* + * The only field the verifier didn't check was the quota type flag, so + * do that here. + */ + if ((dqp->dq_flags & XFS_DQ_ALLTYPES) != + (ddqp->d_flags & XFS_DQ_ALLTYPES) || + dqp->q_core.d_id != ddqp->d_id) { + xfs_alert(bp->b_mount, + "Metadata corruption detected at %pS, quota %u", + __this_address, be32_to_cpu(dqp->q_core.d_id)); + xfs_alert(bp->b_mount, "Unmount and run xfs_repair"); + return -EFSCORRUPTED; + } + /* copy everything from disk dquot to the incore dquot */ memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot)); @@ -544,6 +558,7 @@ xfs_dquot_from_disk( /* initialize the dquot speculative prealloc thresholds */ xfs_dquot_set_prealloc_limits(dqp); + return 0; } /* Allocate and initialize the dquot buffer for this in-core dquot. */ @@ -617,9 +632,11 @@ xfs_qm_dqread( * further. */ ASSERT(xfs_buf_islocked(bp)); - xfs_dquot_from_disk(dqp, bp); - + error = xfs_dquot_from_disk(dqp, bp); xfs_buf_relse(bp); + if (error) + goto err; + *dqpp = dqp; return error;
From: Darrick J. Wong <darrick.wong@oracle.com> Use the incore dq_flags to figure out the dquot type. This is the first step towards removing xfs_disk_dquot from the incore dquot. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/libxfs/xfs_quota_defs.h | 2 ++ fs/xfs/scrub/quota.c | 4 ---- fs/xfs/xfs_dquot.c | 33 +++++++++++++++++++++++++++++++-- fs/xfs/xfs_dquot.h | 2 ++ fs/xfs/xfs_dquot_item.c | 6 ++++-- fs/xfs/xfs_qm.c | 4 ++-- fs/xfs/xfs_qm.h | 2 +- fs/xfs/xfs_qm_syscalls.c | 9 +++------ 8 files changed, 45 insertions(+), 17 deletions(-) diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h index 56d9dd787e7b..459023b0a304 100644 --- a/fs/xfs/libxfs/xfs_quota_defs.h +++ b/fs/xfs/libxfs/xfs_quota_defs.h @@ -29,6 +29,8 @@ typedef uint16_t xfs_qwarncnt_t; #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) +#define XFS_DQ_ONDISK (XFS_DQ_ALLTYPES) + #define XFS_DQ_FLAGS \ { XFS_DQ_USER, "USER" }, \ { XFS_DQ_PROJ, "PROJ" }, \ diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c index 905a34558361..710659d3fa28 100644 --- a/fs/xfs/scrub/quota.c +++ b/fs/xfs/scrub/quota.c @@ -108,10 +108,6 @@ xchk_quota_item( sqi->last_id = id; - /* Did we get the dquot type we wanted? */ - if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES)) - xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); - if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 46c8ca83c04d..59d1bce34a98 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -561,6 +561,16 @@ xfs_dquot_from_disk( return 0; } +/* Copy the in-core quota fields into the on-disk buffer. */ +void +xfs_dquot_to_disk( + struct xfs_disk_dquot *ddqp, + struct xfs_dquot *dqp) +{ + memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); + ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK; +} + /* Allocate and initialize the dquot buffer for this in-core dquot. */ static int xfs_qm_dqread_alloc( @@ -1108,6 +1118,17 @@ xfs_qm_dqflush_done( xfs_dqfunlock(dqp); } +/* Check incore dquot for errors before we flush. */ +static xfs_failaddr_t +xfs_qm_dqflush_check( + struct xfs_dquot *dqp) +{ + if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) + return __this_address; + + return NULL; +} + /* * Write a modified dquot to disk. * The dquot must be locked and the flush lock too taken by caller. @@ -1166,8 +1187,16 @@ xfs_qm_dqflush( goto out_abort; } - /* This is the only portion of data that needs to persist */ - memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); + fa = xfs_qm_dqflush_check(dqp); + if (fa) { + xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", + be32_to_cpu(dqp->q_core.d_id), fa); + xfs_buf_relse(bp); + error = -EFSCORRUPTED; + goto out_abort; + } + + xfs_dquot_to_disk(ddqp, dqp); /* * Clear the dirty field and remember the flush lsn for later use. diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index 71e36c85e20b..1b1a4261a580 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h @@ -144,6 +144,8 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp) return false; } +void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp); + #define XFS_DQ_IS_LOCKED(dqp) (mutex_is_locked(&((dqp)->q_qlock))) #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index 349c92d26570..ff0ab65cf413 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c @@ -45,6 +45,7 @@ xfs_qm_dquot_logitem_format( struct xfs_log_item *lip, struct xfs_log_vec *lv) { + struct xfs_disk_dquot ddq; struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); struct xfs_log_iovec *vecp = NULL; struct xfs_dq_logformat *qlf; @@ -58,8 +59,9 @@ xfs_qm_dquot_logitem_format( qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset; xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat)); - xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, - &qlip->qli_dquot->q_core, + xfs_dquot_to_disk(&ddq, qlip->qli_dquot); + + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, &ddq, sizeof(struct xfs_disk_dquot)); } diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 938023dd8ce5..632025c2f00b 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -161,7 +161,7 @@ xfs_qm_dqpurge( xfs_dqfunlock(dqp); xfs_dqunlock(dqp); - radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags), + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), be32_to_cpu(dqp->q_core.d_id)); qi->qi_dquots--; @@ -1598,7 +1598,7 @@ xfs_qm_dqfree_one( struct xfs_quotainfo *qi = mp->m_quotainfo; mutex_lock(&qi->qi_tree_lock); - radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags), + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), be32_to_cpu(dqp->q_core.d_id)); qi->qi_dquots--; diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 7b0e771fcbce..43b4650cdcdf 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -85,7 +85,7 @@ xfs_dquot_tree( struct xfs_quotainfo *qi, int type) { - switch (type) { + switch (type & XFS_DQ_ALLTYPES) { case XFS_DQ_USER: return &qi->qi_uquota_tree; case XFS_DQ_GROUP: diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 7effd7a28136..8cbb65f01bf1 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -644,12 +644,9 @@ xfs_qm_scall_getquota_fill_qc( * gets turned off. No need to confuse the user level code, * so return zeroes in that case. */ - if ((!XFS_IS_UQUOTA_ENFORCED(mp) && - dqp->q_core.d_flags == XFS_DQ_USER) || - (!XFS_IS_GQUOTA_ENFORCED(mp) && - dqp->q_core.d_flags == XFS_DQ_GROUP) || - (!XFS_IS_PQUOTA_ENFORCED(mp) && - dqp->q_core.d_flags == XFS_DQ_PROJ)) { + if ((!XFS_IS_UQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_USER)) || + (!XFS_IS_GQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_GROUP)) || + (!XFS_IS_PQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_PROJ))) { dst->d_spc_timer = 0; dst->d_ino_timer = 0; dst->d_rt_spc_timer = 0;
From: Darrick J. Wong <darrick.wong@oracle.com> Add a dquot id field to the incore dquot, and use that instead of the one in qcore. This eliminates a bunch of endian conversions and will eventually allow us to remove qcore entirely. We also rearrange the start of xfs_dquot to remove padding holes, saving 8 bytes. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/scrub/quota.c | 19 ++++++++++++------- fs/xfs/xfs_dquot.c | 25 +++++++++++-------------- fs/xfs/xfs_dquot.h | 5 +++-- fs/xfs/xfs_dquot_item.c | 2 +- fs/xfs/xfs_qm.c | 22 ++++++++++------------ fs/xfs/xfs_qm_syscalls.c | 4 ++-- fs/xfs/xfs_trace.h | 2 +- fs/xfs/xfs_trans_dquot.c | 8 +++----- 8 files changed, 43 insertions(+), 44 deletions(-) diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c index 710659d3fa28..9a271f115882 100644 --- a/fs/xfs/scrub/quota.c +++ b/fs/xfs/scrub/quota.c @@ -92,7 +92,6 @@ xchk_quota_item( unsigned long long icount; unsigned long long rcount; xfs_ino_t fs_icount; - xfs_dqid_t id = be32_to_cpu(d->d_id); int error = 0; if (xchk_should_terminate(sc, &error)) @@ -102,11 +101,11 @@ xchk_quota_item( * Except for the root dquot, the actual dquot we got must either have * the same or higher id as we saw before. */ - offset = id / qi->qi_dqperchunk; - if (id && id <= sqi->last_id) + offset = dq->q_id / qi->qi_dqperchunk; + if (dq->q_id && dq->q_id <= sqi->last_id) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); - sqi->last_id = id; + sqi->last_id = dq->q_id; if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); @@ -171,13 +170,19 @@ xchk_quota_item( * lower limit than the actual usage. However, we flag it for * admin review. */ - if (id != 0 && bhard != 0 && bcount > bhard) + if (dq->q_id == 0) + goto out; + + if (bhard != 0 && bcount > bhard) xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); - if (id != 0 && ihard != 0 && icount > ihard) + + if (ihard != 0 && icount > ihard) xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); - if (id != 0 && rhard != 0 && rcount > rhard) + + if (rhard != 0 && rcount > rhard) xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); +out: if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return -EFSCORRUPTED; diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 59d1bce34a98..76b35888e726 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -74,7 +74,7 @@ xfs_qm_adjust_dqlimits( struct xfs_def_quota *defq; int prealloc = 0; - ASSERT(d->d_id); + ASSERT(dq->q_id); defq = xfs_get_defquota(q, xfs_dquot_type(dq)); if (defq->bsoftlimit && !d->d_blk_softlimit) { @@ -120,7 +120,7 @@ xfs_qm_adjust_dqtimers( struct xfs_disk_dquot *d = &dq->q_core; struct xfs_def_quota *defq; - ASSERT(d->d_id); + ASSERT(dq->q_id); defq = xfs_get_defquota(qi, xfs_dquot_type(dq)); #ifdef DEBUG @@ -365,7 +365,7 @@ xfs_dquot_disk_alloc( * Make a chunk of dquots out of this buffer and log * the entire thing. */ - xfs_qm_init_dquot_blk(tp, mp, be32_to_cpu(dqp->q_core.d_id), + xfs_qm_init_dquot_blk(tp, mp, dqp->q_id, dqp->dq_flags & XFS_DQ_ALLTYPES, bp); xfs_buf_set_ref(bp, XFS_DQUOT_REF); @@ -478,7 +478,7 @@ xfs_dquot_alloc( dqp = kmem_zone_zalloc(xfs_qm_dqzone, 0); dqp->dq_flags = type; - dqp->q_core.d_id = cpu_to_be32(id); + dqp->q_id = id; dqp->q_mount = mp; INIT_LIST_HEAD(&dqp->q_lru); mutex_init(&dqp->q_qlock); @@ -537,10 +537,10 @@ xfs_dquot_from_disk( */ if ((dqp->dq_flags & XFS_DQ_ALLTYPES) != (ddqp->d_flags & XFS_DQ_ALLTYPES) || - dqp->q_core.d_id != ddqp->d_id) { + dqp->q_id != be32_to_cpu(ddqp->d_id)) { xfs_alert(bp->b_mount, "Metadata corruption detected at %pS, quota %u", - __this_address, be32_to_cpu(dqp->q_core.d_id)); + __this_address, dqp->q_id); xfs_alert(bp->b_mount, "Unmount and run xfs_repair"); return -EFSCORRUPTED; } @@ -1177,11 +1177,10 @@ xfs_qm_dqflush( ddqp = &dqb->dd_diskdq; /* sanity check the in-core structure before we flush */ - fa = xfs_dquot_verify(mp, &dqp->q_core, be32_to_cpu(dqp->q_core.d_id), - 0); + fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0); if (fa) { xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", - be32_to_cpu(dqp->q_core.d_id), fa); + dqp->q_id, fa); xfs_buf_relse(bp); error = -EFSCORRUPTED; goto out_abort; @@ -1190,7 +1189,7 @@ xfs_qm_dqflush( fa = xfs_qm_dqflush_check(dqp); if (fa) { xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", - be32_to_cpu(dqp->q_core.d_id), fa); + dqp->q_id, fa); xfs_buf_relse(bp); error = -EFSCORRUPTED; goto out_abort; @@ -1263,8 +1262,7 @@ xfs_dqlock2( { if (d1 && d2) { ASSERT(d1 != d2); - if (be32_to_cpu(d1->q_core.d_id) > - be32_to_cpu(d2->q_core.d_id)) { + if (d1->q_id > d2->q_id) { mutex_lock(&d2->q_qlock); mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED); } else { @@ -1332,9 +1330,8 @@ xfs_qm_dqiterate( return error; error = iter_fn(dq, dqtype, priv); - id = be32_to_cpu(dq->q_core.d_id); + id = dq->q_id + 1; xfs_qm_dqput(dq); - id++; } while (error == 0 && id != 0); return error; diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index 1b1a4261a580..5ea1f1515979 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h @@ -31,12 +31,13 @@ enum { * The incore dquot structure */ struct xfs_dquot { - uint dq_flags; struct list_head q_lru; struct xfs_mount *q_mount; + xfs_dqid_t q_id; + uint dq_flags; uint q_nrefs; - xfs_daddr_t q_blkno; int q_bufoffset; + xfs_daddr_t q_blkno; xfs_fileoff_t q_fileoffset; struct xfs_disk_dquot q_core; diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index ff0ab65cf413..378d919997f1 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c @@ -53,7 +53,7 @@ xfs_qm_dquot_logitem_format( qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT); qlf->qlf_type = XFS_LI_DQUOT; qlf->qlf_size = 2; - qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id); + qlf->qlf_id = qlip->qli_dquot->q_id; qlf->qlf_blkno = qlip->qli_dquot->q_blkno; qlf->qlf_len = 1; qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset; diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 632025c2f00b..95e51186bd57 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -79,7 +79,7 @@ xfs_qm_dquot_walk( for (i = 0; i < nr_found; i++) { struct xfs_dquot *dqp = batch[i]; - next_index = be32_to_cpu(dqp->q_core.d_id) + 1; + next_index = dqp->q_id + 1; error = execute(batch[i], data); if (error == -EAGAIN) { @@ -161,8 +161,7 @@ xfs_qm_dqpurge( xfs_dqfunlock(dqp); xfs_dqunlock(dqp); - radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), - be32_to_cpu(dqp->q_core.d_id)); + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id); qi->qi_dquots--; /* @@ -1112,7 +1111,7 @@ xfs_qm_quotacheck_dqadjust( * * There are no timers for the default values set in the root dquot. */ - if (dqp->q_core.d_id) { + if (dqp->q_id) { xfs_qm_adjust_dqlimits(mp, dqp); xfs_qm_adjust_dqtimers(mp, dqp); } @@ -1598,8 +1597,7 @@ xfs_qm_dqfree_one( struct xfs_quotainfo *qi = mp->m_quotainfo; mutex_lock(&qi->qi_tree_lock); - radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), - be32_to_cpu(dqp->q_core.d_id)); + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id); qi->qi_dquots--; mutex_unlock(&qi->qi_tree_lock); @@ -1823,7 +1821,7 @@ xfs_qm_vop_chown_reserve( XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS; if (XFS_IS_UQUOTA_ON(mp) && udqp && - i_uid_read(VFS_I(ip)) != be32_to_cpu(udqp->q_core.d_id)) { + i_uid_read(VFS_I(ip)) != udqp->q_id) { udq_delblks = udqp; /* * If there are delayed allocation blocks, then we have to @@ -1836,7 +1834,7 @@ xfs_qm_vop_chown_reserve( } } if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp && - i_gid_read(VFS_I(ip)) != be32_to_cpu(gdqp->q_core.d_id)) { + i_gid_read(VFS_I(ip)) != gdqp->q_id) { gdq_delblks = gdqp; if (delblks) { ASSERT(ip->i_gdquot); @@ -1845,7 +1843,7 @@ xfs_qm_vop_chown_reserve( } if (XFS_IS_PQUOTA_ON(ip->i_mount) && pdqp && - ip->i_d.di_projid != be32_to_cpu(pdqp->q_core.d_id)) { + ip->i_d.di_projid != pdqp->q_id) { pdq_delblks = pdqp; if (delblks) { ASSERT(ip->i_pdquot); @@ -1929,21 +1927,21 @@ xfs_qm_vop_create_dqattach( if (udqp && XFS_IS_UQUOTA_ON(mp)) { ASSERT(ip->i_udquot == NULL); - ASSERT(i_uid_read(VFS_I(ip)) == be32_to_cpu(udqp->q_core.d_id)); + ASSERT(i_uid_read(VFS_I(ip)) == udqp->q_id); ip->i_udquot = xfs_qm_dqhold(udqp); xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1); } if (gdqp && XFS_IS_GQUOTA_ON(mp)) { ASSERT(ip->i_gdquot == NULL); - ASSERT(i_gid_read(VFS_I(ip)) == be32_to_cpu(gdqp->q_core.d_id)); + ASSERT(i_gid_read(VFS_I(ip)) == gdqp->q_id); ip->i_gdquot = xfs_qm_dqhold(gdqp); xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1); } if (pdqp && XFS_IS_PQUOTA_ON(mp)) { ASSERT(ip->i_pdquot == NULL); - ASSERT(ip->i_d.di_projid == be32_to_cpu(pdqp->q_core.d_id)); + ASSERT(ip->i_d.di_projid == pdqp->q_id); ip->i_pdquot = xfs_qm_dqhold(pdqp); xfs_trans_mod_dquot(tp, pdqp, XFS_TRANS_DQ_ICOUNT, 1); diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 8cbb65f01bf1..90a11e7daf92 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -656,7 +656,7 @@ xfs_qm_scall_getquota_fill_qc( if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) || (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) || (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) && - dqp->q_core.d_id != 0) { + dqp->q_id != 0) { if ((dst->d_space > dst->d_spc_softlimit) && (dst->d_spc_softlimit > 0)) { ASSERT(dst->d_spc_timer != 0); @@ -723,7 +723,7 @@ xfs_qm_scall_getquota_next( return error; /* Fill in the ID we actually read from disk */ - *id = be32_to_cpu(dqp->q_core.d_id); + *id = dqp->q_id; xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 2c5df8315351..78d9dbc7614d 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -876,7 +876,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, ), \ TP_fast_assign( __entry->dev = dqp->q_mount->m_super->s_dev; - __entry->id = be32_to_cpu(dqp->q_core.d_id); + __entry->id = dqp->q_id; __entry->flags = dqp->dq_flags; __entry->nrefs = dqp->q_nrefs; __entry->res_bcount = dqp->q_res_bcount; diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index ed0ce8b301b4..a2656ec6ea76 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -386,7 +386,7 @@ xfs_trans_apply_dquot_deltas( * Get any default limits in use. * Start/reset the timer(s) if needed. */ - if (d->d_id) { + if (dqp->q_id) { xfs_qm_adjust_dqlimits(tp->t_mountp, dqp); xfs_qm_adjust_dqtimers(tp->t_mountp, dqp); } @@ -558,8 +558,7 @@ xfs_quota_warn( else qtype = GRPQUOTA; - quota_send_warning(make_kqid(&init_user_ns, qtype, - be32_to_cpu(dqp->q_core.d_id)), + quota_send_warning(make_kqid(&init_user_ns, qtype, dqp->q_id), mp->m_super->s_dev, type); } @@ -618,8 +617,7 @@ xfs_trans_dqresv( resbcountp = &dqp->q_res_rtbcount; } - if ((flags & XFS_QMOPT_FORCE_RES) == 0 && - dqp->q_core.d_id && + if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_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)))) {
From: Darrick J. Wong <darrick.wong@oracle.com> Introduce a new struct xfs_dquot_res that we'll use to track all the incore data for a particular resource type (block, inode, rt block). This will help us (once we've eliminated q_core) to declutter quota functions that currently open-code field access or pass around fields around explicitly. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_dquot.c | 6 +++--- fs/xfs/xfs_dquot.h | 18 +++++++++++------- fs/xfs/xfs_iomap.c | 6 +++--- fs/xfs/xfs_qm.c | 6 +++--- fs/xfs/xfs_qm_bhv.c | 8 ++++---- fs/xfs/xfs_qm_syscalls.c | 6 +++--- fs/xfs/xfs_trace.h | 2 +- fs/xfs/xfs_trans_dquot.c | 42 +++++++++++++++++++++--------------------- 8 files changed, 49 insertions(+), 45 deletions(-) diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 76b35888e726..03624a8f0566 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -552,9 +552,9 @@ xfs_dquot_from_disk( * Reservation counters are defined as reservation plus current usage * to avoid having to add every time. */ - dqp->q_res_bcount = be64_to_cpu(ddqp->d_bcount); - dqp->q_res_icount = be64_to_cpu(ddqp->d_icount); - dqp->q_res_rtbcount = be64_to_cpu(ddqp->d_rtbcount); + dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount); + dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount); + dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount); /* initialize the dquot speculative prealloc thresholds */ xfs_dquot_set_prealloc_limits(dqp); diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index 5ea1f1515979..cb20df1e774f 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h @@ -27,6 +27,11 @@ enum { XFS_QLOWSP_MAX }; +struct xfs_dquot_res { + /* Total resources allocated and reserved. */ + xfs_qcnt_t reserved; +}; + /* * The incore dquot structure */ @@ -40,14 +45,13 @@ struct xfs_dquot { xfs_daddr_t q_blkno; xfs_fileoff_t q_fileoffset; + struct xfs_dquot_res q_blk; /* regular blocks */ + struct xfs_dquot_res q_ino; /* inodes */ + struct xfs_dquot_res q_rtb; /* realtime blocks */ + struct xfs_disk_dquot q_core; struct xfs_dq_logitem q_logitem; - /* total regular nblks used+reserved */ - xfs_qcnt_t q_res_bcount; - /* total inos allocd+reserved */ - xfs_qcnt_t q_res_icount; - /* total realtime blks used+reserved */ - xfs_qcnt_t q_res_rtbcount; + xfs_qcnt_t q_prealloc_lo_wmark; xfs_qcnt_t q_prealloc_hi_wmark; int64_t q_low_space[XFS_QLOWSP_MAX]; @@ -138,7 +142,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_res_bcount; + freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_blk.reserved; if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT]) return true; diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index b9a8c3798e08..f60a6e44363b 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -307,7 +307,7 @@ xfs_quota_need_throttle( return false; /* under the lo watermark, no throttle */ - if (dq->q_res_bcount + alloc_blocks < dq->q_prealloc_lo_wmark) + if (dq->q_blk.reserved + alloc_blocks < dq->q_prealloc_lo_wmark) return false; return true; @@ -326,13 +326,13 @@ xfs_quota_calc_throttle( struct xfs_dquot *dq = xfs_inode_dquot(ip, type); /* no dq, or over hi wmark, squash the prealloc completely */ - if (!dq || dq->q_res_bcount >= dq->q_prealloc_hi_wmark) { + if (!dq || dq->q_blk.reserved >= dq->q_prealloc_hi_wmark) { *qblocks = 0; *qfreesp = 0; return; } - freesp = dq->q_prealloc_hi_wmark - dq->q_res_bcount; + freesp = dq->q_prealloc_hi_wmark - dq->q_blk.reserved; if (freesp < dq->q_low_space[XFS_QLOWSP_5_PCNT]) { shift = 2; if (freesp < dq->q_low_space[XFS_QLOWSP_3_PCNT]) diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 95e51186bd57..6ce3a4402041 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -1096,14 +1096,14 @@ xfs_qm_quotacheck_dqadjust( * resource usage. */ be64_add_cpu(&dqp->q_core.d_icount, 1); - dqp->q_res_icount++; + dqp->q_ino.reserved++; if (nblks) { be64_add_cpu(&dqp->q_core.d_bcount, nblks); - dqp->q_res_bcount += nblks; + dqp->q_blk.reserved += nblks; } if (rtblks) { be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks); - dqp->q_res_rtbcount += rtblks; + dqp->q_rtb.reserved += rtblks; } /* diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c index fc2fa418919f..94b2b4b0fc17 100644 --- a/fs/xfs/xfs_qm_bhv.c +++ b/fs/xfs/xfs_qm_bhv.c @@ -29,8 +29,8 @@ xfs_fill_statvfs_from_dquot( if (limit && statp->f_blocks > limit) { statp->f_blocks = limit; statp->f_bfree = statp->f_bavail = - (statp->f_blocks > dqp->q_res_bcount) ? - (statp->f_blocks - dqp->q_res_bcount) : 0; + (statp->f_blocks > dqp->q_blk.reserved) ? + (statp->f_blocks - dqp->q_blk.reserved) : 0; } limit = dqp->q_core.d_ino_softlimit ? @@ -39,8 +39,8 @@ xfs_fill_statvfs_from_dquot( if (limit && statp->f_files > limit) { statp->f_files = limit; statp->f_ffree = - (statp->f_files > dqp->q_res_icount) ? - (statp->f_files - dqp->q_res_icount) : 0; + (statp->f_files > dqp->q_ino.reserved) ? + (statp->f_files - dqp->q_ino.reserved) : 0; } } diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 90a11e7daf92..56fe80395679 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -625,8 +625,8 @@ xfs_qm_scall_getquota_fill_qc( XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit)); dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); - dst->d_space = XFS_FSB_TO_B(mp, dqp->q_res_bcount); - dst->d_ino_count = dqp->q_res_icount; + dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); + dst->d_ino_count = dqp->q_ino.reserved; dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); @@ -635,7 +635,7 @@ xfs_qm_scall_getquota_fill_qc( XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit)); dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit)); - dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_res_rtbcount); + dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 78d9dbc7614d..71567ed367f2 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -879,7 +879,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, __entry->id = dqp->q_id; __entry->flags = dqp->dq_flags; __entry->nrefs = dqp->q_nrefs; - __entry->res_bcount = dqp->q_res_bcount; + __entry->res_bcount = dqp->q_blk.reserved; __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); __entry->icount = be64_to_cpu(dqp->q_core.d_icount); __entry->blk_hardlimit = diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index a2656ec6ea76..469bf7946d3d 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -409,11 +409,11 @@ xfs_trans_apply_dquot_deltas( if (qtrx->qt_blk_res != blk_res_used) { if (qtrx->qt_blk_res > blk_res_used) - dqp->q_res_bcount -= (xfs_qcnt_t) + dqp->q_blk.reserved -= (xfs_qcnt_t) (qtrx->qt_blk_res - blk_res_used); else - dqp->q_res_bcount -= (xfs_qcnt_t) + dqp->q_blk.reserved -= (xfs_qcnt_t) (blk_res_used - qtrx->qt_blk_res); } @@ -426,7 +426,7 @@ xfs_trans_apply_dquot_deltas( * deliberately skip quota reservations. */ if (qtrx->qt_bcount_delta) { - dqp->q_res_bcount += + dqp->q_blk.reserved += (xfs_qcnt_t)qtrx->qt_bcount_delta; } } @@ -437,17 +437,17 @@ xfs_trans_apply_dquot_deltas( if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) { if (qtrx->qt_rtblk_res > qtrx->qt_rtblk_res_used) - dqp->q_res_rtbcount -= (xfs_qcnt_t) + dqp->q_rtb.reserved -= (xfs_qcnt_t) (qtrx->qt_rtblk_res - qtrx->qt_rtblk_res_used); else - dqp->q_res_rtbcount -= (xfs_qcnt_t) + dqp->q_rtb.reserved -= (xfs_qcnt_t) (qtrx->qt_rtblk_res_used - qtrx->qt_rtblk_res); } } else { if (qtrx->qt_rtbcount_delta) - dqp->q_res_rtbcount += + dqp->q_rtb.reserved += (xfs_qcnt_t)qtrx->qt_rtbcount_delta; } @@ -458,20 +458,20 @@ xfs_trans_apply_dquot_deltas( ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used); if (qtrx->qt_ino_res > qtrx->qt_ino_res_used) - dqp->q_res_icount -= (xfs_qcnt_t) + dqp->q_ino.reserved -= (xfs_qcnt_t) (qtrx->qt_ino_res - qtrx->qt_ino_res_used); } else { if (qtrx->qt_icount_delta) - dqp->q_res_icount += + dqp->q_ino.reserved += (xfs_qcnt_t)qtrx->qt_icount_delta; } - ASSERT(dqp->q_res_bcount >= + ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount)); - ASSERT(dqp->q_res_icount >= + ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount)); - ASSERT(dqp->q_res_rtbcount >= + ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount)); } } @@ -516,7 +516,7 @@ xfs_trans_unreserve_and_mod_dquots( if (qtrx->qt_blk_res) { xfs_dqlock(dqp); locked = true; - dqp->q_res_bcount -= + dqp->q_blk.reserved -= (xfs_qcnt_t)qtrx->qt_blk_res; } if (qtrx->qt_ino_res) { @@ -524,7 +524,7 @@ xfs_trans_unreserve_and_mod_dquots( xfs_dqlock(dqp); locked = true; } - dqp->q_res_icount -= + dqp->q_ino.reserved -= (xfs_qcnt_t)qtrx->qt_ino_res; } @@ -533,7 +533,7 @@ xfs_trans_unreserve_and_mod_dquots( xfs_dqlock(dqp); locked = true; } - dqp->q_res_rtbcount -= + dqp->q_rtb.reserved -= (xfs_qcnt_t)qtrx->qt_rtblk_res; } if (locked) @@ -602,7 +602,7 @@ xfs_trans_dqresv( timer = be32_to_cpu(dqp->q_core.d_btimer); warns = be16_to_cpu(dqp->q_core.d_bwarns); warnlimit = defq->bwarnlimit; - resbcountp = &dqp->q_res_bcount; + resbcountp = &dqp->q_blk.reserved; } else { ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit); @@ -614,7 +614,7 @@ xfs_trans_dqresv( timer = be32_to_cpu(dqp->q_core.d_rtbtimer); warns = be16_to_cpu(dqp->q_core.d_rtbwarns); warnlimit = defq->rtbwarnlimit; - resbcountp = &dqp->q_res_rtbcount; + resbcountp = &dqp->q_rtb.reserved; } if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id && @@ -675,11 +675,11 @@ xfs_trans_dqresv( /* * Change the reservation, but not the actual usage. - * Note that q_res_bcount = q_core.d_bcount + resv + * Note that q_blk.reserved = q_core.d_bcount + resv */ (*resbcountp) += (xfs_qcnt_t)nblks; if (ninos != 0) - dqp->q_res_icount += (xfs_qcnt_t)ninos; + dqp->q_ino.reserved += (xfs_qcnt_t)ninos; /* * note the reservation amt in the trans struct too, @@ -700,9 +700,9 @@ xfs_trans_dqresv( 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)); + ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount)); + ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount)); + ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount)); xfs_dqunlock(dqp); return 0;
From: Darrick J. Wong <darrick.wong@oracle.com> 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: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/scrub/quota.c | 36 ++++-------- fs/xfs/xfs_dquot.c | 136 ++++++++++++++++++++++++++-------------------- fs/xfs/xfs_dquot.h | 6 ++ fs/xfs/xfs_qm.c | 14 ++--- fs/xfs/xfs_qm.h | 12 ++-- fs/xfs/xfs_qm_bhv.c | 12 ++-- fs/xfs/xfs_qm_syscalls.c | 40 ++++++-------- fs/xfs/xfs_trace.h | 12 +--- fs/xfs/xfs_trans_dquot.c | 12 ++-- 9 files changed, 139 insertions(+), 141 deletions(-) diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c index 9a271f115882..1a1c6996fc69 100644 --- a/fs/xfs/scrub/quota.c +++ b/fs/xfs/scrub/quota.c @@ -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; @@ -110,15 +104,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 @@ -127,19 +112,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. */ @@ -173,13 +158,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: diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 03624a8f0566..63f744bcbc90 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -70,29 +70,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); @@ -124,82 +123,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; } } @@ -290,8 +274,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 @@ -569,6 +559,12 @@ xfs_dquot_to_disk( { memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK; + 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. */ @@ -1123,9 +1119,29 @@ static xfs_failaddr_t xfs_qm_dqflush_check( struct xfs_dquot *dqp) { + struct xfs_disk_dquot *ddq = &dqp->q_core; + if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) 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; } diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index cb20df1e774f..edb49788c476 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h @@ -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; }; /* @@ -142,7 +146,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; diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 6ce3a4402041..54fc3aac1a68 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -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); } diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 43b4650cdcdf..84cb8af468b7 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -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) diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c index 94b2b4b0fc17..0993217e5ac8 100644 --- a/fs/xfs/xfs_qm_bhv.c +++ b/fs/xfs/xfs_qm_bhv.c @@ -23,9 +23,9 @@ xfs_fill_statvfs_from_dquot( { uint64_t limit; - limit = dqp->q_core.d_blk_softlimit ? - be64_to_cpu(dqp->q_core.d_blk_softlimit) : - be64_to_cpu(dqp->q_core.d_blk_hardlimit); + limit = dqp->q_blk.softlimit ? + dqp->q_blk.softlimit : + dqp->q_blk.hardlimit; if (limit && statp->f_blocks > limit) { statp->f_blocks = limit; statp->f_bfree = statp->f_bavail = @@ -33,9 +33,9 @@ xfs_fill_statvfs_from_dquot( (statp->f_blocks - dqp->q_blk.reserved) : 0; } - limit = dqp->q_core.d_ino_softlimit ? - be64_to_cpu(dqp->q_core.d_ino_softlimit) : - be64_to_cpu(dqp->q_core.d_ino_hardlimit); + limit = dqp->q_ino.softlimit ? + dqp->q_ino.softlimit : + dqp->q_ino.hardlimit; if (limit && statp->f_files > limit) { statp->f_files = limit; statp->f_ffree = diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 56fe80395679..ab596d389e3e 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -495,13 +495,13 @@ xfs_qm_scall_setqlim( */ hard = (newlim->d_fieldmask & QC_SPC_HARD) ? (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : - be64_to_cpu(ddq->d_blk_hardlimit); + dqp->q_blk.hardlimit; soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : - be64_to_cpu(ddq->d_blk_softlimit); + dqp->q_blk.softlimit; if (hard == 0 || hard >= soft) { - ddq->d_blk_hardlimit = cpu_to_be64(hard); - ddq->d_blk_softlimit = cpu_to_be64(soft); + dqp->q_blk.hardlimit = hard; + dqp->q_blk.softlimit = soft; xfs_dquot_set_prealloc_limits(dqp); if (id == 0) { defq->bhardlimit = hard; @@ -512,13 +512,13 @@ xfs_qm_scall_setqlim( } hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : - be64_to_cpu(ddq->d_rtb_hardlimit); + dqp->q_rtb.hardlimit; soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : - be64_to_cpu(ddq->d_rtb_softlimit); + dqp->q_rtb.softlimit; if (hard == 0 || hard >= soft) { - ddq->d_rtb_hardlimit = cpu_to_be64(hard); - ddq->d_rtb_softlimit = cpu_to_be64(soft); + dqp->q_rtb.hardlimit = hard; + dqp->q_rtb.softlimit = soft; if (id == 0) { defq->rtbhardlimit = hard; defq->rtbsoftlimit = soft; @@ -529,13 +529,13 @@ xfs_qm_scall_setqlim( hard = (newlim->d_fieldmask & QC_INO_HARD) ? (xfs_qcnt_t) newlim->d_ino_hardlimit : - be64_to_cpu(ddq->d_ino_hardlimit); + dqp->q_ino.hardlimit; soft = (newlim->d_fieldmask & QC_INO_SOFT) ? (xfs_qcnt_t) newlim->d_ino_softlimit : - be64_to_cpu(ddq->d_ino_softlimit); + dqp->q_ino.softlimit; if (hard == 0 || hard >= soft) { - ddq->d_ino_hardlimit = cpu_to_be64(hard); - ddq->d_ino_softlimit = cpu_to_be64(soft); + dqp->q_ino.hardlimit = hard; + dqp->q_ino.softlimit = soft; if (id == 0) { defq->ihardlimit = hard; defq->isoftlimit = soft; @@ -619,10 +619,8 @@ xfs_qm_scall_getquota_fill_qc( struct qc_dqblk *dst) { memset(dst, 0, sizeof(*dst)); - dst->d_spc_hardlimit = - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit)); - dst->d_spc_softlimit = - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit)); + dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit); + dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit); dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); @@ -631,10 +629,8 @@ xfs_qm_scall_getquota_fill_qc( dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns); - dst->d_rt_spc_hardlimit = - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit)); - dst->d_rt_spc_softlimit = - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit)); + dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); + dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); @@ -661,8 +657,8 @@ xfs_qm_scall_getquota_fill_qc( (dst->d_spc_softlimit > 0)) { ASSERT(dst->d_spc_timer != 0); } - if ((dst->d_ino_count > dst->d_ino_softlimit) && - (dst->d_ino_softlimit > 0)) { + if ((dst->d_ino_count > dqp->q_ino.softlimit) && + (dqp->q_ino.softlimit > 0)) { ASSERT(dst->d_ino_timer != 0); } } diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 71567ed367f2..7f744a37dc0e 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -882,14 +882,10 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, __entry->res_bcount = dqp->q_blk.reserved; __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); __entry->icount = be64_to_cpu(dqp->q_core.d_icount); - __entry->blk_hardlimit = - be64_to_cpu(dqp->q_core.d_blk_hardlimit); - __entry->blk_softlimit = - be64_to_cpu(dqp->q_core.d_blk_softlimit); - __entry->ino_hardlimit = - be64_to_cpu(dqp->q_core.d_ino_hardlimit); - __entry->ino_softlimit = - be64_to_cpu(dqp->q_core.d_ino_softlimit); + __entry->blk_hardlimit = dqp->q_blk.hardlimit; + __entry->blk_softlimit = dqp->q_blk.softlimit; + __entry->ino_hardlimit = dqp->q_ino.hardlimit; + __entry->ino_softlimit = dqp->q_ino.softlimit; ), TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx " "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx " diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 469bf7946d3d..7a3d64eb9fbf 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -593,10 +593,10 @@ xfs_trans_dqresv( defq = xfs_get_defquota(q, xfs_dquot_type(dqp)); if (flags & XFS_TRANS_DQ_RES_BLKS) { - hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit); + hardlimit = dqp->q_blk.hardlimit; if (!hardlimit) hardlimit = defq->bhardlimit; - softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit); + softlimit = dqp->q_blk.softlimit; if (!softlimit) softlimit = defq->bsoftlimit; timer = be32_to_cpu(dqp->q_core.d_btimer); @@ -605,10 +605,10 @@ xfs_trans_dqresv( resbcountp = &dqp->q_blk.reserved; } else { ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); - hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit); + hardlimit = dqp->q_rtb.hardlimit; if (!hardlimit) hardlimit = defq->rtbhardlimit; - softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit); + softlimit = dqp->q_rtb.softlimit; if (!softlimit) softlimit = defq->rtbsoftlimit; timer = be32_to_cpu(dqp->q_core.d_rtbtimer); @@ -649,10 +649,10 @@ xfs_trans_dqresv( timer = be32_to_cpu(dqp->q_core.d_itimer); warns = be16_to_cpu(dqp->q_core.d_iwarns); warnlimit = defq->iwarnlimit; - hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); + hardlimit = dqp->q_ino.hardlimit; if (!hardlimit) hardlimit = defq->ihardlimit; - softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); + softlimit = dqp->q_ino.softlimit; if (!softlimit) softlimit = defq->isoftlimit;
From: Darrick J. Wong <darrick.wong@oracle.com> Add counter fields to 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: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/scrub/quota.c | 18 ++++++------------ fs/xfs/xfs_dquot.c | 47 +++++++++++++++++++++++++--------------------- fs/xfs/xfs_dquot.h | 3 +++ fs/xfs/xfs_qm.c | 6 +++--- fs/xfs/xfs_qm.h | 6 +++--- fs/xfs/xfs_trace.h | 4 ++-- fs/xfs/xfs_trans_dquot.c | 36 ++++++++++++++--------------------- 7 files changed, 57 insertions(+), 63 deletions(-) diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c index 1a1c6996fc69..2fc2625feca0 100644 --- a/fs/xfs/scrub/quota.c +++ b/fs/xfs/scrub/quota.c @@ -82,9 +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 bcount; - unsigned long long icount; - unsigned long long rcount; xfs_ino_t fs_icount; int error = 0; @@ -128,9 +125,6 @@ xchk_quota_item( xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); /* Check the resource counts. */ - bcount = be64_to_cpu(d->d_bcount); - icount = be64_to_cpu(d->d_icount); - rcount = be64_to_cpu(d->d_rtbcount); fs_icount = percpu_counter_sum(&mp->m_icount); /* @@ -139,15 +133,15 @@ xchk_quota_item( * if there are no quota limits. */ if (xfs_sb_version_hasreflink(&mp->m_sb)) { - if (mp->m_sb.sb_dblocks < bcount) + if (mp->m_sb.sb_dblocks < dq->q_blk.count) xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); } else { - if (mp->m_sb.sb_dblocks < bcount) + if (mp->m_sb.sb_dblocks < dq->q_blk.count) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); } - if (icount > fs_icount || rcount > mp->m_sb.sb_rblocks) + if (dq->q_ino.count > fs_icount || dq->q_rtb.count > mp->m_sb.sb_rblocks) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); /* @@ -159,15 +153,15 @@ xchk_quota_item( goto out; if (dq->q_blk.hardlimit != 0 && - bcount > dq->q_blk.hardlimit) + dq->q_blk.count > dq->q_blk.hardlimit) xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); if (dq->q_ino.hardlimit != 0 && - icount > dq->q_ino.hardlimit) + dq->q_ino.count > dq->q_ino.hardlimit) xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); if (dq->q_rtb.hardlimit != 0 && - rcount > dq->q_rtb.hardlimit) + dq->q_rtb.count > dq->q_rtb.hardlimit) xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); out: diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 63f744bcbc90..02eae8c2ba1b 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -133,9 +133,9 @@ xfs_qm_adjust_dqtimers( if (!d->d_btimer) { if ((dq->q_blk.softlimit && - (be64_to_cpu(d->d_bcount) > dq->q_blk.softlimit)) || + (dq->q_blk.count > dq->q_blk.softlimit)) || (dq->q_blk.hardlimit && - (be64_to_cpu(d->d_bcount) > dq->q_blk.hardlimit))) { + (dq->q_blk.count > dq->q_blk.hardlimit))) { d->d_btimer = cpu_to_be32(ktime_get_real_seconds() + defq->btimelimit); } else { @@ -143,18 +143,18 @@ xfs_qm_adjust_dqtimers( } } else { if ((!dq->q_blk.softlimit || - (be64_to_cpu(d->d_bcount) <= dq->q_blk.softlimit)) && + (dq->q_blk.count <= dq->q_blk.softlimit)) && (!dq->q_blk.hardlimit || - (be64_to_cpu(d->d_bcount) <= dq->q_blk.hardlimit))) { + (dq->q_blk.count <= dq->q_blk.hardlimit))) { d->d_btimer = 0; } } if (!d->d_itimer) { if ((dq->q_ino.softlimit && - (be64_to_cpu(d->d_icount) > dq->q_ino.softlimit)) || + (dq->q_ino.count > dq->q_ino.softlimit)) || (dq->q_ino.hardlimit && - (be64_to_cpu(d->d_icount) > dq->q_ino.hardlimit))) { + (dq->q_ino.count > dq->q_ino.hardlimit))) { d->d_itimer = cpu_to_be32(ktime_get_real_seconds() + defq->itimelimit); } else { @@ -162,18 +162,18 @@ xfs_qm_adjust_dqtimers( } } else { if ((!dq->q_ino.softlimit || - (be64_to_cpu(d->d_icount) <= dq->q_ino.softlimit)) && + (dq->q_ino.count <= dq->q_ino.softlimit)) && (!dq->q_ino.hardlimit || - (be64_to_cpu(d->d_icount) <= dq->q_ino.hardlimit))) { + (dq->q_ino.count <= dq->q_ino.hardlimit))) { d->d_itimer = 0; } } if (!d->d_rtbtimer) { if ((dq->q_rtb.softlimit && - (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.softlimit)) || + (dq->q_rtb.count > dq->q_rtb.softlimit)) || (dq->q_rtb.hardlimit && - (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.hardlimit))) { + (dq->q_rtb.count > dq->q_rtb.hardlimit))) { d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() + defq->rtbtimelimit); } else { @@ -181,9 +181,9 @@ xfs_qm_adjust_dqtimers( } } else { if ((!dq->q_rtb.softlimit || - (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.softlimit)) && + (dq->q_rtb.count <= dq->q_rtb.softlimit)) && (!dq->q_rtb.hardlimit || - (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.hardlimit))) { + (dq->q_rtb.count <= dq->q_rtb.hardlimit))) { d->d_rtbtimer = 0; } } @@ -538,13 +538,17 @@ xfs_dquot_from_disk( dqp->q_rtb.hardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit); dqp->q_rtb.softlimit = be64_to_cpu(ddqp->d_rtb_softlimit); + dqp->q_blk.count = be64_to_cpu(ddqp->d_bcount); + dqp->q_ino.count = be64_to_cpu(ddqp->d_icount); + dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount); + /* * Reservation counters are defined as reservation plus current usage * to avoid having to add every time. */ - dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount); - dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount); - dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount); + dqp->q_blk.reserved = dqp->q_blk.count; + dqp->q_ino.reserved = dqp->q_ino.count; + dqp->q_rtb.reserved = dqp->q_rtb.count; /* initialize the dquot speculative prealloc thresholds */ xfs_dquot_set_prealloc_limits(dqp); @@ -565,6 +569,10 @@ xfs_dquot_to_disk( 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); + + ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count); + ddqp->d_icount = cpu_to_be64(dqp->q_ino.count); + ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count); } /* Allocate and initialize the dquot buffer for this in-core dquot. */ @@ -1127,18 +1135,15 @@ xfs_qm_dqflush_check( if (dqp->q_id == 0) return NULL; - if (dqp->q_blk.softlimit && - be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit && + if (dqp->q_blk.softlimit && dqp->q_blk.count > 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 && + if (dqp->q_ino.softlimit && dqp->q_ino.count > 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 && + if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit && !ddq->d_rtbtimer) return __this_address; diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index edb49788c476..23e05b0d7567 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h @@ -31,6 +31,9 @@ struct xfs_dquot_res { /* Total resources allocated and reserved. */ xfs_qcnt_t reserved; + /* Total resources allocated. */ + xfs_qcnt_t count; + /* Absolute and preferred limits. */ xfs_qcnt_t hardlimit; xfs_qcnt_t softlimit; diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 54fc3aac1a68..b47bba204240 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -1093,14 +1093,14 @@ xfs_qm_quotacheck_dqadjust( * Adjust the inode count and the block count to reflect this inode's * resource usage. */ - be64_add_cpu(&dqp->q_core.d_icount, 1); + dqp->q_ino.count++; dqp->q_ino.reserved++; if (nblks) { - be64_add_cpu(&dqp->q_core.d_bcount, nblks); + dqp->q_blk.count += nblks; dqp->q_blk.reserved += nblks; } if (rtblks) { - be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks); + dqp->q_rtb.count += rtblks; dqp->q_rtb.reserved += rtblks; } diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 84cb8af468b7..6ed4ae942603 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -26,9 +26,9 @@ extern struct kmem_zone *xfs_qm_dqtrxzone; !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) + !dqp->q_blk.count && \ + !dqp->q_rtb.count && \ + !dqp->q_ino.count) /* * This defines the unit of allocation of dquots. diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 7f744a37dc0e..851f97dfe9e3 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -880,8 +880,8 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, __entry->flags = dqp->dq_flags; __entry->nrefs = dqp->q_nrefs; __entry->res_bcount = dqp->q_blk.reserved; - __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); - __entry->icount = be64_to_cpu(dqp->q_core.d_icount); + __entry->bcount = dqp->q_blk.count; + __entry->icount = dqp->q_ino.count; __entry->blk_hardlimit = dqp->q_blk.hardlimit; __entry->blk_softlimit = dqp->q_blk.softlimit; __entry->ino_hardlimit = dqp->q_ino.hardlimit; diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 7a3d64eb9fbf..b36d747989a7 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -309,7 +309,6 @@ xfs_trans_apply_dquot_deltas( int i, j; struct xfs_dquot *dqp; struct xfs_dqtrx *qtrx, *qa; - struct xfs_disk_dquot *d; int64_t totalbdelta; int64_t totalrtbdelta; @@ -341,7 +340,6 @@ xfs_trans_apply_dquot_deltas( /* * adjust the actual number of blocks used */ - d = &dqp->q_core; /* * The issue here is - sometimes we don't make a blkquota @@ -362,25 +360,22 @@ xfs_trans_apply_dquot_deltas( qtrx->qt_delrtb_delta; #ifdef DEBUG if (totalbdelta < 0) - ASSERT(be64_to_cpu(d->d_bcount) >= - -totalbdelta); + ASSERT(dqp->q_blk.count >= -totalbdelta); if (totalrtbdelta < 0) - ASSERT(be64_to_cpu(d->d_rtbcount) >= - -totalrtbdelta); + ASSERT(dqp->q_rtb.count >= -totalrtbdelta); if (qtrx->qt_icount_delta < 0) - ASSERT(be64_to_cpu(d->d_icount) >= - -qtrx->qt_icount_delta); + ASSERT(dqp->q_ino.count >= -qtrx->qt_icount_delta); #endif if (totalbdelta) - be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta); + dqp->q_blk.count += totalbdelta; if (qtrx->qt_icount_delta) - be64_add_cpu(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta); + dqp->q_ino.count += qtrx->qt_icount_delta; if (totalrtbdelta) - be64_add_cpu(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta); + dqp->q_rtb.count += totalrtbdelta; /* * Get any default limits in use. @@ -467,12 +462,9 @@ xfs_trans_apply_dquot_deltas( (xfs_qcnt_t)qtrx->qt_icount_delta; } - ASSERT(dqp->q_blk.reserved >= - be64_to_cpu(dqp->q_core.d_bcount)); - ASSERT(dqp->q_ino.reserved >= - be64_to_cpu(dqp->q_core.d_icount)); - ASSERT(dqp->q_rtb.reserved >= - be64_to_cpu(dqp->q_core.d_rtbcount)); + ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count); + ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count); + ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count); } } } @@ -645,7 +637,7 @@ xfs_trans_dqresv( } } if (ninos > 0) { - total_count = dqp->q_res_icount + ninos; + total_count = dqp->q_ino.reserved + ninos; timer = be32_to_cpu(dqp->q_core.d_itimer); warns = be16_to_cpu(dqp->q_core.d_iwarns); warnlimit = defq->iwarnlimit; @@ -675,7 +667,7 @@ xfs_trans_dqresv( /* * Change the reservation, but not the actual usage. - * Note that q_blk.reserved = q_core.d_bcount + resv + * Note that q_blk.reserved = q_blk.count + resv */ (*resbcountp) += (xfs_qcnt_t)nblks; if (ninos != 0) @@ -700,9 +692,9 @@ xfs_trans_dqresv( XFS_TRANS_DQ_RES_INOS, ninos); } - ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount)); - ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount)); - ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount)); + ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count); + ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count); + ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count); xfs_dqunlock(dqp); return 0;
From: Darrick J. Wong <darrick.wong@oracle.com> Add warning counter fields to 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: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_dquot.c | 14 +++++++++++--- fs/xfs/xfs_dquot.h | 8 ++++++++ fs/xfs/xfs_qm.c | 12 ++++++------ fs/xfs/xfs_qm_syscalls.c | 12 ++++++------ fs/xfs/xfs_trans_dquot.c | 6 +++--- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 02eae8c2ba1b..a1edb49ceda5 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -139,7 +139,7 @@ xfs_qm_adjust_dqtimers( d->d_btimer = cpu_to_be32(ktime_get_real_seconds() + defq->btimelimit); } else { - d->d_bwarns = 0; + dq->q_blk.warnings = 0; } } else { if ((!dq->q_blk.softlimit || @@ -158,7 +158,7 @@ xfs_qm_adjust_dqtimers( d->d_itimer = cpu_to_be32(ktime_get_real_seconds() + defq->itimelimit); } else { - d->d_iwarns = 0; + dq->q_ino.warnings = 0; } } else { if ((!dq->q_ino.softlimit || @@ -177,7 +177,7 @@ xfs_qm_adjust_dqtimers( d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() + defq->rtbtimelimit); } else { - d->d_rtbwarns = 0; + dq->q_rtb.warnings = 0; } } else { if ((!dq->q_rtb.softlimit || @@ -542,6 +542,10 @@ xfs_dquot_from_disk( dqp->q_ino.count = be64_to_cpu(ddqp->d_icount); dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount); + dqp->q_blk.warnings = be16_to_cpu(ddqp->d_bwarns); + dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns); + dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns); + /* * Reservation counters are defined as reservation plus current usage * to avoid having to add every time. @@ -573,6 +577,10 @@ xfs_dquot_to_disk( ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count); ddqp->d_icount = cpu_to_be64(dqp->q_ino.count); ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count); + + ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings); + ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings); + ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings); } /* Allocate and initialize the dquot buffer for this in-core dquot. */ diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index 23e05b0d7567..5840bc54b772 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h @@ -37,6 +37,14 @@ struct xfs_dquot_res { /* Absolute and preferred limits. */ xfs_qcnt_t hardlimit; xfs_qcnt_t softlimit; + + /* + * For root dquots, this is the maximum number of warnings that will + * be issued for this quota type. Otherwise, this is the number of + * warnings issued against this quota. Note that none of this is + * implemented. + */ + xfs_qwarncnt_t warnings; }; /* diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index b47bba204240..4e233cfef46d 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -616,12 +616,12 @@ xfs_qm_init_timelimits( defq->itimelimit = be32_to_cpu(ddqp->d_itimer); if (ddqp->d_rtbtimer) defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer); - if (ddqp->d_bwarns) - defq->bwarnlimit = be16_to_cpu(ddqp->d_bwarns); - if (ddqp->d_iwarns) - defq->iwarnlimit = be16_to_cpu(ddqp->d_iwarns); - if (ddqp->d_rtbwarns) - defq->rtbwarnlimit = be16_to_cpu(ddqp->d_rtbwarns); + if (dqp->q_blk.warnings) + defq->bwarnlimit = dqp->q_blk.warnings; + if (dqp->q_ino.warnings) + defq->iwarnlimit = dqp->q_ino.warnings; + if (dqp->q_rtb.warnings) + defq->rtbwarnlimit = dqp->q_rtb.warnings; xfs_qm_dqdestroy(dqp); } diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index ab596d389e3e..5d3bccdbd3bf 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -548,11 +548,11 @@ xfs_qm_scall_setqlim( * Update warnings counter(s) if requested */ if (newlim->d_fieldmask & QC_SPC_WARNS) - ddq->d_bwarns = cpu_to_be16(newlim->d_spc_warns); + dqp->q_blk.warnings = newlim->d_spc_warns; if (newlim->d_fieldmask & QC_INO_WARNS) - ddq->d_iwarns = cpu_to_be16(newlim->d_ino_warns); + dqp->q_ino.warnings = newlim->d_ino_warns; if (newlim->d_fieldmask & QC_RT_SPC_WARNS) - ddq->d_rtbwarns = cpu_to_be16(newlim->d_rt_spc_warns); + dqp->q_rtb.warnings = newlim->d_rt_spc_warns; if (id == 0) { if (newlim->d_fieldmask & QC_SPC_WARNS) @@ -627,13 +627,13 @@ xfs_qm_scall_getquota_fill_qc( dst->d_ino_count = dqp->q_ino.reserved; dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); - dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); - dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns); + dst->d_ino_warns = dqp->q_ino.warnings; + dst->d_spc_warns = dqp->q_blk.warnings; dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); - dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); + dst->d_rt_spc_warns = dqp->q_rtb.warnings; /* * Internally, we don't reset all the timers when quota enforcement diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index b36d747989a7..21ed8eda3c80 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -592,7 +592,7 @@ xfs_trans_dqresv( if (!softlimit) softlimit = defq->bsoftlimit; timer = be32_to_cpu(dqp->q_core.d_btimer); - warns = be16_to_cpu(dqp->q_core.d_bwarns); + warns = dqp->q_blk.warnings; warnlimit = defq->bwarnlimit; resbcountp = &dqp->q_blk.reserved; } else { @@ -604,7 +604,7 @@ xfs_trans_dqresv( if (!softlimit) softlimit = defq->rtbsoftlimit; timer = be32_to_cpu(dqp->q_core.d_rtbtimer); - warns = be16_to_cpu(dqp->q_core.d_rtbwarns); + warns = dqp->q_rtb.warnings; warnlimit = defq->rtbwarnlimit; resbcountp = &dqp->q_rtb.reserved; } @@ -639,7 +639,7 @@ xfs_trans_dqresv( if (ninos > 0) { total_count = dqp->q_ino.reserved + ninos; timer = be32_to_cpu(dqp->q_core.d_itimer); - warns = be16_to_cpu(dqp->q_core.d_iwarns); + warns = dqp->q_ino.warnings; warnlimit = defq->iwarnlimit; hardlimit = dqp->q_ino.hardlimit; if (!hardlimit)
From: Darrick J. Wong <darrick.wong@oracle.com> Add timers fields to 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: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_dquot.c | 41 +++++++++++++++++++++++------------------ fs/xfs/xfs_dquot.h | 7 +++++++ fs/xfs/xfs_qm.c | 15 ++++++--------- fs/xfs/xfs_qm_syscalls.c | 18 ++++++++---------- fs/xfs/xfs_trans_dquot.c | 6 +++--- 5 files changed, 47 insertions(+), 40 deletions(-) diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index a1edb49ceda5..7434ee57ec43 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -116,7 +116,6 @@ xfs_qm_adjust_dqtimers( struct xfs_dquot *dq) { struct xfs_quotainfo *qi = mp->m_quotainfo; - struct xfs_disk_dquot *d = &dq->q_core; struct xfs_def_quota *defq; ASSERT(dq->q_id); @@ -131,13 +130,13 @@ xfs_qm_adjust_dqtimers( ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit); #endif - if (!d->d_btimer) { + if (!dq->q_blk.timer) { if ((dq->q_blk.softlimit && (dq->q_blk.count > dq->q_blk.softlimit)) || (dq->q_blk.hardlimit && (dq->q_blk.count > dq->q_blk.hardlimit))) { - d->d_btimer = cpu_to_be32(ktime_get_real_seconds() + - defq->btimelimit); + dq->q_blk.timer = ktime_get_real_seconds() + + defq->btimelimit; } else { dq->q_blk.warnings = 0; } @@ -146,17 +145,17 @@ xfs_qm_adjust_dqtimers( (dq->q_blk.count <= dq->q_blk.softlimit)) && (!dq->q_blk.hardlimit || (dq->q_blk.count <= dq->q_blk.hardlimit))) { - d->d_btimer = 0; + dq->q_blk.timer = 0; } } - if (!d->d_itimer) { + if (!dq->q_ino.timer) { if ((dq->q_ino.softlimit && (dq->q_ino.count > dq->q_ino.softlimit)) || (dq->q_ino.hardlimit && (dq->q_ino.count > dq->q_ino.hardlimit))) { - d->d_itimer = cpu_to_be32(ktime_get_real_seconds() + - defq->itimelimit); + dq->q_ino.timer = ktime_get_real_seconds() + + defq->itimelimit; } else { dq->q_ino.warnings = 0; } @@ -165,17 +164,17 @@ xfs_qm_adjust_dqtimers( (dq->q_ino.count <= dq->q_ino.softlimit)) && (!dq->q_ino.hardlimit || (dq->q_ino.count <= dq->q_ino.hardlimit))) { - d->d_itimer = 0; + dq->q_ino.timer = 0; } } - if (!d->d_rtbtimer) { + if (!dq->q_rtb.timer) { if ((dq->q_rtb.softlimit && (dq->q_rtb.count > dq->q_rtb.softlimit)) || (dq->q_rtb.hardlimit && (dq->q_rtb.count > dq->q_rtb.hardlimit))) { - d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() + - defq->rtbtimelimit); + dq->q_rtb.timer = ktime_get_real_seconds() + + defq->rtbtimelimit; } else { dq->q_rtb.warnings = 0; } @@ -184,7 +183,7 @@ xfs_qm_adjust_dqtimers( (dq->q_rtb.count <= dq->q_rtb.softlimit)) && (!dq->q_rtb.hardlimit || (dq->q_rtb.count <= dq->q_rtb.hardlimit))) { - d->d_rtbtimer = 0; + dq->q_rtb.timer = 0; } } } @@ -546,6 +545,10 @@ xfs_dquot_from_disk( dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns); dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns); + dqp->q_blk.timer = be32_to_cpu(ddqp->d_btimer); + dqp->q_ino.timer = be32_to_cpu(ddqp->d_itimer); + dqp->q_rtb.timer = be32_to_cpu(ddqp->d_rtbtimer); + /* * Reservation counters are defined as reservation plus current usage * to avoid having to add every time. @@ -581,6 +584,10 @@ xfs_dquot_to_disk( ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings); ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings); ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings); + + ddqp->d_btimer = cpu_to_be32(dqp->q_blk.timer); + ddqp->d_itimer = cpu_to_be32(dqp->q_ino.timer); + ddqp->d_rtbtimer = cpu_to_be32(dqp->q_rtb.timer); } /* Allocate and initialize the dquot buffer for this in-core dquot. */ @@ -1135,8 +1142,6 @@ static xfs_failaddr_t xfs_qm_dqflush_check( struct xfs_dquot *dqp) { - struct xfs_disk_dquot *ddq = &dqp->q_core; - if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) return __this_address; @@ -1144,15 +1149,15 @@ xfs_qm_dqflush_check( return NULL; if (dqp->q_blk.softlimit && dqp->q_blk.count > dqp->q_blk.softlimit && - !ddq->d_btimer) + !dqp->q_blk.timer) return __this_address; if (dqp->q_ino.softlimit && dqp->q_ino.count > dqp->q_ino.softlimit && - !ddq->d_itimer) + !dqp->q_ino.timer) return __this_address; if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit && - !ddq->d_rtbtimer) + !dqp->q_rtb.timer) return __this_address; return NULL; diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index 5840bc54b772..414bae537b1d 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h @@ -38,6 +38,13 @@ struct xfs_dquot_res { xfs_qcnt_t hardlimit; xfs_qcnt_t softlimit; + /* + * For root dquots, this is the default grace period, in seconds. + * Otherwise, this is when the quota grace period expires, + * in seconds since the Unix epoch. + */ + time64_t timer; + /* * For root dquots, this is the maximum number of warnings that will * be issued for this quota type. Otherwise, this is the number of diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 4e233cfef46d..a56c6e4a5d99 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -579,7 +579,6 @@ xfs_qm_init_timelimits( { struct xfs_quotainfo *qinf = mp->m_quotainfo; struct xfs_def_quota *defq; - struct xfs_disk_dquot *ddqp; struct xfs_dquot *dqp; int error; @@ -603,19 +602,17 @@ xfs_qm_init_timelimits( if (error) return; - ddqp = &dqp->q_core; - /* * The warnings and timers set the grace period given to * a user or group before he or she can not perform any * more writing. If it is zero, a default is used. */ - if (ddqp->d_btimer) - defq->btimelimit = be32_to_cpu(ddqp->d_btimer); - if (ddqp->d_itimer) - defq->itimelimit = be32_to_cpu(ddqp->d_itimer); - if (ddqp->d_rtbtimer) - defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer); + if (dqp->q_blk.timer) + defq->btimelimit = dqp->q_blk.timer; + if (dqp->q_ino.timer) + defq->itimelimit = dqp->q_ino.timer; + if (dqp->q_rtb.timer) + defq->rtbtimelimit = dqp->q_rtb.timer; if (dqp->q_blk.warnings) defq->bwarnlimit = dqp->q_blk.warnings; if (dqp->q_ino.warnings) diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 5d3bccdbd3bf..1b2b70b1660f 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -447,7 +447,6 @@ xfs_qm_scall_setqlim( struct qc_dqblk *newlim) { struct xfs_quotainfo *q = mp->m_quotainfo; - struct xfs_disk_dquot *ddq; struct xfs_dquot *dqp; struct xfs_trans *tp; struct xfs_def_quota *defq; @@ -488,7 +487,6 @@ xfs_qm_scall_setqlim( xfs_dqlock(dqp); xfs_trans_dqjoin(tp, dqp); - ddq = &dqp->q_core; /* * Make sure that hardlimits are >= soft limits before changing. @@ -573,11 +571,11 @@ xfs_qm_scall_setqlim( * the soft limit. */ if (newlim->d_fieldmask & QC_SPC_TIMER) - ddq->d_btimer = cpu_to_be32(newlim->d_spc_timer); + dqp->q_blk.timer = newlim->d_spc_timer; if (newlim->d_fieldmask & QC_INO_TIMER) - ddq->d_itimer = cpu_to_be32(newlim->d_ino_timer); + dqp->q_ino.timer = newlim->d_ino_timer; if (newlim->d_fieldmask & QC_RT_SPC_TIMER) - ddq->d_rtbtimer = cpu_to_be32(newlim->d_rt_spc_timer); + dqp->q_rtb.timer = newlim->d_rt_spc_timer; if (id == 0) { if (newlim->d_fieldmask & QC_SPC_TIMER) @@ -621,18 +619,18 @@ xfs_qm_scall_getquota_fill_qc( memset(dst, 0, sizeof(*dst)); dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit); dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit); - dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); - dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); + dst->d_ino_hardlimit = dqp->q_ino.hardlimit; + dst->d_ino_softlimit = dqp->q_ino.softlimit; dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); dst->d_ino_count = dqp->q_ino.reserved; - dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); - dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); + dst->d_spc_timer = dqp->q_blk.timer; + dst->d_ino_timer = dqp->q_ino.timer; dst->d_ino_warns = dqp->q_ino.warnings; dst->d_spc_warns = dqp->q_blk.warnings; dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); - dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); + dst->d_rt_spc_timer = dqp->q_rtb.timer; dst->d_rt_spc_warns = dqp->q_rtb.warnings; /* diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 21ed8eda3c80..28b59a4069a3 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -591,7 +591,7 @@ xfs_trans_dqresv( softlimit = dqp->q_blk.softlimit; if (!softlimit) softlimit = defq->bsoftlimit; - timer = be32_to_cpu(dqp->q_core.d_btimer); + timer = dqp->q_blk.timer; warns = dqp->q_blk.warnings; warnlimit = defq->bwarnlimit; resbcountp = &dqp->q_blk.reserved; @@ -603,7 +603,7 @@ xfs_trans_dqresv( softlimit = dqp->q_rtb.softlimit; if (!softlimit) softlimit = defq->rtbsoftlimit; - timer = be32_to_cpu(dqp->q_core.d_rtbtimer); + timer = dqp->q_rtb.timer; warns = dqp->q_rtb.warnings; warnlimit = defq->rtbwarnlimit; resbcountp = &dqp->q_rtb.reserved; @@ -638,7 +638,7 @@ xfs_trans_dqresv( } if (ninos > 0) { total_count = dqp->q_ino.reserved + ninos; - timer = be32_to_cpu(dqp->q_core.d_itimer); + timer = dqp->q_ino.timer; warns = dqp->q_ino.warnings; warnlimit = defq->iwarnlimit; hardlimit = dqp->q_ino.hardlimit;
From: Darrick J. Wong <darrick.wong@oracle.com> Now that we've stopped using qcore entirely, drop it from the incore dquot. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/scrub/quota.c | 4 ---- fs/xfs/xfs_dquot.c | 29 +++++++++-------------------- fs/xfs/xfs_dquot.h | 1 - 3 files changed, 9 insertions(+), 25 deletions(-) diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c index 2fc2625feca0..f4aad5b00188 100644 --- a/fs/xfs/scrub/quota.c +++ b/fs/xfs/scrub/quota.c @@ -79,7 +79,6 @@ xchk_quota_item( struct xchk_quota_info *sqi = priv; struct xfs_scrub *sc = sqi->sc; struct xfs_mount *mp = sc->mp; - struct xfs_disk_dquot *d = &dq->q_core; struct xfs_quotainfo *qi = mp->m_quotainfo; xfs_fileoff_t offset; xfs_ino_t fs_icount; @@ -98,9 +97,6 @@ xchk_quota_item( sqi->last_id = dq->q_id; - if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) - xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); - /* * Warn if the hard limits are larger than the fs. * Administrators can do this, though in production this seems diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 7434ee57ec43..2d6b50760962 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -529,7 +529,6 @@ 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); @@ -568,8 +567,13 @@ xfs_dquot_to_disk( struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp) { - memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); + ddqp->d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); + ddqp->d_version = XFS_DQUOT_VERSION; ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK; + ddqp->d_id = cpu_to_be32(dqp->q_id); + ddqp->d_pad0 = 0; + ddqp->d_pad = 0; + 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); @@ -1180,7 +1184,6 @@ xfs_qm_dqflush( struct xfs_log_item *lip = &dqp->q_logitem.qli_item; struct xfs_buf *bp; struct xfs_dqblk *dqb; - struct xfs_disk_dquot *ddqp; xfs_failaddr_t fa; int error; @@ -1204,22 +1207,6 @@ xfs_qm_dqflush( if (error) goto out_abort; - /* - * Calculate the location of the dquot inside the buffer. - */ - dqb = bp->b_addr + dqp->q_bufoffset; - ddqp = &dqb->dd_diskdq; - - /* sanity check the in-core structure before we flush */ - fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0); - if (fa) { - xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", - dqp->q_id, fa); - xfs_buf_relse(bp); - error = -EFSCORRUPTED; - goto out_abort; - } - fa = xfs_qm_dqflush_check(dqp); if (fa) { xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", @@ -1229,7 +1216,9 @@ xfs_qm_dqflush( goto out_abort; } - xfs_dquot_to_disk(ddqp, dqp); + /* Flush the incore dquot to the ondisk buffer. */ + dqb = bp->b_addr + dqp->q_bufoffset; + xfs_dquot_to_disk(&dqb->dd_diskdq, dqp); /* * Clear the dirty field and remember the flush lsn for later use. diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index 414bae537b1d..62b0fc6e0133 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h @@ -71,7 +71,6 @@ struct xfs_dquot { struct xfs_dquot_res q_ino; /* inodes */ struct xfs_dquot_res q_rtb; /* realtime blocks */ - struct xfs_disk_dquot q_core; struct xfs_dq_logitem q_logitem; xfs_qcnt_t q_prealloc_lo_wmark;
From: Darrick J. Wong <darrick.wong@oracle.com> Now that we've split up the dquot resource fields into separate structs, do the same for the default limits to enable further refactoring. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_dquot.c | 30 +++++++++++++++--------------- fs/xfs/xfs_qm.c | 36 ++++++++++++++++++------------------ fs/xfs/xfs_qm.h | 22 ++++++++++------------ fs/xfs/xfs_qm_syscalls.c | 24 ++++++++++++------------ fs/xfs/xfs_quotaops.c | 12 ++++++------ fs/xfs/xfs_trans_dquot.c | 18 +++++++++--------- 6 files changed, 70 insertions(+), 72 deletions(-) diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 2d6b50760962..6975c27145fc 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -76,22 +76,22 @@ xfs_qm_adjust_dqlimits( ASSERT(dq->q_id); defq = xfs_get_defquota(q, xfs_dquot_type(dq)); - if (defq->bsoftlimit && !dq->q_blk.softlimit) { - dq->q_blk.softlimit = defq->bsoftlimit; + if (defq->dfq_blk.softlimit && !dq->q_blk.softlimit) { + dq->q_blk.softlimit = defq->dfq_blk.softlimit; prealloc = 1; } - if (defq->bhardlimit && !dq->q_blk.hardlimit) { - dq->q_blk.hardlimit = defq->bhardlimit; + if (defq->dfq_blk.hardlimit && !dq->q_blk.hardlimit) { + dq->q_blk.hardlimit = defq->dfq_blk.hardlimit; prealloc = 1; } - 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 (defq->dfq_ino.softlimit && !dq->q_ino.softlimit) + dq->q_ino.softlimit = defq->dfq_ino.softlimit; + if (defq->dfq_ino.hardlimit && !dq->q_ino.hardlimit) + dq->q_ino.hardlimit = defq->dfq_ino.hardlimit; + if (defq->dfq_rtb.softlimit && !dq->q_rtb.softlimit) + dq->q_rtb.softlimit = defq->dfq_rtb.softlimit; + if (defq->dfq_rtb.hardlimit && !dq->q_rtb.hardlimit) + dq->q_rtb.hardlimit = defq->dfq_rtb.hardlimit; if (prealloc) xfs_dquot_set_prealloc_limits(dq); @@ -136,7 +136,7 @@ xfs_qm_adjust_dqtimers( (dq->q_blk.hardlimit && (dq->q_blk.count > dq->q_blk.hardlimit))) { dq->q_blk.timer = ktime_get_real_seconds() + - defq->btimelimit; + defq->dfq_blk.timelimit; } else { dq->q_blk.warnings = 0; } @@ -155,7 +155,7 @@ xfs_qm_adjust_dqtimers( (dq->q_ino.hardlimit && (dq->q_ino.count > dq->q_ino.hardlimit))) { dq->q_ino.timer = ktime_get_real_seconds() + - defq->itimelimit; + defq->dfq_ino.timelimit; } else { dq->q_ino.warnings = 0; } @@ -174,7 +174,7 @@ xfs_qm_adjust_dqtimers( (dq->q_rtb.hardlimit && (dq->q_rtb.count > dq->q_rtb.hardlimit))) { dq->q_rtb.timer = ktime_get_real_seconds() + - defq->rtbtimelimit; + defq->dfq_rtb.timelimit; } else { dq->q_rtb.warnings = 0; } diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index a56c6e4a5d99..28326a6264a8 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -562,12 +562,12 @@ xfs_qm_set_defquota( * Timers and warnings have been already set, let's just set the * default limits for this quota type */ - 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; + defq->dfq_blk.hardlimit = dqp->q_blk.hardlimit; + defq->dfq_blk.softlimit = dqp->q_blk.softlimit; + defq->dfq_ino.hardlimit = dqp->q_ino.hardlimit; + defq->dfq_ino.softlimit = dqp->q_ino.softlimit; + defq->dfq_rtb.hardlimit = dqp->q_rtb.hardlimit; + defq->dfq_rtb.softlimit = dqp->q_rtb.softlimit; xfs_qm_dqdestroy(dqp); } @@ -584,12 +584,12 @@ xfs_qm_init_timelimits( defq = xfs_get_defquota(qinf, type); - defq->btimelimit = XFS_QM_BTIMELIMIT; - defq->itimelimit = XFS_QM_ITIMELIMIT; - defq->rtbtimelimit = XFS_QM_RTBTIMELIMIT; - defq->bwarnlimit = XFS_QM_BWARNLIMIT; - defq->iwarnlimit = XFS_QM_IWARNLIMIT; - defq->rtbwarnlimit = XFS_QM_RTBWARNLIMIT; + defq->dfq_blk.timelimit = XFS_QM_BTIMELIMIT; + defq->dfq_ino.timelimit = XFS_QM_ITIMELIMIT; + defq->dfq_rtb.timelimit = XFS_QM_RTBTIMELIMIT; + defq->dfq_blk.warnlimit = XFS_QM_BWARNLIMIT; + defq->dfq_ino.warnlimit = XFS_QM_IWARNLIMIT; + defq->dfq_rtb.warnlimit = XFS_QM_RTBWARNLIMIT; /* * We try to get the limits from the superuser's limits fields. @@ -608,17 +608,17 @@ xfs_qm_init_timelimits( * more writing. If it is zero, a default is used. */ if (dqp->q_blk.timer) - defq->btimelimit = dqp->q_blk.timer; + defq->dfq_blk.timelimit = dqp->q_blk.timer; if (dqp->q_ino.timer) - defq->itimelimit = dqp->q_ino.timer; + defq->dfq_ino.timelimit = dqp->q_ino.timer; if (dqp->q_rtb.timer) - defq->rtbtimelimit = dqp->q_rtb.timer; + defq->dfq_rtb.timelimit = dqp->q_rtb.timer; if (dqp->q_blk.warnings) - defq->bwarnlimit = dqp->q_blk.warnings; + defq->dfq_blk.warnlimit = dqp->q_blk.warnings; if (dqp->q_ino.warnings) - defq->iwarnlimit = dqp->q_ino.warnings; + defq->dfq_ino.warnlimit = dqp->q_ino.warnings; if (dqp->q_rtb.warnings) - defq->rtbwarnlimit = dqp->q_rtb.warnings; + defq->dfq_rtb.warnlimit = dqp->q_rtb.warnings; xfs_qm_dqdestroy(dqp); } diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 6ed4ae942603..e2f0027f0ac1 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -41,20 +41,18 @@ extern struct kmem_zone *xfs_qm_dqtrxzone; */ #define XFS_DQUOT_CLUSTER_SIZE_FSB (xfs_filblks_t)1 +struct xfs_def_qres { + xfs_qcnt_t hardlimit; /* default hard limit */ + xfs_qcnt_t softlimit; /* default soft limit */ + time64_t timelimit; /* limit for timers */ + xfs_qwarncnt_t warnlimit; /* limit for warnings */ +}; + /* Defaults for each quota type: time limits, warn limits, usage limits */ struct xfs_def_quota { - time64_t btimelimit; /* limit for blks timer */ - time64_t itimelimit; /* limit for inodes timer */ - time64_t rtbtimelimit; /* limit for rt blks timer */ - xfs_qwarncnt_t bwarnlimit; /* limit for blks warnings */ - xfs_qwarncnt_t iwarnlimit; /* limit for inodes warnings */ - xfs_qwarncnt_t rtbwarnlimit; /* limit for rt blks warnings */ - xfs_qcnt_t bhardlimit; /* default data blk hard limit */ - xfs_qcnt_t bsoftlimit; /* default data blk soft limit */ - xfs_qcnt_t ihardlimit; /* default inode count hard limit */ - xfs_qcnt_t isoftlimit; /* default inode count soft limit */ - xfs_qcnt_t rtbhardlimit; /* default realtime blk hard limit */ - xfs_qcnt_t rtbsoftlimit; /* default realtime blk soft limit */ + struct xfs_def_qres dfq_blk; + struct xfs_def_qres dfq_ino; + struct xfs_def_qres dfq_rtb; }; /* diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 1b2b70b1660f..393b88612cc8 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -502,8 +502,8 @@ xfs_qm_scall_setqlim( dqp->q_blk.softlimit = soft; xfs_dquot_set_prealloc_limits(dqp); if (id == 0) { - defq->bhardlimit = hard; - defq->bsoftlimit = soft; + defq->dfq_blk.hardlimit = hard; + defq->dfq_blk.softlimit = soft; } } else { xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft); @@ -518,8 +518,8 @@ xfs_qm_scall_setqlim( dqp->q_rtb.hardlimit = hard; dqp->q_rtb.softlimit = soft; if (id == 0) { - defq->rtbhardlimit = hard; - defq->rtbsoftlimit = soft; + defq->dfq_rtb.hardlimit = hard; + defq->dfq_rtb.softlimit = soft; } } else { xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft); @@ -535,8 +535,8 @@ xfs_qm_scall_setqlim( dqp->q_ino.hardlimit = hard; dqp->q_ino.softlimit = soft; if (id == 0) { - defq->ihardlimit = hard; - defq->isoftlimit = soft; + defq->dfq_ino.hardlimit = hard; + defq->dfq_ino.softlimit = soft; } } else { xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft); @@ -554,11 +554,11 @@ xfs_qm_scall_setqlim( if (id == 0) { if (newlim->d_fieldmask & QC_SPC_WARNS) - defq->bwarnlimit = newlim->d_spc_warns; + defq->dfq_blk.warnlimit = newlim->d_spc_warns; if (newlim->d_fieldmask & QC_INO_WARNS) - defq->iwarnlimit = newlim->d_ino_warns; + defq->dfq_ino.warnlimit = newlim->d_ino_warns; if (newlim->d_fieldmask & QC_RT_SPC_WARNS) - defq->rtbwarnlimit = newlim->d_rt_spc_warns; + defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns; } /* @@ -579,11 +579,11 @@ xfs_qm_scall_setqlim( if (id == 0) { if (newlim->d_fieldmask & QC_SPC_TIMER) - defq->btimelimit = newlim->d_spc_timer; + defq->dfq_blk.timelimit = newlim->d_spc_timer; if (newlim->d_fieldmask & QC_INO_TIMER) - defq->itimelimit = newlim->d_ino_timer; + defq->dfq_ino.timelimit = newlim->d_ino_timer; if (newlim->d_fieldmask & QC_RT_SPC_TIMER) - defq->rtbtimelimit = newlim->d_rt_spc_timer; + defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer; } if (id != 0) { diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index bf809b77a316..c86a6fe263da 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c @@ -37,12 +37,12 @@ xfs_qm_fill_state( tstate->flags |= QCI_SYSFILE; tstate->blocks = ip->i_d.di_nblocks; tstate->nextents = ip->i_df.if_nextents; - tstate->spc_timelimit = (u32)defq->btimelimit; - tstate->ino_timelimit = (u32)defq->itimelimit; - tstate->rt_spc_timelimit = (u32)defq->rtbtimelimit; - tstate->spc_warnlimit = defq->bwarnlimit; - tstate->ino_warnlimit = defq->iwarnlimit; - tstate->rt_spc_warnlimit = defq->rtbwarnlimit; + tstate->spc_timelimit = (u32)defq->dfq_blk.timelimit; + tstate->ino_timelimit = (u32)defq->dfq_ino.timelimit; + tstate->rt_spc_timelimit = (u32)defq->dfq_rtb.timelimit; + tstate->spc_warnlimit = defq->dfq_blk.warnlimit; + tstate->ino_warnlimit = defq->dfq_ino.warnlimit; + tstate->rt_spc_warnlimit = defq->dfq_rtb.warnlimit; if (tempqip) xfs_irele(ip); } diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 28b59a4069a3..392e51baad6f 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -587,25 +587,25 @@ xfs_trans_dqresv( if (flags & XFS_TRANS_DQ_RES_BLKS) { hardlimit = dqp->q_blk.hardlimit; if (!hardlimit) - hardlimit = defq->bhardlimit; + hardlimit = defq->dfq_blk.hardlimit; softlimit = dqp->q_blk.softlimit; if (!softlimit) - softlimit = defq->bsoftlimit; + softlimit = defq->dfq_blk.softlimit; timer = dqp->q_blk.timer; warns = dqp->q_blk.warnings; - warnlimit = defq->bwarnlimit; + warnlimit = defq->dfq_blk.warnlimit; resbcountp = &dqp->q_blk.reserved; } else { ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); hardlimit = dqp->q_rtb.hardlimit; if (!hardlimit) - hardlimit = defq->rtbhardlimit; + hardlimit = defq->dfq_rtb.hardlimit; softlimit = dqp->q_rtb.softlimit; if (!softlimit) - softlimit = defq->rtbsoftlimit; + softlimit = defq->dfq_rtb.softlimit; timer = dqp->q_rtb.timer; warns = dqp->q_rtb.warnings; - warnlimit = defq->rtbwarnlimit; + warnlimit = defq->dfq_rtb.warnlimit; resbcountp = &dqp->q_rtb.reserved; } @@ -640,13 +640,13 @@ xfs_trans_dqresv( total_count = dqp->q_ino.reserved + ninos; timer = dqp->q_ino.timer; warns = dqp->q_ino.warnings; - warnlimit = defq->iwarnlimit; + warnlimit = defq->dfq_ino.warnlimit; hardlimit = dqp->q_ino.hardlimit; if (!hardlimit) - hardlimit = defq->ihardlimit; + hardlimit = defq->dfq_ino.hardlimit; softlimit = dqp->q_ino.softlimit; if (!softlimit) - softlimit = defq->isoftlimit; + softlimit = defq->dfq_ino.softlimit; if (hardlimit && total_count > hardlimit) { xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
From: Darrick J. Wong <darrick.wong@oracle.com> struct xfs_dquot already has a pointer to the xfs mount, so remove the redundant parameter from xfs_qm_adjust_dq*. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_dquot.c | 4 ++-- fs/xfs/xfs_dquot.h | 6 ++---- fs/xfs/xfs_qm.c | 4 ++-- fs/xfs/xfs_qm_syscalls.c | 2 +- fs/xfs/xfs_trans_dquot.c | 4 ++-- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 6975c27145fc..35a113d1b42b 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -66,9 +66,9 @@ xfs_qm_dqdestroy( */ void xfs_qm_adjust_dqlimits( - struct xfs_mount *mp, struct xfs_dquot *dq) { + struct xfs_mount *mp = dq->q_mount; struct xfs_quotainfo *q = mp->m_quotainfo; struct xfs_def_quota *defq; int prealloc = 0; @@ -112,9 +112,9 @@ xfs_qm_adjust_dqlimits( */ void xfs_qm_adjust_dqtimers( - struct xfs_mount *mp, struct xfs_dquot *dq) { + struct xfs_mount *mp = dq->q_mount; struct xfs_quotainfo *qi = mp->m_quotainfo; struct xfs_def_quota *defq; diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index 62b0fc6e0133..e37b4bebc1ea 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h @@ -181,10 +181,8 @@ void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp); void xfs_qm_dqdestroy(struct xfs_dquot *dqp); int xfs_qm_dqflush(struct xfs_dquot *dqp, struct xfs_buf **bpp); void xfs_qm_dqunpin_wait(struct xfs_dquot *dqp); -void xfs_qm_adjust_dqtimers(struct xfs_mount *mp, - struct xfs_dquot *d); -void xfs_qm_adjust_dqlimits(struct xfs_mount *mp, - struct xfs_dquot *d); +void xfs_qm_adjust_dqtimers(struct xfs_dquot *d); +void xfs_qm_adjust_dqlimits(struct xfs_dquot *d); xfs_dqid_t xfs_qm_id_for_quotatype(struct xfs_inode *ip, uint type); int xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id, uint type, bool can_alloc, diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 28326a6264a8..30deb6cf6a7a 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -1107,8 +1107,8 @@ xfs_qm_quotacheck_dqadjust( * There are no timers for the default values set in the root dquot. */ if (dqp->q_id) { - xfs_qm_adjust_dqlimits(mp, dqp); - xfs_qm_adjust_dqtimers(mp, dqp); + xfs_qm_adjust_dqlimits(dqp); + xfs_qm_adjust_dqtimers(dqp); } dqp->dq_flags |= XFS_DQ_DIRTY; diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 393b88612cc8..5423e02f9837 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -594,7 +594,7 @@ xfs_qm_scall_setqlim( * is on or off. We don't really want to bother with iterating * over all ondisk dquots and turning the timers on/off. */ - xfs_qm_adjust_dqtimers(mp, dqp); + xfs_qm_adjust_dqtimers(dqp); } dqp->dq_flags |= XFS_DQ_DIRTY; xfs_trans_log_dquot(tp, dqp); diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 392e51baad6f..2712814d696d 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -382,8 +382,8 @@ xfs_trans_apply_dquot_deltas( * Start/reset the timer(s) if needed. */ if (dqp->q_id) { - xfs_qm_adjust_dqlimits(tp->t_mountp, dqp); - xfs_qm_adjust_dqtimers(tp->t_mountp, dqp); + xfs_qm_adjust_dqlimits(dqp); + xfs_qm_adjust_dqtimers(dqp); } dqp->dq_flags |= XFS_DQ_DIRTY;
From: Darrick J. Wong <darrick.wong@oracle.com> Refactor the open-coded test for whether or not we're over quota. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_dquot.c | 95 ++++++++++++++++------------------------------------ 1 file changed, 30 insertions(+), 65 deletions(-) diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 35a113d1b42b..ef34c82c28a0 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits( xfs_dquot_set_prealloc_limits(dq); } +/* + * Determine if this quota counter is over either limit and set the quota + * timers as appropriate. + */ +static inline void +xfs_qm_adjust_res_timer( + struct xfs_dquot_res *res, + struct xfs_def_qres *dres) +{ + bool over; + +#ifdef DEBUG + if (res->hardlimit) + ASSERT(res->softlimit <= res->hardlimit); +#endif + + over = (res->softlimit && res->count > res->softlimit) || + (res->hardlimit && res->count > res->hardlimit); + + if (over && res->timer == 0) + res->timer = ktime_get_real_seconds() + dres->timelimit; + else if (!over && res->timer != 0) + res->timer = 0; + else if (!over && res->timer == 0) + res->warnings = 0; +} + /* * Check the limits and timers of a dquot and start or reset timers * if necessary. @@ -121,71 +148,9 @@ xfs_qm_adjust_dqtimers( ASSERT(dq->q_id); defq = xfs_get_defquota(qi, xfs_dquot_type(dq)); -#ifdef DEBUG - 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 (!dq->q_blk.timer) { - if ((dq->q_blk.softlimit && - (dq->q_blk.count > dq->q_blk.softlimit)) || - (dq->q_blk.hardlimit && - (dq->q_blk.count > dq->q_blk.hardlimit))) { - dq->q_blk.timer = ktime_get_real_seconds() + - defq->dfq_blk.timelimit; - } else { - dq->q_blk.warnings = 0; - } - } else { - if ((!dq->q_blk.softlimit || - (dq->q_blk.count <= dq->q_blk.softlimit)) && - (!dq->q_blk.hardlimit || - (dq->q_blk.count <= dq->q_blk.hardlimit))) { - dq->q_blk.timer = 0; - } - } - - if (!dq->q_ino.timer) { - if ((dq->q_ino.softlimit && - (dq->q_ino.count > dq->q_ino.softlimit)) || - (dq->q_ino.hardlimit && - (dq->q_ino.count > dq->q_ino.hardlimit))) { - dq->q_ino.timer = ktime_get_real_seconds() + - defq->dfq_ino.timelimit; - } else { - dq->q_ino.warnings = 0; - } - } else { - if ((!dq->q_ino.softlimit || - (dq->q_ino.count <= dq->q_ino.softlimit)) && - (!dq->q_ino.hardlimit || - (dq->q_ino.count <= dq->q_ino.hardlimit))) { - dq->q_ino.timer = 0; - } - } - - if (!dq->q_rtb.timer) { - if ((dq->q_rtb.softlimit && - (dq->q_rtb.count > dq->q_rtb.softlimit)) || - (dq->q_rtb.hardlimit && - (dq->q_rtb.count > dq->q_rtb.hardlimit))) { - dq->q_rtb.timer = ktime_get_real_seconds() + - defq->dfq_rtb.timelimit; - } else { - dq->q_rtb.warnings = 0; - } - } else { - if ((!dq->q_rtb.softlimit || - (dq->q_rtb.count <= dq->q_rtb.softlimit)) && - (!dq->q_rtb.hardlimit || - (dq->q_rtb.count <= dq->q_rtb.hardlimit))) { - dq->q_rtb.timer = 0; - } - } + xfs_qm_adjust_res_timer(&dq->q_blk, &defq->dfq_blk); + xfs_qm_adjust_res_timer(&dq->q_ino, &defq->dfq_ino); + xfs_qm_adjust_res_timer(&dq->q_rtb, &defq->dfq_rtb); } /*
From: Darrick J. Wong <darrick.wong@oracle.com> Now that we can pass around quota resource and limit structures, clean up the open-coded field setting in xfs_qm_scall_setqlim. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_qm_syscalls.c | 164 ++++++++++++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 71 deletions(-) diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 5423e02f9837..5044c333af5c 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -436,6 +436,58 @@ xfs_qm_scall_quotaon( #define XFS_QC_MASK \ (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK) +/* + * Adjust limits of this quota, and the defaults if passed in. Returns true + * if the new limits made sense and were applied, false otherwise. + */ +static inline bool +xfs_setqlim_limits( + struct xfs_mount *mp, + struct xfs_dquot_res *res, + struct xfs_def_qres *dres, + xfs_qcnt_t hard, + xfs_qcnt_t soft, + const char *tag) +{ + /* The hard limit can't be less than the soft limit. */ + if (hard != 0 && hard < soft) { + xfs_debug(mp, "%shard %lld < %ssoft %lld", tag, hard, tag, + soft); + return false; + } + + res->hardlimit = hard; + res->softlimit = soft; + if (dres) { + dres->hardlimit = hard; + dres->softlimit = soft; + } + + return true; +} + +static inline void +xfs_setqlim_warns( + struct xfs_dquot_res *res, + struct xfs_def_qres *dres, + int warns) +{ + res->warnings = warns; + if (dres) + dres->warnlimit = warns; +} + +static inline void +xfs_setqlim_timer( + struct xfs_dquot_res *res, + struct xfs_def_qres *dres, + s64 timer) +{ + res->timer = timer; + if (dres) + dres->timelimit = timer; +} + /* * Adjust quota limits, and start/stop timers accordingly. */ @@ -450,6 +502,8 @@ xfs_qm_scall_setqlim( struct xfs_dquot *dqp; struct xfs_trans *tp; struct xfs_def_quota *defq; + struct xfs_dquot_res *res; + struct xfs_def_qres *dres; int error; xfs_qcnt_t hard, soft; @@ -489,102 +543,70 @@ xfs_qm_scall_setqlim( xfs_trans_dqjoin(tp, dqp); /* + * Update quota limits, warnings, and timers, and the defaults + * if we're touching id == 0. + * * Make sure that hardlimits are >= soft limits before changing. + * + * Update warnings counter(s) if requested. + * + * Timelimits for the super user set the relative time the other users + * can be over quota for this file system. If it is zero a default is + * used. Ditto for the default soft and hard limit values (already + * done, above), and for warnings. + * + * For other IDs, userspace can bump out the grace period if over + * the soft limit. */ + + /* Blocks on the data device. */ hard = (newlim->d_fieldmask & QC_SPC_HARD) ? (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : dqp->q_blk.hardlimit; soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : dqp->q_blk.softlimit; - if (hard == 0 || hard >= soft) { - dqp->q_blk.hardlimit = hard; - dqp->q_blk.softlimit = soft; + res = &dqp->q_blk; + dres = id == 0 ? &defq->dfq_blk : NULL; + + if (xfs_setqlim_limits(mp, res, dres, hard, soft, "blk")) xfs_dquot_set_prealloc_limits(dqp); - if (id == 0) { - defq->dfq_blk.hardlimit = hard; - defq->dfq_blk.softlimit = soft; - } - } else { - xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft); - } + if (newlim->d_fieldmask & QC_SPC_WARNS) + xfs_setqlim_warns(res, dres, newlim->d_spc_warns); + if (newlim->d_fieldmask & QC_SPC_TIMER) + xfs_setqlim_timer(res, dres, newlim->d_spc_timer); + + /* Blocks on the realtime device. */ hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : dqp->q_rtb.hardlimit; soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : dqp->q_rtb.softlimit; - if (hard == 0 || hard >= soft) { - dqp->q_rtb.hardlimit = hard; - dqp->q_rtb.softlimit = soft; - if (id == 0) { - defq->dfq_rtb.hardlimit = hard; - defq->dfq_rtb.softlimit = soft; - } - } else { - xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft); - } + res = &dqp->q_rtb; + dres = id == 0 ? &defq->dfq_rtb : NULL; + xfs_setqlim_limits(mp, res, dres, hard, soft, "rtb"); + if (newlim->d_fieldmask & QC_RT_SPC_WARNS) + xfs_setqlim_warns(res, dres, newlim->d_rt_spc_warns); + if (newlim->d_fieldmask & QC_RT_SPC_TIMER) + xfs_setqlim_timer(res, dres, newlim->d_rt_spc_timer); + + /* Inodes */ hard = (newlim->d_fieldmask & QC_INO_HARD) ? (xfs_qcnt_t) newlim->d_ino_hardlimit : dqp->q_ino.hardlimit; soft = (newlim->d_fieldmask & QC_INO_SOFT) ? (xfs_qcnt_t) newlim->d_ino_softlimit : dqp->q_ino.softlimit; - if (hard == 0 || hard >= soft) { - dqp->q_ino.hardlimit = hard; - dqp->q_ino.softlimit = soft; - if (id == 0) { - defq->dfq_ino.hardlimit = hard; - defq->dfq_ino.softlimit = soft; - } - } else { - xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft); - } + res = &dqp->q_ino; + dres = id == 0 ? &defq->dfq_ino : NULL; - /* - * Update warnings counter(s) if requested - */ - if (newlim->d_fieldmask & QC_SPC_WARNS) - dqp->q_blk.warnings = newlim->d_spc_warns; + xfs_setqlim_limits(mp, res, dres, hard, soft, "ino"); if (newlim->d_fieldmask & QC_INO_WARNS) - dqp->q_ino.warnings = newlim->d_ino_warns; - if (newlim->d_fieldmask & QC_RT_SPC_WARNS) - dqp->q_rtb.warnings = newlim->d_rt_spc_warns; - - if (id == 0) { - if (newlim->d_fieldmask & QC_SPC_WARNS) - defq->dfq_blk.warnlimit = newlim->d_spc_warns; - if (newlim->d_fieldmask & QC_INO_WARNS) - defq->dfq_ino.warnlimit = newlim->d_ino_warns; - if (newlim->d_fieldmask & QC_RT_SPC_WARNS) - defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns; - } - - /* - * Timelimits for the super user set the relative time the other users - * can be over quota for this file system. If it is zero a default is - * used. Ditto for the default soft and hard limit values (already - * done, above), and for warnings. - * - * For other IDs, userspace can bump out the grace period if over - * the soft limit. - */ - if (newlim->d_fieldmask & QC_SPC_TIMER) - dqp->q_blk.timer = newlim->d_spc_timer; + xfs_setqlim_warns(res, dres, newlim->d_ino_warns); if (newlim->d_fieldmask & QC_INO_TIMER) - dqp->q_ino.timer = newlim->d_ino_timer; - if (newlim->d_fieldmask & QC_RT_SPC_TIMER) - dqp->q_rtb.timer = newlim->d_rt_spc_timer; - - if (id == 0) { - if (newlim->d_fieldmask & QC_SPC_TIMER) - defq->dfq_blk.timelimit = newlim->d_spc_timer; - if (newlim->d_fieldmask & QC_INO_TIMER) - defq->dfq_ino.timelimit = newlim->d_ino_timer; - if (newlim->d_fieldmask & QC_RT_SPC_TIMER) - defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer; - } + xfs_setqlim_timer(res, dres, newlim->d_ino_timer); if (id != 0) { /*
From: Darrick J. Wong <darrick.wong@oracle.com> Now that we've refactored the resource usage and limits into per-resource structures, we can refactor some of the open-coded reservation limit checking in xfs_trans_dqresv. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_trans_dquot.c | 153 +++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 75 deletions(-) diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 2712814d696d..30a011dc9828 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -554,6 +554,58 @@ xfs_quota_warn( mp->m_super->s_dev, type); } +/* + * Decide if we can make an additional reservation against a quota resource. + * Returns an inode QUOTA_NL_ warning code and whether or not it's fatal. + * + * Note that we assume that the numeric difference between the inode and block + * warning codes will always be 3 since it's userspace ABI now, and will never + * decrease the quota reservation, so the *BELOW messages are irrelevant. + */ +static inline int +xfs_dqresv_check( + struct xfs_dquot_res *res, + struct xfs_def_qres *dres, + int64_t delta, + bool *fatal) +{ + xfs_qcnt_t hardlimit = res->hardlimit; + xfs_qcnt_t softlimit = res->softlimit; + xfs_qcnt_t total_count = res->reserved + delta; + + BUILD_BUG_ON(QUOTA_NL_BHARDWARN != QUOTA_NL_IHARDWARN + 3); + BUILD_BUG_ON(QUOTA_NL_BSOFTLONGWARN != QUOTA_NL_ISOFTLONGWARN + 3); + BUILD_BUG_ON(QUOTA_NL_BSOFTWARN != QUOTA_NL_ISOFTWARN + 3); + + *fatal = false; + if (delta <= 0) + return QUOTA_NL_NOWARN; + + if (!hardlimit) + hardlimit = dres->hardlimit; + if (!softlimit) + softlimit = dres->softlimit; + + if (hardlimit && total_count > hardlimit) { + *fatal = true; + return QUOTA_NL_IHARDWARN; + } + + if (softlimit && total_count > softlimit) { + time64_t now = ktime_get_real_seconds(); + + if ((res->timer != 0 && now > res->timer) || + (res->warnings != 0 && res->warnings >= dres->warnlimit)) { + *fatal = true; + return QUOTA_NL_ISOFTLONGWARN; + } + + return QUOTA_NL_ISOFTWARN; + } + + return QUOTA_NL_NOWARN; +} + /* * This reserves disk blocks and inodes against a dquot. * Flags indicate if the dquot is to be locked here and also @@ -569,99 +621,51 @@ xfs_trans_dqresv( long ninos, uint flags) { - xfs_qcnt_t hardlimit; - xfs_qcnt_t softlimit; - time64_t timer; - xfs_qwarncnt_t warns; - xfs_qwarncnt_t warnlimit; - xfs_qcnt_t total_count; - xfs_qcnt_t *resbcountp; struct xfs_quotainfo *q = mp->m_quotainfo; struct xfs_def_quota *defq; - + struct xfs_dquot_res *blkres; + struct xfs_def_qres *def_blkres; xfs_dqlock(dqp); defq = xfs_get_defquota(q, xfs_dquot_type(dqp)); if (flags & XFS_TRANS_DQ_RES_BLKS) { - hardlimit = dqp->q_blk.hardlimit; - if (!hardlimit) - hardlimit = defq->dfq_blk.hardlimit; - softlimit = dqp->q_blk.softlimit; - if (!softlimit) - softlimit = defq->dfq_blk.softlimit; - timer = dqp->q_blk.timer; - warns = dqp->q_blk.warnings; - warnlimit = defq->dfq_blk.warnlimit; - resbcountp = &dqp->q_blk.reserved; + blkres = &dqp->q_blk; + def_blkres = &defq->dfq_blk; } else { - ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); - hardlimit = dqp->q_rtb.hardlimit; - if (!hardlimit) - hardlimit = defq->dfq_rtb.hardlimit; - softlimit = dqp->q_rtb.softlimit; - if (!softlimit) - softlimit = defq->dfq_rtb.softlimit; - timer = dqp->q_rtb.timer; - warns = dqp->q_rtb.warnings; - warnlimit = defq->dfq_rtb.warnlimit; - resbcountp = &dqp->q_rtb.reserved; + blkres = &dqp->q_rtb; + def_blkres = &defq->dfq_rtb; } if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_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) { + int quota_nl; + bool fatal; + + /* + * dquot is locked already. See if we'd go over the hardlimit + * or exceed the timelimit if we'd reserve resources. + */ + quota_nl = xfs_dqresv_check(blkres, def_blkres, nblks, &fatal); + if (quota_nl != QUOTA_NL_NOWARN) { /* - * dquot is locked already. See if we'd go over the - * hardlimit or exceed the timelimit if we allocate - * nblks. + * Quota block warning codes are 3 more than the inode + * codes, which we check above. */ - total_count = *resbcountp + nblks; - if (hardlimit && total_count > hardlimit) { - xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN); + xfs_quota_warn(mp, dqp, quota_nl + 3); + if (fatal) goto error_return; - } - if (softlimit && total_count > softlimit) { - if ((timer != 0 && - ktime_get_real_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 = dqp->q_ino.reserved + ninos; - timer = dqp->q_ino.timer; - warns = dqp->q_ino.warnings; - warnlimit = defq->dfq_ino.warnlimit; - hardlimit = dqp->q_ino.hardlimit; - if (!hardlimit) - hardlimit = defq->dfq_ino.hardlimit; - softlimit = dqp->q_ino.softlimit; - if (!softlimit) - softlimit = defq->dfq_ino.softlimit; - if (hardlimit && total_count > hardlimit) { - xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN); + quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->dfq_ino, ninos, + &fatal); + if (quota_nl != QUOTA_NL_NOWARN) { + xfs_quota_warn(mp, dqp, quota_nl); + if (fatal) goto error_return; - } - if (softlimit && total_count > softlimit) { - if ((timer != 0 && - ktime_get_real_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); - } } } @@ -669,9 +673,8 @@ xfs_trans_dqresv( * Change the reservation, but not the actual usage. * Note that q_blk.reserved = q_blk.count + resv */ - (*resbcountp) += (xfs_qcnt_t)nblks; - if (ninos != 0) - dqp->q_ino.reserved += (xfs_qcnt_t)ninos; + blkres->reserved += (xfs_qcnt_t)nblks; + dqp->q_ino.reserved += (xfs_qcnt_t)ninos; /* * note the reservation amt in the trans struct too,
From: Darrick J. Wong <darrick.wong@oracle.com> Hoist the code that adjusts the incore quota reservation count adjustments into a separate function, both to reduce the level of indentation and also to reduce the amount of open-coded logic. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_trans_dquot.c | 103 +++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 30a011dc9828..701923ea6c04 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -293,6 +293,37 @@ xfs_trans_dqlockedjoin( } } +/* Apply dqtrx changes to the quota reservation counters. */ +static inline void +xfs_apply_quota_reservation_deltas( + struct xfs_dquot_res *res, + uint64_t reserved, + int64_t res_used, + int64_t count_delta) +{ + if (reserved != 0) { + /* + * Subtle math here: If reserved > res_used (the normal case), + * we're simply subtracting the unused transaction quota + * reservation from the dquot reservation. + * + * If, however, res_used > reserved, then we have allocated + * more quota blocks than were reserved for the transaction. + * We must add that excess to the dquot reservation since it + * tracks (usage + resv) and by definition we didn't reserve + * that excess. + */ + res->reserved -= abs(reserved - res_used); + } else if (count_delta != 0) { + /* + * These blks were never reserved, either inside a transaction + * or outside one (in a delayed allocation). Also, this isn't + * always a negative number since we sometimes deliberately + * skip quota reservations. + */ + res->reserved += count_delta; + } +} /* * Called by xfs_trans_commit() and similar in spirit to @@ -327,6 +358,8 @@ xfs_trans_apply_dquot_deltas( xfs_trans_dqlockedjoin(tp, qa); for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) { + uint64_t blk_res_used; + qtrx = &qa[i]; /* * The array of dquots is filled @@ -396,71 +429,27 @@ xfs_trans_apply_dquot_deltas( * In case of delayed allocations, there's no * reservation that a transaction structure knows of. */ - if (qtrx->qt_blk_res != 0) { - uint64_t blk_res_used = 0; + blk_res_used = max_t(int64_t, 0, qtrx->qt_bcount_delta); + xfs_apply_quota_reservation_deltas(&dqp->q_blk, + qtrx->qt_blk_res, blk_res_used, + qtrx->qt_bcount_delta); - if (qtrx->qt_bcount_delta > 0) - blk_res_used = qtrx->qt_bcount_delta; - - if (qtrx->qt_blk_res != blk_res_used) { - if (qtrx->qt_blk_res > blk_res_used) - dqp->q_blk.reserved -= (xfs_qcnt_t) - (qtrx->qt_blk_res - - blk_res_used); - else - dqp->q_blk.reserved -= (xfs_qcnt_t) - (blk_res_used - - qtrx->qt_blk_res); - } - } else { - /* - * These blks were never reserved, either inside - * a transaction or outside one (in a delayed - * allocation). Also, this isn't always a - * negative number since we sometimes - * deliberately skip quota reservations. - */ - if (qtrx->qt_bcount_delta) { - dqp->q_blk.reserved += - (xfs_qcnt_t)qtrx->qt_bcount_delta; - } - } /* * Adjust the RT reservation. */ - if (qtrx->qt_rtblk_res != 0) { - if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) { - if (qtrx->qt_rtblk_res > - qtrx->qt_rtblk_res_used) - dqp->q_rtb.reserved -= (xfs_qcnt_t) - (qtrx->qt_rtblk_res - - qtrx->qt_rtblk_res_used); - else - dqp->q_rtb.reserved -= (xfs_qcnt_t) - (qtrx->qt_rtblk_res_used - - qtrx->qt_rtblk_res); - } - } else { - if (qtrx->qt_rtbcount_delta) - dqp->q_rtb.reserved += - (xfs_qcnt_t)qtrx->qt_rtbcount_delta; - } + xfs_apply_quota_reservation_deltas(&dqp->q_rtb, + qtrx->qt_rtblk_res, + qtrx->qt_rtblk_res_used, + qtrx->qt_rtbcount_delta); /* * Adjust the inode reservation. */ - if (qtrx->qt_ino_res != 0) { - ASSERT(qtrx->qt_ino_res >= - qtrx->qt_ino_res_used); - if (qtrx->qt_ino_res > qtrx->qt_ino_res_used) - dqp->q_ino.reserved -= (xfs_qcnt_t) - (qtrx->qt_ino_res - - qtrx->qt_ino_res_used); - } else { - if (qtrx->qt_icount_delta) - dqp->q_ino.reserved += - (xfs_qcnt_t)qtrx->qt_icount_delta; - } + ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used); + xfs_apply_quota_reservation_deltas(&dqp->q_ino, + qtrx->qt_ino_res, + qtrx->qt_ino_res_used, + qtrx->qt_icount_delta); ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count); ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
From: Darrick J. Wong <darrick.wong@oracle.com> Add all the xfs_dquot fields to the tracepoint for that type; add a new tracepoint type for the qtrx structure (dquot transaction deltas); and use our new tracepoints. This makes it easier for the author to trace changes to dquot counters for debugging. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/xfs_trace.h | 140 +++++++++++++++++++++++++++++++++++++++++++++- fs/xfs/xfs_trans_dquot.c | 21 +++++++ 2 files changed, 159 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 851f97dfe9e3..35b9dfd3984f 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -36,6 +36,7 @@ struct xfs_owner_info; struct xfs_trans_res; struct xfs_inobt_rec_incore; union xfs_btree_ptr; +struct xfs_dqtrx; #define XFS_ATTR_FILTER_FLAGS \ { XFS_ATTR_ROOT, "ROOT" }, \ @@ -867,37 +868,59 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, __field(unsigned, flags) __field(unsigned, nrefs) __field(unsigned long long, res_bcount) + __field(unsigned long long, res_rtbcount) + __field(unsigned long long, res_icount) + __field(unsigned long long, bcount) + __field(unsigned long long, rtbcount) __field(unsigned long long, icount) + __field(unsigned long long, blk_hardlimit) __field(unsigned long long, blk_softlimit) + __field(unsigned long long, rtb_hardlimit) + __field(unsigned long long, rtb_softlimit) __field(unsigned long long, ino_hardlimit) __field(unsigned long long, ino_softlimit) - ), \ + ), TP_fast_assign( __entry->dev = dqp->q_mount->m_super->s_dev; __entry->id = dqp->q_id; __entry->flags = dqp->dq_flags; __entry->nrefs = dqp->q_nrefs; + __entry->res_bcount = dqp->q_blk.reserved; + __entry->res_rtbcount = dqp->q_rtb.reserved; + __entry->res_icount = dqp->q_ino.reserved; + __entry->bcount = dqp->q_blk.count; + __entry->rtbcount = dqp->q_rtb.count; __entry->icount = dqp->q_ino.count; + __entry->blk_hardlimit = dqp->q_blk.hardlimit; __entry->blk_softlimit = dqp->q_blk.softlimit; + __entry->rtb_hardlimit = dqp->q_rtb.hardlimit; + __entry->rtb_softlimit = dqp->q_rtb.softlimit; __entry->ino_hardlimit = dqp->q_ino.hardlimit; __entry->ino_softlimit = dqp->q_ino.softlimit; ), - TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx " + TP_printk("dev %d:%d id 0x%x flags %s nrefs %u " + "res_bc 0x%llx res_rtbc 0x%llx res_ic 0x%llx " "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx " + "rtbcnt 0x%llx rtbhardlimit 0x%llx rtbsoftlimit 0x%llx " "icnt 0x%llx ihardlimit 0x%llx isoftlimit 0x%llx]", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->id, __print_flags(__entry->flags, "|", XFS_DQ_FLAGS), __entry->nrefs, __entry->res_bcount, + __entry->res_rtbcount, + __entry->res_icount, __entry->bcount, __entry->blk_hardlimit, __entry->blk_softlimit, + __entry->rtbcount, + __entry->rtb_hardlimit, + __entry->rtb_softlimit, __entry->icount, __entry->ino_hardlimit, __entry->ino_softlimit) @@ -928,6 +951,119 @@ DEFINE_DQUOT_EVENT(xfs_dqrele); DEFINE_DQUOT_EVENT(xfs_dqflush); DEFINE_DQUOT_EVENT(xfs_dqflush_force); DEFINE_DQUOT_EVENT(xfs_dqflush_done); +DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_before); +DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_after); + +#define XFS_QMOPT_FLAGS \ + { XFS_QMOPT_UQUOTA, "UQUOTA" }, \ + { XFS_QMOPT_PQUOTA, "PQUOTA" }, \ + { XFS_QMOPT_FORCE_RES, "FORCE_RES" }, \ + { XFS_QMOPT_SBVERSION, "SBVERSION" }, \ + { XFS_QMOPT_GQUOTA, "GQUOTA" }, \ + { XFS_QMOPT_INHERIT, "INHERIT" }, \ + { XFS_QMOPT_RES_REGBLKS, "RES_REGBLKS" }, \ + { XFS_QMOPT_RES_RTBLKS, "RES_RTBLKS" }, \ + { XFS_QMOPT_BCOUNT, "BCOUNT" }, \ + { XFS_QMOPT_ICOUNT, "ICOUNT" }, \ + { XFS_QMOPT_RTBCOUNT, "RTBCOUNT" }, \ + { XFS_QMOPT_DELBCOUNT, "DELBCOUNT" }, \ + { XFS_QMOPT_DELRTBCOUNT, "DELRTBCOUNT" }, \ + { XFS_QMOPT_RES_INOS, "RES_INOS" } + +TRACE_EVENT(xfs_trans_mod_dquot, + TP_PROTO(struct xfs_trans *tp, struct xfs_dquot *dqp, + unsigned int field, int64_t delta), + TP_ARGS(tp, dqp, field, delta), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned int, dqflags) + __field(unsigned int, dqid) + __field(unsigned int, field) + __field(int64_t, delta) + ), + TP_fast_assign( + __entry->dev = tp->t_mountp->m_super->s_dev; + __entry->dqflags = dqp->dq_flags; + __entry->dqid = dqp->q_id; + __entry->field = field; + __entry->delta = delta; + ), + TP_printk("dev %d:%d dquot %s id 0x%x %s delta %lld", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS), + __entry->dqid, + __print_flags(__entry->field, "|", XFS_QMOPT_FLAGS), + __entry->delta) +); + +DECLARE_EVENT_CLASS(xfs_dqtrx_class, + TP_PROTO(struct xfs_dqtrx *qtrx), + TP_ARGS(qtrx), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned int, dqflags) + __field(u32, dqid) + + __field(uint64_t, blk_res) + __field(int64_t, bcount_delta) + __field(int64_t, delbcnt_delta) + + __field(uint64_t, rtblk_res) + __field(uint64_t, rtblk_res_used) + __field(int64_t, rtbcount_delta) + __field(int64_t, delrtb_delta) + + __field(uint64_t, ino_res) + __field(uint64_t, ino_res_used) + __field(int64_t, icount_delta) + ), + TP_fast_assign( + __entry->dev = qtrx->qt_dquot->q_mount->m_super->s_dev; + __entry->dqflags = qtrx->qt_dquot->dq_flags; + __entry->dqid = qtrx->qt_dquot->q_id; + + __entry->blk_res = qtrx->qt_blk_res; + __entry->bcount_delta = qtrx->qt_bcount_delta; + __entry->delbcnt_delta = qtrx->qt_delbcnt_delta; + + __entry->rtblk_res = qtrx->qt_rtblk_res; + __entry->rtblk_res_used = qtrx->qt_rtblk_res_used; + __entry->rtbcount_delta = qtrx->qt_rtbcount_delta; + __entry->delrtb_delta = qtrx->qt_delrtb_delta; + + __entry->ino_res = qtrx->qt_ino_res; + __entry->ino_res_used = qtrx->qt_ino_res_used; + __entry->icount_delta = qtrx->qt_icount_delta; + ), + TP_printk("dev %d:%d dquot %s id 0x%x " + "blk_res %llu bcount_delta %lld delbcnt_delta %lld " + "rtblk_res %llu rtblk_res_used %llu rtbcount_delta %lld delrtb_delta %lld " + "ino_res %llu ino_res_used %llu icount_delta %lld", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS), + __entry->dqid, + + __entry->blk_res, + __entry->bcount_delta, + __entry->delbcnt_delta, + + __entry->rtblk_res, + __entry->rtblk_res_used, + __entry->rtbcount_delta, + __entry->delrtb_delta, + + __entry->ino_res, + __entry->ino_res_used, + __entry->icount_delta) +) + +#define DEFINE_DQTRX_EVENT(name) \ +DEFINE_EVENT(xfs_dqtrx_class, name, \ + TP_PROTO(struct xfs_dqtrx *qtrx), \ + TP_ARGS(qtrx)) +DEFINE_DQTRX_EVENT(xfs_trans_apply_dquot_deltas); +DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_before); +DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_after); DECLARE_EVENT_CLASS(xfs_loggrant_class, TP_PROTO(struct xlog *log, struct xlog_ticket *tic), diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 701923ea6c04..5689d9f1b748 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -15,6 +15,7 @@ #include "xfs_trans_priv.h" #include "xfs_quota.h" #include "xfs_qm.h" +#include "xfs_trace.h" STATIC void xfs_trans_alloc_dqinfo(xfs_trans_t *); @@ -203,6 +204,11 @@ xfs_trans_mod_dquot( if (qtrx->qt_dquot == NULL) qtrx->qt_dquot = dqp; + if (delta) { + trace_xfs_trans_mod_dquot_before(qtrx); + trace_xfs_trans_mod_dquot(tp, dqp, field, delta); + } + switch (field) { /* @@ -266,6 +272,10 @@ xfs_trans_mod_dquot( default: ASSERT(0); } + + if (delta) + trace_xfs_trans_mod_dquot_after(qtrx); + tp->t_flags |= XFS_TRANS_DQ_DIRTY; } @@ -391,6 +401,13 @@ xfs_trans_apply_dquot_deltas( qtrx->qt_delbcnt_delta; totalrtbdelta = qtrx->qt_rtbcount_delta + qtrx->qt_delrtb_delta; + + if (totalbdelta != 0 || totalrtbdelta != 0 || + qtrx->qt_icount_delta != 0) { + trace_xfs_trans_apply_dquot_deltas_before(dqp); + trace_xfs_trans_apply_dquot_deltas(qtrx); + } + #ifdef DEBUG if (totalbdelta < 0) ASSERT(dqp->q_blk.count >= -totalbdelta); @@ -410,6 +427,10 @@ xfs_trans_apply_dquot_deltas( if (totalrtbdelta) dqp->q_rtb.count += totalrtbdelta; + if (totalbdelta != 0 || totalrtbdelta != 0 || + qtrx->qt_icount_delta != 0) + trace_xfs_trans_apply_dquot_deltas_after(dqp); + /* * Get any default limits in use. * Start/reset the timer(s) if needed.
On 6/30/20 8:41 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we > can't lock the dquot buf to flush the dquot. This prevents the AIL from > blocking on the dquot, but it also forgets to clear the FREEING flag on > its way out. A subsequent purge attempt will see the FREEING flag is > set and bail out, which leads to dqpurge_all failing to purge all the > dquots. This causes unmounts and quotaoff operations to hang. > > Fixes: 8d3d7e2b35ea ("xfs: trylock underlying buffer on dquot flush") > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Ok Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_qm.c | 1 + > 1 file changed, 1 insertion(+) > > > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index d6cd83317344..938023dd8ce5 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -148,6 +148,7 @@ xfs_qm_dqpurge( > error = xfs_bwrite(bp); > xfs_buf_relse(bp); > } else if (error == -EAGAIN) { > + dqp->dq_flags &= ~XFS_DQ_FREEING; > goto out_unlock; > } > xfs_dqflock(dqp); >
On 6/30/20 8:42 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > xfs_trans_dqresv is the function that we use to make reservations > against resource quotas. Each resource contains two counters: the > q_core counter, which tracks resources allocated on disk; and the dquot > reservation counter, which tracks how much of that resource has either > been allocated or reserved by threads that are working on metadata > updates. > > For disk blocks, we compare the proposed reservation counter against the > hard and soft limits to decide if we're going to fail the operation. > However, for inodes we inexplicably compare against the q_core counter, > not the incore reservation count. > > Since the q_core counter is always lower than the reservation count and > we unlock the dquot between reservation and transaction commit, this > means that multiple threads can reserve the last inode count before we > hit the hard limit, and when they commit, we'll be well over the hard > limit. > > Fix this by checking against the incore inode reservation counter, since > we would appear to maintain that correctly (and that's what we report in > GETQUOTA). > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Ok, makes sense Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_trans_dquot.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index c0f73b82c055..ed0ce8b301b4 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -647,7 +647,7 @@ xfs_trans_dqresv( > } > } > if (ninos > 0) { > - total_count = be64_to_cpu(dqp->q_core.d_icount) + ninos; > + total_count = dqp->q_res_icount + ninos; > timer = be32_to_cpu(dqp->q_core.d_itimer); > warns = be16_to_cpu(dqp->q_core.d_iwarns); > warnlimit = defq->iwarnlimit; >
On 6/30/20 8:42 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > While loading dquot records off disk, make sure that the quota type > flags are the same between the incore dquot and the ondisk dquot. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Looks ok Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_dquot.c | 23 ++++++++++++++++++++--- > 1 file changed, 20 insertions(+), 3 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index d5b7f03e93c8..46c8ca83c04d 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -524,13 +524,27 @@ xfs_dquot_alloc( > } > > /* Copy the in-core quota fields in from the on-disk buffer. */ > -STATIC void > +STATIC int > xfs_dquot_from_disk( > struct xfs_dquot *dqp, > struct xfs_buf *bp) > { > struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset; > > + /* > + * The only field the verifier didn't check was the quota type flag, so > + * do that here. > + */ > + if ((dqp->dq_flags & XFS_DQ_ALLTYPES) != > + (ddqp->d_flags & XFS_DQ_ALLTYPES) || > + dqp->q_core.d_id != ddqp->d_id) { > + xfs_alert(bp->b_mount, > + "Metadata corruption detected at %pS, quota %u", > + __this_address, be32_to_cpu(dqp->q_core.d_id)); > + xfs_alert(bp->b_mount, "Unmount and run xfs_repair"); > + return -EFSCORRUPTED; > + } > + > /* copy everything from disk dquot to the incore dquot */ > memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot)); > > @@ -544,6 +558,7 @@ xfs_dquot_from_disk( > > /* initialize the dquot speculative prealloc thresholds */ > xfs_dquot_set_prealloc_limits(dqp); > + return 0; > } > > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > @@ -617,9 +632,11 @@ xfs_qm_dqread( > * further. > */ > ASSERT(xfs_buf_islocked(bp)); > - xfs_dquot_from_disk(dqp, bp); > - > + error = xfs_dquot_from_disk(dqp, bp); > xfs_buf_relse(bp); > + if (error) > + goto err; > + > *dqpp = dqp; > return error; > >
On Tuesday 30 June 2020 9:11:56 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we > can't lock the dquot buf to flush the dquot. This prevents the AIL from > blocking on the dquot, but it also forgets to clear the FREEING flag on > its way out. A subsequent purge attempt will see the FREEING flag is > set and bail out, which leads to dqpurge_all failing to purge all the > dquots. This causes unmounts and quotaoff operations to hang. > xfs_qm_dqpurge() checks for the presence of XFS_DQ_FREEING. If it is set, it indicates that another task is freeing this dquot. A failed read operation could return -EAGAIN and hence xfs_qm_dqpurge() returning without clearing XFS_DQ_FREEING would mean that future invocations of this function would turn out to be a nop and hence the corresponding dquot would linger around forever. Hence the fix is correct. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Fixes: 8d3d7e2b35ea ("xfs: trylock underlying buffer on dquot flush") > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_qm.c | 1 + > 1 file changed, 1 insertion(+) > > > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index d6cd83317344..938023dd8ce5 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -148,6 +148,7 @@ xfs_qm_dqpurge( > error = xfs_bwrite(bp); > xfs_buf_relse(bp); > } else if (error == -EAGAIN) { > + dqp->dq_flags &= ~XFS_DQ_FREEING; > goto out_unlock; > } > xfs_dqflock(dqp); > > -- chandan
On Tuesday 30 June 2020 9:12:02 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > xfs_trans_dqresv is the function that we use to make reservations > against resource quotas. Each resource contains two counters: the > q_core counter, which tracks resources allocated on disk; and the dquot > reservation counter, which tracks how much of that resource has either > been allocated or reserved by threads that are working on metadata > updates. > > For disk blocks, we compare the proposed reservation counter against the > hard and soft limits to decide if we're going to fail the operation. > However, for inodes we inexplicably compare against the q_core counter, > not the incore reservation count. > > Since the q_core counter is always lower than the reservation count and > we unlock the dquot between reservation and transaction commit, this > means that multiple threads can reserve the last inode count before we > hit the hard limit, and when they commit, we'll be well over the hard > limit. > > Fix this by checking against the incore inode reservation counter, since > we would appear to maintain that correctly (and that's what we report in > GETQUOTA). > As mentioned above, q_core.d_icount's value can be less than what has been reserved by various running tasks. Hence deriving new reservation count from q_core.d_icount is incorrect. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_trans_dquot.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index c0f73b82c055..ed0ce8b301b4 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -647,7 +647,7 @@ xfs_trans_dqresv( > } > } > if (ninos > 0) { > - total_count = be64_to_cpu(dqp->q_core.d_icount) + ninos; > + total_count = dqp->q_res_icount + ninos; > timer = be32_to_cpu(dqp->q_core.d_itimer); > warns = be16_to_cpu(dqp->q_core.d_iwarns); > warnlimit = defq->iwarnlimit; > > -- chandan
On Tuesday 30 June 2020 9:12:09 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > While loading dquot records off disk, make sure that the quota type > flags are the same between the incore dquot and the ondisk dquot. > The changes look good to me. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_dquot.c | 23 ++++++++++++++++++++--- > 1 file changed, 20 insertions(+), 3 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index d5b7f03e93c8..46c8ca83c04d 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -524,13 +524,27 @@ xfs_dquot_alloc( > } > > /* Copy the in-core quota fields in from the on-disk buffer. */ > -STATIC void > +STATIC int > xfs_dquot_from_disk( > struct xfs_dquot *dqp, > struct xfs_buf *bp) > { > struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset; > > + /* > + * The only field the verifier didn't check was the quota type flag, so > + * do that here. > + */ > + if ((dqp->dq_flags & XFS_DQ_ALLTYPES) != > + (ddqp->d_flags & XFS_DQ_ALLTYPES) || > + dqp->q_core.d_id != ddqp->d_id) { > + xfs_alert(bp->b_mount, > + "Metadata corruption detected at %pS, quota %u", > + __this_address, be32_to_cpu(dqp->q_core.d_id)); > + xfs_alert(bp->b_mount, "Unmount and run xfs_repair"); > + return -EFSCORRUPTED; > + } > + > /* copy everything from disk dquot to the incore dquot */ > memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot)); > > @@ -544,6 +558,7 @@ xfs_dquot_from_disk( > > /* initialize the dquot speculative prealloc thresholds */ > xfs_dquot_set_prealloc_limits(dqp); > + return 0; > } > > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > @@ -617,9 +632,11 @@ xfs_qm_dqread( > * further. > */ > ASSERT(xfs_buf_islocked(bp)); > - xfs_dquot_from_disk(dqp, bp); > - > + error = xfs_dquot_from_disk(dqp, bp); > xfs_buf_relse(bp); > + if (error) > + goto err; > + > *dqpp = dqp; > return error; > > > -- chandan
On Tuesday 30 June 2020 9:12:23 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Add a dquot id field to the incore dquot, and use that instead of the > one in qcore. This eliminates a bunch of endian conversions and will > eventually allow us to remove qcore entirely. > > We also rearrange the start of xfs_dquot to remove padding holes, saving > 8 bytes. The changes look good to me. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/scrub/quota.c | 19 ++++++++++++------- > fs/xfs/xfs_dquot.c | 25 +++++++++++-------------- > fs/xfs/xfs_dquot.h | 5 +++-- > fs/xfs/xfs_dquot_item.c | 2 +- > fs/xfs/xfs_qm.c | 22 ++++++++++------------ > fs/xfs/xfs_qm_syscalls.c | 4 ++-- > fs/xfs/xfs_trace.h | 2 +- > fs/xfs/xfs_trans_dquot.c | 8 +++----- > 8 files changed, 43 insertions(+), 44 deletions(-) > > > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index 710659d3fa28..9a271f115882 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -92,7 +92,6 @@ xchk_quota_item( > unsigned long long icount; > unsigned long long rcount; > xfs_ino_t fs_icount; > - xfs_dqid_t id = be32_to_cpu(d->d_id); > int error = 0; > > if (xchk_should_terminate(sc, &error)) > @@ -102,11 +101,11 @@ xchk_quota_item( > * Except for the root dquot, the actual dquot we got must either have > * the same or higher id as we saw before. > */ > - offset = id / qi->qi_dqperchunk; > - if (id && id <= sqi->last_id) > + offset = dq->q_id / qi->qi_dqperchunk; > + if (dq->q_id && dq->q_id <= sqi->last_id) > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > > - sqi->last_id = id; > + sqi->last_id = dq->q_id; > > if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > @@ -171,13 +170,19 @@ xchk_quota_item( > * lower limit than the actual usage. However, we flag it for > * admin review. > */ > - if (id != 0 && bhard != 0 && bcount > bhard) > + if (dq->q_id == 0) > + goto out; > + > + if (bhard != 0 && bcount > bhard) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > - if (id != 0 && ihard != 0 && icount > ihard) > + > + if (ihard != 0 && icount > ihard) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > - if (id != 0 && rhard != 0 && rcount > rhard) > + > + if (rhard != 0 && rcount > rhard) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > > +out: > if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) > return -EFSCORRUPTED; > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 59d1bce34a98..76b35888e726 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -74,7 +74,7 @@ xfs_qm_adjust_dqlimits( > struct xfs_def_quota *defq; > int prealloc = 0; > > - ASSERT(d->d_id); > + ASSERT(dq->q_id); > defq = xfs_get_defquota(q, xfs_dquot_type(dq)); > > if (defq->bsoftlimit && !d->d_blk_softlimit) { > @@ -120,7 +120,7 @@ xfs_qm_adjust_dqtimers( > struct xfs_disk_dquot *d = &dq->q_core; > struct xfs_def_quota *defq; > > - ASSERT(d->d_id); > + ASSERT(dq->q_id); > defq = xfs_get_defquota(qi, xfs_dquot_type(dq)); > > #ifdef DEBUG > @@ -365,7 +365,7 @@ xfs_dquot_disk_alloc( > * Make a chunk of dquots out of this buffer and log > * the entire thing. > */ > - xfs_qm_init_dquot_blk(tp, mp, be32_to_cpu(dqp->q_core.d_id), > + xfs_qm_init_dquot_blk(tp, mp, dqp->q_id, > dqp->dq_flags & XFS_DQ_ALLTYPES, bp); > xfs_buf_set_ref(bp, XFS_DQUOT_REF); > > @@ -478,7 +478,7 @@ xfs_dquot_alloc( > dqp = kmem_zone_zalloc(xfs_qm_dqzone, 0); > > dqp->dq_flags = type; > - dqp->q_core.d_id = cpu_to_be32(id); > + dqp->q_id = id; > dqp->q_mount = mp; > INIT_LIST_HEAD(&dqp->q_lru); > mutex_init(&dqp->q_qlock); > @@ -537,10 +537,10 @@ xfs_dquot_from_disk( > */ > if ((dqp->dq_flags & XFS_DQ_ALLTYPES) != > (ddqp->d_flags & XFS_DQ_ALLTYPES) || > - dqp->q_core.d_id != ddqp->d_id) { > + dqp->q_id != be32_to_cpu(ddqp->d_id)) { > xfs_alert(bp->b_mount, > "Metadata corruption detected at %pS, quota %u", > - __this_address, be32_to_cpu(dqp->q_core.d_id)); > + __this_address, dqp->q_id); > xfs_alert(bp->b_mount, "Unmount and run xfs_repair"); > return -EFSCORRUPTED; > } > @@ -1177,11 +1177,10 @@ xfs_qm_dqflush( > ddqp = &dqb->dd_diskdq; > > /* sanity check the in-core structure before we flush */ > - fa = xfs_dquot_verify(mp, &dqp->q_core, be32_to_cpu(dqp->q_core.d_id), > - 0); > + fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0); > if (fa) { > xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > - be32_to_cpu(dqp->q_core.d_id), fa); > + dqp->q_id, fa); > xfs_buf_relse(bp); > error = -EFSCORRUPTED; > goto out_abort; > @@ -1190,7 +1189,7 @@ xfs_qm_dqflush( > fa = xfs_qm_dqflush_check(dqp); > if (fa) { > xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > - be32_to_cpu(dqp->q_core.d_id), fa); > + dqp->q_id, fa); > xfs_buf_relse(bp); > error = -EFSCORRUPTED; > goto out_abort; > @@ -1263,8 +1262,7 @@ xfs_dqlock2( > { > if (d1 && d2) { > ASSERT(d1 != d2); > - if (be32_to_cpu(d1->q_core.d_id) > > - be32_to_cpu(d2->q_core.d_id)) { > + if (d1->q_id > d2->q_id) { > mutex_lock(&d2->q_qlock); > mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED); > } else { > @@ -1332,9 +1330,8 @@ xfs_qm_dqiterate( > return error; > > error = iter_fn(dq, dqtype, priv); > - id = be32_to_cpu(dq->q_core.d_id); > + id = dq->q_id + 1; > xfs_qm_dqput(dq); > - id++; > } while (error == 0 && id != 0); > > return error; > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 1b1a4261a580..5ea1f1515979 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -31,12 +31,13 @@ enum { > * The incore dquot structure > */ > struct xfs_dquot { > - uint dq_flags; > struct list_head q_lru; > struct xfs_mount *q_mount; > + xfs_dqid_t q_id; > + uint dq_flags; > uint q_nrefs; > - xfs_daddr_t q_blkno; > int q_bufoffset; > + xfs_daddr_t q_blkno; > xfs_fileoff_t q_fileoffset; > > struct xfs_disk_dquot q_core; > diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c > index ff0ab65cf413..378d919997f1 100644 > --- a/fs/xfs/xfs_dquot_item.c > +++ b/fs/xfs/xfs_dquot_item.c > @@ -53,7 +53,7 @@ xfs_qm_dquot_logitem_format( > qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT); > qlf->qlf_type = XFS_LI_DQUOT; > qlf->qlf_size = 2; > - qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id); > + qlf->qlf_id = qlip->qli_dquot->q_id; > qlf->qlf_blkno = qlip->qli_dquot->q_blkno; > qlf->qlf_len = 1; > qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset; > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 632025c2f00b..95e51186bd57 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -79,7 +79,7 @@ xfs_qm_dquot_walk( > for (i = 0; i < nr_found; i++) { > struct xfs_dquot *dqp = batch[i]; > > - next_index = be32_to_cpu(dqp->q_core.d_id) + 1; > + next_index = dqp->q_id + 1; > > error = execute(batch[i], data); > if (error == -EAGAIN) { > @@ -161,8 +161,7 @@ xfs_qm_dqpurge( > xfs_dqfunlock(dqp); > xfs_dqunlock(dqp); > > - radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), > - be32_to_cpu(dqp->q_core.d_id)); > + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id); > qi->qi_dquots--; > > /* > @@ -1112,7 +1111,7 @@ xfs_qm_quotacheck_dqadjust( > * > * There are no timers for the default values set in the root dquot. > */ > - if (dqp->q_core.d_id) { > + if (dqp->q_id) { > xfs_qm_adjust_dqlimits(mp, dqp); > xfs_qm_adjust_dqtimers(mp, dqp); > } > @@ -1598,8 +1597,7 @@ xfs_qm_dqfree_one( > struct xfs_quotainfo *qi = mp->m_quotainfo; > > mutex_lock(&qi->qi_tree_lock); > - radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), > - be32_to_cpu(dqp->q_core.d_id)); > + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id); > > qi->qi_dquots--; > mutex_unlock(&qi->qi_tree_lock); > @@ -1823,7 +1821,7 @@ xfs_qm_vop_chown_reserve( > XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS; > > if (XFS_IS_UQUOTA_ON(mp) && udqp && > - i_uid_read(VFS_I(ip)) != be32_to_cpu(udqp->q_core.d_id)) { > + i_uid_read(VFS_I(ip)) != udqp->q_id) { > udq_delblks = udqp; > /* > * If there are delayed allocation blocks, then we have to > @@ -1836,7 +1834,7 @@ xfs_qm_vop_chown_reserve( > } > } > if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp && > - i_gid_read(VFS_I(ip)) != be32_to_cpu(gdqp->q_core.d_id)) { > + i_gid_read(VFS_I(ip)) != gdqp->q_id) { > gdq_delblks = gdqp; > if (delblks) { > ASSERT(ip->i_gdquot); > @@ -1845,7 +1843,7 @@ xfs_qm_vop_chown_reserve( > } > > if (XFS_IS_PQUOTA_ON(ip->i_mount) && pdqp && > - ip->i_d.di_projid != be32_to_cpu(pdqp->q_core.d_id)) { > + ip->i_d.di_projid != pdqp->q_id) { > pdq_delblks = pdqp; > if (delblks) { > ASSERT(ip->i_pdquot); > @@ -1929,21 +1927,21 @@ xfs_qm_vop_create_dqattach( > > if (udqp && XFS_IS_UQUOTA_ON(mp)) { > ASSERT(ip->i_udquot == NULL); > - ASSERT(i_uid_read(VFS_I(ip)) == be32_to_cpu(udqp->q_core.d_id)); > + ASSERT(i_uid_read(VFS_I(ip)) == udqp->q_id); > > ip->i_udquot = xfs_qm_dqhold(udqp); > xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1); > } > if (gdqp && XFS_IS_GQUOTA_ON(mp)) { > ASSERT(ip->i_gdquot == NULL); > - ASSERT(i_gid_read(VFS_I(ip)) == be32_to_cpu(gdqp->q_core.d_id)); > + ASSERT(i_gid_read(VFS_I(ip)) == gdqp->q_id); > > ip->i_gdquot = xfs_qm_dqhold(gdqp); > xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1); > } > if (pdqp && XFS_IS_PQUOTA_ON(mp)) { > ASSERT(ip->i_pdquot == NULL); > - ASSERT(ip->i_d.di_projid == be32_to_cpu(pdqp->q_core.d_id)); > + ASSERT(ip->i_d.di_projid == pdqp->q_id); > > ip->i_pdquot = xfs_qm_dqhold(pdqp); > xfs_trans_mod_dquot(tp, pdqp, XFS_TRANS_DQ_ICOUNT, 1); > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 8cbb65f01bf1..90a11e7daf92 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -656,7 +656,7 @@ xfs_qm_scall_getquota_fill_qc( > if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) || > (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) || > (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) && > - dqp->q_core.d_id != 0) { > + dqp->q_id != 0) { > if ((dst->d_space > dst->d_spc_softlimit) && > (dst->d_spc_softlimit > 0)) { > ASSERT(dst->d_spc_timer != 0); > @@ -723,7 +723,7 @@ xfs_qm_scall_getquota_next( > return error; > > /* Fill in the ID we actually read from disk */ > - *id = be32_to_cpu(dqp->q_core.d_id); > + *id = dqp->q_id; > > xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); > > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 2c5df8315351..78d9dbc7614d 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -876,7 +876,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, > ), \ > TP_fast_assign( > __entry->dev = dqp->q_mount->m_super->s_dev; > - __entry->id = be32_to_cpu(dqp->q_core.d_id); > + __entry->id = dqp->q_id; > __entry->flags = dqp->dq_flags; > __entry->nrefs = dqp->q_nrefs; > __entry->res_bcount = dqp->q_res_bcount; > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index ed0ce8b301b4..a2656ec6ea76 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -386,7 +386,7 @@ xfs_trans_apply_dquot_deltas( > * Get any default limits in use. > * Start/reset the timer(s) if needed. > */ > - if (d->d_id) { > + if (dqp->q_id) { > xfs_qm_adjust_dqlimits(tp->t_mountp, dqp); > xfs_qm_adjust_dqtimers(tp->t_mountp, dqp); > } > @@ -558,8 +558,7 @@ xfs_quota_warn( > else > qtype = GRPQUOTA; > > - quota_send_warning(make_kqid(&init_user_ns, qtype, > - be32_to_cpu(dqp->q_core.d_id)), > + quota_send_warning(make_kqid(&init_user_ns, qtype, dqp->q_id), > mp->m_super->s_dev, type); > } > > @@ -618,8 +617,7 @@ xfs_trans_dqresv( > resbcountp = &dqp->q_res_rtbcount; > } > > - if ((flags & XFS_QMOPT_FORCE_RES) == 0 && > - dqp->q_core.d_id && > + if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_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)))) { > > -- chandan
On Tuesday 30 June 2020 9:12:29 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Introduce a new struct xfs_dquot_res that we'll use to track all the > incore data for a particular resource type (block, inode, rt block). > This will help us (once we've eliminated q_core) to declutter quota > functions that currently open-code field access or pass around fields > around explicitly. > The changes are logically correct. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_dquot.c | 6 +++--- > fs/xfs/xfs_dquot.h | 18 +++++++++++------- > fs/xfs/xfs_iomap.c | 6 +++--- > fs/xfs/xfs_qm.c | 6 +++--- > fs/xfs/xfs_qm_bhv.c | 8 ++++---- > fs/xfs/xfs_qm_syscalls.c | 6 +++--- > fs/xfs/xfs_trace.h | 2 +- > fs/xfs/xfs_trans_dquot.c | 42 +++++++++++++++++++++--------------------- > 8 files changed, 49 insertions(+), 45 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 76b35888e726..03624a8f0566 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -552,9 +552,9 @@ xfs_dquot_from_disk( > * Reservation counters are defined as reservation plus current usage > * to avoid having to add every time. > */ > - dqp->q_res_bcount = be64_to_cpu(ddqp->d_bcount); > - dqp->q_res_icount = be64_to_cpu(ddqp->d_icount); > - dqp->q_res_rtbcount = be64_to_cpu(ddqp->d_rtbcount); > + dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount); > + dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount); > + dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount); > > /* initialize the dquot speculative prealloc thresholds */ > xfs_dquot_set_prealloc_limits(dqp); > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 5ea1f1515979..cb20df1e774f 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -27,6 +27,11 @@ enum { > XFS_QLOWSP_MAX > }; > > +struct xfs_dquot_res { > + /* Total resources allocated and reserved. */ > + xfs_qcnt_t reserved; > +}; > + > /* > * The incore dquot structure > */ > @@ -40,14 +45,13 @@ struct xfs_dquot { > xfs_daddr_t q_blkno; > xfs_fileoff_t q_fileoffset; > > + struct xfs_dquot_res q_blk; /* regular blocks */ > + struct xfs_dquot_res q_ino; /* inodes */ > + struct xfs_dquot_res q_rtb; /* realtime blocks */ > + > struct xfs_disk_dquot q_core; > struct xfs_dq_logitem q_logitem; > - /* total regular nblks used+reserved */ > - xfs_qcnt_t q_res_bcount; > - /* total inos allocd+reserved */ > - xfs_qcnt_t q_res_icount; > - /* total realtime blks used+reserved */ > - xfs_qcnt_t q_res_rtbcount; > + > xfs_qcnt_t q_prealloc_lo_wmark; > xfs_qcnt_t q_prealloc_hi_wmark; > int64_t q_low_space[XFS_QLOWSP_MAX]; > @@ -138,7 +142,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_res_bcount; > + freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_blk.reserved; > if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT]) > return true; > > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > index b9a8c3798e08..f60a6e44363b 100644 > --- a/fs/xfs/xfs_iomap.c > +++ b/fs/xfs/xfs_iomap.c > @@ -307,7 +307,7 @@ xfs_quota_need_throttle( > return false; > > /* under the lo watermark, no throttle */ > - if (dq->q_res_bcount + alloc_blocks < dq->q_prealloc_lo_wmark) > + if (dq->q_blk.reserved + alloc_blocks < dq->q_prealloc_lo_wmark) > return false; > > return true; > @@ -326,13 +326,13 @@ xfs_quota_calc_throttle( > struct xfs_dquot *dq = xfs_inode_dquot(ip, type); > > /* no dq, or over hi wmark, squash the prealloc completely */ > - if (!dq || dq->q_res_bcount >= dq->q_prealloc_hi_wmark) { > + if (!dq || dq->q_blk.reserved >= dq->q_prealloc_hi_wmark) { > *qblocks = 0; > *qfreesp = 0; > return; > } > > - freesp = dq->q_prealloc_hi_wmark - dq->q_res_bcount; > + freesp = dq->q_prealloc_hi_wmark - dq->q_blk.reserved; > if (freesp < dq->q_low_space[XFS_QLOWSP_5_PCNT]) { > shift = 2; > if (freesp < dq->q_low_space[XFS_QLOWSP_3_PCNT]) > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 95e51186bd57..6ce3a4402041 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -1096,14 +1096,14 @@ xfs_qm_quotacheck_dqadjust( > * resource usage. > */ > be64_add_cpu(&dqp->q_core.d_icount, 1); > - dqp->q_res_icount++; > + dqp->q_ino.reserved++; > if (nblks) { > be64_add_cpu(&dqp->q_core.d_bcount, nblks); > - dqp->q_res_bcount += nblks; > + dqp->q_blk.reserved += nblks; > } > if (rtblks) { > be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks); > - dqp->q_res_rtbcount += rtblks; > + dqp->q_rtb.reserved += rtblks; > } > > /* > diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c > index fc2fa418919f..94b2b4b0fc17 100644 > --- a/fs/xfs/xfs_qm_bhv.c > +++ b/fs/xfs/xfs_qm_bhv.c > @@ -29,8 +29,8 @@ xfs_fill_statvfs_from_dquot( > if (limit && statp->f_blocks > limit) { > statp->f_blocks = limit; > statp->f_bfree = statp->f_bavail = > - (statp->f_blocks > dqp->q_res_bcount) ? > - (statp->f_blocks - dqp->q_res_bcount) : 0; > + (statp->f_blocks > dqp->q_blk.reserved) ? > + (statp->f_blocks - dqp->q_blk.reserved) : 0; > } > > limit = dqp->q_core.d_ino_softlimit ? > @@ -39,8 +39,8 @@ xfs_fill_statvfs_from_dquot( > if (limit && statp->f_files > limit) { > statp->f_files = limit; > statp->f_ffree = > - (statp->f_files > dqp->q_res_icount) ? > - (statp->f_files - dqp->q_res_icount) : 0; > + (statp->f_files > dqp->q_ino.reserved) ? > + (statp->f_files - dqp->q_ino.reserved) : 0; > } > } > > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 90a11e7daf92..56fe80395679 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -625,8 +625,8 @@ xfs_qm_scall_getquota_fill_qc( > XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit)); > dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); > dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); > - dst->d_space = XFS_FSB_TO_B(mp, dqp->q_res_bcount); > - dst->d_ino_count = dqp->q_res_icount; > + dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); > + dst->d_ino_count = dqp->q_ino.reserved; > dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); > dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); > dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); > @@ -635,7 +635,7 @@ xfs_qm_scall_getquota_fill_qc( > XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit)); > dst->d_rt_spc_softlimit = > XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit)); > - dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_res_rtbcount); > + dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); > dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); > > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 78d9dbc7614d..71567ed367f2 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -879,7 +879,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, > __entry->id = dqp->q_id; > __entry->flags = dqp->dq_flags; > __entry->nrefs = dqp->q_nrefs; > - __entry->res_bcount = dqp->q_res_bcount; > + __entry->res_bcount = dqp->q_blk.reserved; > __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); > __entry->icount = be64_to_cpu(dqp->q_core.d_icount); > __entry->blk_hardlimit = > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index a2656ec6ea76..469bf7946d3d 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -409,11 +409,11 @@ xfs_trans_apply_dquot_deltas( > > if (qtrx->qt_blk_res != blk_res_used) { > if (qtrx->qt_blk_res > blk_res_used) > - dqp->q_res_bcount -= (xfs_qcnt_t) > + dqp->q_blk.reserved -= (xfs_qcnt_t) > (qtrx->qt_blk_res - > blk_res_used); > else > - dqp->q_res_bcount -= (xfs_qcnt_t) > + dqp->q_blk.reserved -= (xfs_qcnt_t) > (blk_res_used - > qtrx->qt_blk_res); > } > @@ -426,7 +426,7 @@ xfs_trans_apply_dquot_deltas( > * deliberately skip quota reservations. > */ > if (qtrx->qt_bcount_delta) { > - dqp->q_res_bcount += > + dqp->q_blk.reserved += > (xfs_qcnt_t)qtrx->qt_bcount_delta; > } > } > @@ -437,17 +437,17 @@ xfs_trans_apply_dquot_deltas( > if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) { > if (qtrx->qt_rtblk_res > > qtrx->qt_rtblk_res_used) > - dqp->q_res_rtbcount -= (xfs_qcnt_t) > + dqp->q_rtb.reserved -= (xfs_qcnt_t) > (qtrx->qt_rtblk_res - > qtrx->qt_rtblk_res_used); > else > - dqp->q_res_rtbcount -= (xfs_qcnt_t) > + dqp->q_rtb.reserved -= (xfs_qcnt_t) > (qtrx->qt_rtblk_res_used - > qtrx->qt_rtblk_res); > } > } else { > if (qtrx->qt_rtbcount_delta) > - dqp->q_res_rtbcount += > + dqp->q_rtb.reserved += > (xfs_qcnt_t)qtrx->qt_rtbcount_delta; > } > > @@ -458,20 +458,20 @@ xfs_trans_apply_dquot_deltas( > ASSERT(qtrx->qt_ino_res >= > qtrx->qt_ino_res_used); > if (qtrx->qt_ino_res > qtrx->qt_ino_res_used) > - dqp->q_res_icount -= (xfs_qcnt_t) > + dqp->q_ino.reserved -= (xfs_qcnt_t) > (qtrx->qt_ino_res - > qtrx->qt_ino_res_used); > } else { > if (qtrx->qt_icount_delta) > - dqp->q_res_icount += > + dqp->q_ino.reserved += > (xfs_qcnt_t)qtrx->qt_icount_delta; > } > > - ASSERT(dqp->q_res_bcount >= > + ASSERT(dqp->q_blk.reserved >= > be64_to_cpu(dqp->q_core.d_bcount)); > - ASSERT(dqp->q_res_icount >= > + ASSERT(dqp->q_ino.reserved >= > be64_to_cpu(dqp->q_core.d_icount)); > - ASSERT(dqp->q_res_rtbcount >= > + ASSERT(dqp->q_rtb.reserved >= > be64_to_cpu(dqp->q_core.d_rtbcount)); > } > } > @@ -516,7 +516,7 @@ xfs_trans_unreserve_and_mod_dquots( > if (qtrx->qt_blk_res) { > xfs_dqlock(dqp); > locked = true; > - dqp->q_res_bcount -= > + dqp->q_blk.reserved -= > (xfs_qcnt_t)qtrx->qt_blk_res; > } > if (qtrx->qt_ino_res) { > @@ -524,7 +524,7 @@ xfs_trans_unreserve_and_mod_dquots( > xfs_dqlock(dqp); > locked = true; > } > - dqp->q_res_icount -= > + dqp->q_ino.reserved -= > (xfs_qcnt_t)qtrx->qt_ino_res; > } > > @@ -533,7 +533,7 @@ xfs_trans_unreserve_and_mod_dquots( > xfs_dqlock(dqp); > locked = true; > } > - dqp->q_res_rtbcount -= > + dqp->q_rtb.reserved -= > (xfs_qcnt_t)qtrx->qt_rtblk_res; > } > if (locked) > @@ -602,7 +602,7 @@ xfs_trans_dqresv( > timer = be32_to_cpu(dqp->q_core.d_btimer); > warns = be16_to_cpu(dqp->q_core.d_bwarns); > warnlimit = defq->bwarnlimit; > - resbcountp = &dqp->q_res_bcount; > + resbcountp = &dqp->q_blk.reserved; > } else { > ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); > hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit); > @@ -614,7 +614,7 @@ xfs_trans_dqresv( > timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > warns = be16_to_cpu(dqp->q_core.d_rtbwarns); > warnlimit = defq->rtbwarnlimit; > - resbcountp = &dqp->q_res_rtbcount; > + resbcountp = &dqp->q_rtb.reserved; > } > > if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id && > @@ -675,11 +675,11 @@ xfs_trans_dqresv( > > /* > * Change the reservation, but not the actual usage. > - * Note that q_res_bcount = q_core.d_bcount + resv > + * Note that q_blk.reserved = q_core.d_bcount + resv > */ > (*resbcountp) += (xfs_qcnt_t)nblks; > if (ninos != 0) > - dqp->q_res_icount += (xfs_qcnt_t)ninos; > + dqp->q_ino.reserved += (xfs_qcnt_t)ninos; > > /* > * note the reservation amt in the trans struct too, > @@ -700,9 +700,9 @@ xfs_trans_dqresv( > 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)); > + ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount)); > + ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount)); > + ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount)); > > xfs_dqunlock(dqp); > return 0; > > -- chandan
On Tuesday 30 June 2020 9:12:36 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > 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. > The changes are logically correct. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/scrub/quota.c | 36 ++++-------- > fs/xfs/xfs_dquot.c | 136 ++++++++++++++++++++++++++-------------------- > fs/xfs/xfs_dquot.h | 6 ++ > fs/xfs/xfs_qm.c | 14 ++--- > fs/xfs/xfs_qm.h | 12 ++-- > fs/xfs/xfs_qm_bhv.c | 12 ++-- > fs/xfs/xfs_qm_syscalls.c | 40 ++++++-------- > fs/xfs/xfs_trace.h | 12 +--- > fs/xfs/xfs_trans_dquot.c | 12 ++-- > 9 files changed, 139 insertions(+), 141 deletions(-) > > > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index 9a271f115882..1a1c6996fc69 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -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; > @@ -110,15 +104,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 > @@ -127,19 +112,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. */ > @@ -173,13 +158,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: > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 03624a8f0566..63f744bcbc90 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -70,29 +70,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); > @@ -124,82 +123,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; > } > } > @@ -290,8 +274,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 > @@ -569,6 +559,12 @@ xfs_dquot_to_disk( > { > memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); > ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK; > + 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. */ > @@ -1123,9 +1119,29 @@ static xfs_failaddr_t > xfs_qm_dqflush_check( > struct xfs_dquot *dqp) > { > + struct xfs_disk_dquot *ddq = &dqp->q_core; > + > if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) > 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; > } > > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index cb20df1e774f..edb49788c476 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -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; > }; > > /* > @@ -142,7 +146,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; > > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 6ce3a4402041..54fc3aac1a68 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -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); > } > > diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h > index 43b4650cdcdf..84cb8af468b7 100644 > --- a/fs/xfs/xfs_qm.h > +++ b/fs/xfs/xfs_qm.h > @@ -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) > diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c > index 94b2b4b0fc17..0993217e5ac8 100644 > --- a/fs/xfs/xfs_qm_bhv.c > +++ b/fs/xfs/xfs_qm_bhv.c > @@ -23,9 +23,9 @@ xfs_fill_statvfs_from_dquot( > { > uint64_t limit; > > - limit = dqp->q_core.d_blk_softlimit ? > - be64_to_cpu(dqp->q_core.d_blk_softlimit) : > - be64_to_cpu(dqp->q_core.d_blk_hardlimit); > + limit = dqp->q_blk.softlimit ? > + dqp->q_blk.softlimit : > + dqp->q_blk.hardlimit; > if (limit && statp->f_blocks > limit) { > statp->f_blocks = limit; > statp->f_bfree = statp->f_bavail = > @@ -33,9 +33,9 @@ xfs_fill_statvfs_from_dquot( > (statp->f_blocks - dqp->q_blk.reserved) : 0; > } > > - limit = dqp->q_core.d_ino_softlimit ? > - be64_to_cpu(dqp->q_core.d_ino_softlimit) : > - be64_to_cpu(dqp->q_core.d_ino_hardlimit); > + limit = dqp->q_ino.softlimit ? > + dqp->q_ino.softlimit : > + dqp->q_ino.hardlimit; > if (limit && statp->f_files > limit) { > statp->f_files = limit; > statp->f_ffree = > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 56fe80395679..ab596d389e3e 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -495,13 +495,13 @@ xfs_qm_scall_setqlim( > */ > hard = (newlim->d_fieldmask & QC_SPC_HARD) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : > - be64_to_cpu(ddq->d_blk_hardlimit); > + dqp->q_blk.hardlimit; > soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : > - be64_to_cpu(ddq->d_blk_softlimit); > + dqp->q_blk.softlimit; > if (hard == 0 || hard >= soft) { > - ddq->d_blk_hardlimit = cpu_to_be64(hard); > - ddq->d_blk_softlimit = cpu_to_be64(soft); > + dqp->q_blk.hardlimit = hard; > + dqp->q_blk.softlimit = soft; > xfs_dquot_set_prealloc_limits(dqp); > if (id == 0) { > defq->bhardlimit = hard; > @@ -512,13 +512,13 @@ xfs_qm_scall_setqlim( > } > hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : > - be64_to_cpu(ddq->d_rtb_hardlimit); > + dqp->q_rtb.hardlimit; > soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : > - be64_to_cpu(ddq->d_rtb_softlimit); > + dqp->q_rtb.softlimit; > if (hard == 0 || hard >= soft) { > - ddq->d_rtb_hardlimit = cpu_to_be64(hard); > - ddq->d_rtb_softlimit = cpu_to_be64(soft); > + dqp->q_rtb.hardlimit = hard; > + dqp->q_rtb.softlimit = soft; > if (id == 0) { > defq->rtbhardlimit = hard; > defq->rtbsoftlimit = soft; > @@ -529,13 +529,13 @@ xfs_qm_scall_setqlim( > > hard = (newlim->d_fieldmask & QC_INO_HARD) ? > (xfs_qcnt_t) newlim->d_ino_hardlimit : > - be64_to_cpu(ddq->d_ino_hardlimit); > + dqp->q_ino.hardlimit; > soft = (newlim->d_fieldmask & QC_INO_SOFT) ? > (xfs_qcnt_t) newlim->d_ino_softlimit : > - be64_to_cpu(ddq->d_ino_softlimit); > + dqp->q_ino.softlimit; > if (hard == 0 || hard >= soft) { > - ddq->d_ino_hardlimit = cpu_to_be64(hard); > - ddq->d_ino_softlimit = cpu_to_be64(soft); > + dqp->q_ino.hardlimit = hard; > + dqp->q_ino.softlimit = soft; > if (id == 0) { > defq->ihardlimit = hard; > defq->isoftlimit = soft; > @@ -619,10 +619,8 @@ xfs_qm_scall_getquota_fill_qc( > struct qc_dqblk *dst) > { > memset(dst, 0, sizeof(*dst)); > - dst->d_spc_hardlimit = > - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit)); > - dst->d_spc_softlimit = > - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit)); > + dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit); > + dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit); > dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); > dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); > dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); > @@ -631,10 +629,8 @@ xfs_qm_scall_getquota_fill_qc( > dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); > dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); > dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns); > - dst->d_rt_spc_hardlimit = > - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit)); > - dst->d_rt_spc_softlimit = > - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit)); > + dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); > + dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); > dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); > dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); > @@ -661,8 +657,8 @@ xfs_qm_scall_getquota_fill_qc( > (dst->d_spc_softlimit > 0)) { > ASSERT(dst->d_spc_timer != 0); > } > - if ((dst->d_ino_count > dst->d_ino_softlimit) && > - (dst->d_ino_softlimit > 0)) { > + if ((dst->d_ino_count > dqp->q_ino.softlimit) && > + (dqp->q_ino.softlimit > 0)) { > ASSERT(dst->d_ino_timer != 0); > } > } > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 71567ed367f2..7f744a37dc0e 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -882,14 +882,10 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, > __entry->res_bcount = dqp->q_blk.reserved; > __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); > __entry->icount = be64_to_cpu(dqp->q_core.d_icount); > - __entry->blk_hardlimit = > - be64_to_cpu(dqp->q_core.d_blk_hardlimit); > - __entry->blk_softlimit = > - be64_to_cpu(dqp->q_core.d_blk_softlimit); > - __entry->ino_hardlimit = > - be64_to_cpu(dqp->q_core.d_ino_hardlimit); > - __entry->ino_softlimit = > - be64_to_cpu(dqp->q_core.d_ino_softlimit); > + __entry->blk_hardlimit = dqp->q_blk.hardlimit; > + __entry->blk_softlimit = dqp->q_blk.softlimit; > + __entry->ino_hardlimit = dqp->q_ino.hardlimit; > + __entry->ino_softlimit = dqp->q_ino.softlimit; > ), > TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx " > "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx " > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 469bf7946d3d..7a3d64eb9fbf 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -593,10 +593,10 @@ xfs_trans_dqresv( > defq = xfs_get_defquota(q, xfs_dquot_type(dqp)); > > if (flags & XFS_TRANS_DQ_RES_BLKS) { > - hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit); > + hardlimit = dqp->q_blk.hardlimit; > if (!hardlimit) > hardlimit = defq->bhardlimit; > - softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit); > + softlimit = dqp->q_blk.softlimit; > if (!softlimit) > softlimit = defq->bsoftlimit; > timer = be32_to_cpu(dqp->q_core.d_btimer); > @@ -605,10 +605,10 @@ xfs_trans_dqresv( > resbcountp = &dqp->q_blk.reserved; > } else { > ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); > - hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit); > + hardlimit = dqp->q_rtb.hardlimit; > if (!hardlimit) > hardlimit = defq->rtbhardlimit; > - softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit); > + softlimit = dqp->q_rtb.softlimit; > if (!softlimit) > softlimit = defq->rtbsoftlimit; > timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > @@ -649,10 +649,10 @@ xfs_trans_dqresv( > timer = be32_to_cpu(dqp->q_core.d_itimer); > warns = be16_to_cpu(dqp->q_core.d_iwarns); > warnlimit = defq->iwarnlimit; > - hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); > + hardlimit = dqp->q_ino.hardlimit; > if (!hardlimit) > hardlimit = defq->ihardlimit; > - softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); > + softlimit = dqp->q_ino.softlimit; > if (!softlimit) > softlimit = defq->isoftlimit; > > > -- chandan
On Tuesday 30 June 2020 9:12:42 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Add counter fields to 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. > The changes are logically correct. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/scrub/quota.c | 18 ++++++------------ > fs/xfs/xfs_dquot.c | 47 +++++++++++++++++++++++++--------------------- > fs/xfs/xfs_dquot.h | 3 +++ > fs/xfs/xfs_qm.c | 6 +++--- > fs/xfs/xfs_qm.h | 6 +++--- > fs/xfs/xfs_trace.h | 4 ++-- > fs/xfs/xfs_trans_dquot.c | 36 ++++++++++++++--------------------- > 7 files changed, 57 insertions(+), 63 deletions(-) > > > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index 1a1c6996fc69..2fc2625feca0 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -82,9 +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 bcount; > - unsigned long long icount; > - unsigned long long rcount; > xfs_ino_t fs_icount; > int error = 0; > > @@ -128,9 +125,6 @@ xchk_quota_item( > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > > /* Check the resource counts. */ > - bcount = be64_to_cpu(d->d_bcount); > - icount = be64_to_cpu(d->d_icount); > - rcount = be64_to_cpu(d->d_rtbcount); > fs_icount = percpu_counter_sum(&mp->m_icount); > > /* > @@ -139,15 +133,15 @@ xchk_quota_item( > * if there are no quota limits. > */ > if (xfs_sb_version_hasreflink(&mp->m_sb)) { > - if (mp->m_sb.sb_dblocks < bcount) > + if (mp->m_sb.sb_dblocks < dq->q_blk.count) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, > offset); > } else { > - if (mp->m_sb.sb_dblocks < bcount) > + if (mp->m_sb.sb_dblocks < dq->q_blk.count) > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, > offset); > } > - if (icount > fs_icount || rcount > mp->m_sb.sb_rblocks) > + if (dq->q_ino.count > fs_icount || dq->q_rtb.count > mp->m_sb.sb_rblocks) > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > > /* > @@ -159,15 +153,15 @@ xchk_quota_item( > goto out; > > if (dq->q_blk.hardlimit != 0 && > - bcount > dq->q_blk.hardlimit) > + dq->q_blk.count > dq->q_blk.hardlimit) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > > if (dq->q_ino.hardlimit != 0 && > - icount > dq->q_ino.hardlimit) > + dq->q_ino.count > dq->q_ino.hardlimit) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > > if (dq->q_rtb.hardlimit != 0 && > - rcount > dq->q_rtb.hardlimit) > + dq->q_rtb.count > dq->q_rtb.hardlimit) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > > out: > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 63f744bcbc90..02eae8c2ba1b 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -133,9 +133,9 @@ xfs_qm_adjust_dqtimers( > > if (!d->d_btimer) { > if ((dq->q_blk.softlimit && > - (be64_to_cpu(d->d_bcount) > dq->q_blk.softlimit)) || > + (dq->q_blk.count > dq->q_blk.softlimit)) || > (dq->q_blk.hardlimit && > - (be64_to_cpu(d->d_bcount) > dq->q_blk.hardlimit))) { > + (dq->q_blk.count > dq->q_blk.hardlimit))) { > d->d_btimer = cpu_to_be32(ktime_get_real_seconds() + > defq->btimelimit); > } else { > @@ -143,18 +143,18 @@ xfs_qm_adjust_dqtimers( > } > } else { > if ((!dq->q_blk.softlimit || > - (be64_to_cpu(d->d_bcount) <= dq->q_blk.softlimit)) && > + (dq->q_blk.count <= dq->q_blk.softlimit)) && > (!dq->q_blk.hardlimit || > - (be64_to_cpu(d->d_bcount) <= dq->q_blk.hardlimit))) { > + (dq->q_blk.count <= dq->q_blk.hardlimit))) { > d->d_btimer = 0; > } > } > > if (!d->d_itimer) { > if ((dq->q_ino.softlimit && > - (be64_to_cpu(d->d_icount) > dq->q_ino.softlimit)) || > + (dq->q_ino.count > dq->q_ino.softlimit)) || > (dq->q_ino.hardlimit && > - (be64_to_cpu(d->d_icount) > dq->q_ino.hardlimit))) { > + (dq->q_ino.count > dq->q_ino.hardlimit))) { > d->d_itimer = cpu_to_be32(ktime_get_real_seconds() + > defq->itimelimit); > } else { > @@ -162,18 +162,18 @@ xfs_qm_adjust_dqtimers( > } > } else { > if ((!dq->q_ino.softlimit || > - (be64_to_cpu(d->d_icount) <= dq->q_ino.softlimit)) && > + (dq->q_ino.count <= dq->q_ino.softlimit)) && > (!dq->q_ino.hardlimit || > - (be64_to_cpu(d->d_icount) <= dq->q_ino.hardlimit))) { > + (dq->q_ino.count <= dq->q_ino.hardlimit))) { > d->d_itimer = 0; > } > } > > if (!d->d_rtbtimer) { > if ((dq->q_rtb.softlimit && > - (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.softlimit)) || > + (dq->q_rtb.count > dq->q_rtb.softlimit)) || > (dq->q_rtb.hardlimit && > - (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.hardlimit))) { > + (dq->q_rtb.count > dq->q_rtb.hardlimit))) { > d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() + > defq->rtbtimelimit); > } else { > @@ -181,9 +181,9 @@ xfs_qm_adjust_dqtimers( > } > } else { > if ((!dq->q_rtb.softlimit || > - (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.softlimit)) && > + (dq->q_rtb.count <= dq->q_rtb.softlimit)) && > (!dq->q_rtb.hardlimit || > - (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.hardlimit))) { > + (dq->q_rtb.count <= dq->q_rtb.hardlimit))) { > d->d_rtbtimer = 0; > } > } > @@ -538,13 +538,17 @@ xfs_dquot_from_disk( > dqp->q_rtb.hardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit); > dqp->q_rtb.softlimit = be64_to_cpu(ddqp->d_rtb_softlimit); > > + dqp->q_blk.count = be64_to_cpu(ddqp->d_bcount); > + dqp->q_ino.count = be64_to_cpu(ddqp->d_icount); > + dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount); > + > /* > * Reservation counters are defined as reservation plus current usage > * to avoid having to add every time. > */ > - dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount); > - dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount); > - dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount); > + dqp->q_blk.reserved = dqp->q_blk.count; > + dqp->q_ino.reserved = dqp->q_ino.count; > + dqp->q_rtb.reserved = dqp->q_rtb.count; > > /* initialize the dquot speculative prealloc thresholds */ > xfs_dquot_set_prealloc_limits(dqp); > @@ -565,6 +569,10 @@ xfs_dquot_to_disk( > 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); > + > + ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count); > + ddqp->d_icount = cpu_to_be64(dqp->q_ino.count); > + ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count); > } > > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > @@ -1127,18 +1135,15 @@ xfs_qm_dqflush_check( > if (dqp->q_id == 0) > return NULL; > > - if (dqp->q_blk.softlimit && > - be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit && > + if (dqp->q_blk.softlimit && dqp->q_blk.count > 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 && > + if (dqp->q_ino.softlimit && dqp->q_ino.count > 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 && > + if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit && > !ddq->d_rtbtimer) > return __this_address; > > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index edb49788c476..23e05b0d7567 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -31,6 +31,9 @@ struct xfs_dquot_res { > /* Total resources allocated and reserved. */ > xfs_qcnt_t reserved; > > + /* Total resources allocated. */ > + xfs_qcnt_t count; > + > /* Absolute and preferred limits. */ > xfs_qcnt_t hardlimit; > xfs_qcnt_t softlimit; > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 54fc3aac1a68..b47bba204240 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -1093,14 +1093,14 @@ xfs_qm_quotacheck_dqadjust( > * Adjust the inode count and the block count to reflect this inode's > * resource usage. > */ > - be64_add_cpu(&dqp->q_core.d_icount, 1); > + dqp->q_ino.count++; > dqp->q_ino.reserved++; > if (nblks) { > - be64_add_cpu(&dqp->q_core.d_bcount, nblks); > + dqp->q_blk.count += nblks; > dqp->q_blk.reserved += nblks; > } > if (rtblks) { > - be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks); > + dqp->q_rtb.count += rtblks; > dqp->q_rtb.reserved += rtblks; > } > > diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h > index 84cb8af468b7..6ed4ae942603 100644 > --- a/fs/xfs/xfs_qm.h > +++ b/fs/xfs/xfs_qm.h > @@ -26,9 +26,9 @@ extern struct kmem_zone *xfs_qm_dqtrxzone; > !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) > + !dqp->q_blk.count && \ > + !dqp->q_rtb.count && \ > + !dqp->q_ino.count) > > /* > * This defines the unit of allocation of dquots. > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 7f744a37dc0e..851f97dfe9e3 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -880,8 +880,8 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, > __entry->flags = dqp->dq_flags; > __entry->nrefs = dqp->q_nrefs; > __entry->res_bcount = dqp->q_blk.reserved; > - __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); > - __entry->icount = be64_to_cpu(dqp->q_core.d_icount); > + __entry->bcount = dqp->q_blk.count; > + __entry->icount = dqp->q_ino.count; > __entry->blk_hardlimit = dqp->q_blk.hardlimit; > __entry->blk_softlimit = dqp->q_blk.softlimit; > __entry->ino_hardlimit = dqp->q_ino.hardlimit; > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 7a3d64eb9fbf..b36d747989a7 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -309,7 +309,6 @@ xfs_trans_apply_dquot_deltas( > int i, j; > struct xfs_dquot *dqp; > struct xfs_dqtrx *qtrx, *qa; > - struct xfs_disk_dquot *d; > int64_t totalbdelta; > int64_t totalrtbdelta; > > @@ -341,7 +340,6 @@ xfs_trans_apply_dquot_deltas( > /* > * adjust the actual number of blocks used > */ > - d = &dqp->q_core; > > /* > * The issue here is - sometimes we don't make a blkquota > @@ -362,25 +360,22 @@ xfs_trans_apply_dquot_deltas( > qtrx->qt_delrtb_delta; > #ifdef DEBUG > if (totalbdelta < 0) > - ASSERT(be64_to_cpu(d->d_bcount) >= > - -totalbdelta); > + ASSERT(dqp->q_blk.count >= -totalbdelta); > > if (totalrtbdelta < 0) > - ASSERT(be64_to_cpu(d->d_rtbcount) >= > - -totalrtbdelta); > + ASSERT(dqp->q_rtb.count >= -totalrtbdelta); > > if (qtrx->qt_icount_delta < 0) > - ASSERT(be64_to_cpu(d->d_icount) >= > - -qtrx->qt_icount_delta); > + ASSERT(dqp->q_ino.count >= -qtrx->qt_icount_delta); > #endif > if (totalbdelta) > - be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta); > + dqp->q_blk.count += totalbdelta; > > if (qtrx->qt_icount_delta) > - be64_add_cpu(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta); > + dqp->q_ino.count += qtrx->qt_icount_delta; > > if (totalrtbdelta) > - be64_add_cpu(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta); > + dqp->q_rtb.count += totalrtbdelta; > > /* > * Get any default limits in use. > @@ -467,12 +462,9 @@ xfs_trans_apply_dquot_deltas( > (xfs_qcnt_t)qtrx->qt_icount_delta; > } > > - ASSERT(dqp->q_blk.reserved >= > - be64_to_cpu(dqp->q_core.d_bcount)); > - ASSERT(dqp->q_ino.reserved >= > - be64_to_cpu(dqp->q_core.d_icount)); > - ASSERT(dqp->q_rtb.reserved >= > - be64_to_cpu(dqp->q_core.d_rtbcount)); > + ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count); > + ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count); > + ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count); > } > } > } > @@ -645,7 +637,7 @@ xfs_trans_dqresv( > } > } > if (ninos > 0) { > - total_count = dqp->q_res_icount + ninos; > + total_count = dqp->q_ino.reserved + ninos; > timer = be32_to_cpu(dqp->q_core.d_itimer); > warns = be16_to_cpu(dqp->q_core.d_iwarns); > warnlimit = defq->iwarnlimit; > @@ -675,7 +667,7 @@ xfs_trans_dqresv( > > /* > * Change the reservation, but not the actual usage. > - * Note that q_blk.reserved = q_core.d_bcount + resv > + * Note that q_blk.reserved = q_blk.count + resv > */ > (*resbcountp) += (xfs_qcnt_t)nblks; > if (ninos != 0) > @@ -700,9 +692,9 @@ xfs_trans_dqresv( > XFS_TRANS_DQ_RES_INOS, > ninos); > } > - ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount)); > - ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount)); > - ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount)); > + ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count); > + ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count); > + ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count); > > xfs_dqunlock(dqp); > return 0; > > -- chandan
On Tuesday 30 June 2020 9:12:48 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Add warning counter fields to 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. > The changes are logically correct. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_dquot.c | 14 +++++++++++--- > fs/xfs/xfs_dquot.h | 8 ++++++++ > fs/xfs/xfs_qm.c | 12 ++++++------ > fs/xfs/xfs_qm_syscalls.c | 12 ++++++------ > fs/xfs/xfs_trans_dquot.c | 6 +++--- > 5 files changed, 34 insertions(+), 18 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 02eae8c2ba1b..a1edb49ceda5 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -139,7 +139,7 @@ xfs_qm_adjust_dqtimers( > d->d_btimer = cpu_to_be32(ktime_get_real_seconds() + > defq->btimelimit); > } else { > - d->d_bwarns = 0; > + dq->q_blk.warnings = 0; > } > } else { > if ((!dq->q_blk.softlimit || > @@ -158,7 +158,7 @@ xfs_qm_adjust_dqtimers( > d->d_itimer = cpu_to_be32(ktime_get_real_seconds() + > defq->itimelimit); > } else { > - d->d_iwarns = 0; > + dq->q_ino.warnings = 0; > } > } else { > if ((!dq->q_ino.softlimit || > @@ -177,7 +177,7 @@ xfs_qm_adjust_dqtimers( > d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() + > defq->rtbtimelimit); > } else { > - d->d_rtbwarns = 0; > + dq->q_rtb.warnings = 0; > } > } else { > if ((!dq->q_rtb.softlimit || > @@ -542,6 +542,10 @@ xfs_dquot_from_disk( > dqp->q_ino.count = be64_to_cpu(ddqp->d_icount); > dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount); > > + dqp->q_blk.warnings = be16_to_cpu(ddqp->d_bwarns); > + dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns); > + dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns); > + > /* > * Reservation counters are defined as reservation plus current usage > * to avoid having to add every time. > @@ -573,6 +577,10 @@ xfs_dquot_to_disk( > ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count); > ddqp->d_icount = cpu_to_be64(dqp->q_ino.count); > ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count); > + > + ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings); > + ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings); > + ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings); > } > > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 23e05b0d7567..5840bc54b772 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -37,6 +37,14 @@ struct xfs_dquot_res { > /* Absolute and preferred limits. */ > xfs_qcnt_t hardlimit; > xfs_qcnt_t softlimit; > + > + /* > + * For root dquots, this is the maximum number of warnings that will > + * be issued for this quota type. Otherwise, this is the number of > + * warnings issued against this quota. Note that none of this is > + * implemented. > + */ > + xfs_qwarncnt_t warnings; > }; > > /* > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index b47bba204240..4e233cfef46d 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -616,12 +616,12 @@ xfs_qm_init_timelimits( > defq->itimelimit = be32_to_cpu(ddqp->d_itimer); > if (ddqp->d_rtbtimer) > defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer); > - if (ddqp->d_bwarns) > - defq->bwarnlimit = be16_to_cpu(ddqp->d_bwarns); > - if (ddqp->d_iwarns) > - defq->iwarnlimit = be16_to_cpu(ddqp->d_iwarns); > - if (ddqp->d_rtbwarns) > - defq->rtbwarnlimit = be16_to_cpu(ddqp->d_rtbwarns); > + if (dqp->q_blk.warnings) > + defq->bwarnlimit = dqp->q_blk.warnings; > + if (dqp->q_ino.warnings) > + defq->iwarnlimit = dqp->q_ino.warnings; > + if (dqp->q_rtb.warnings) > + defq->rtbwarnlimit = dqp->q_rtb.warnings; > > xfs_qm_dqdestroy(dqp); > } > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index ab596d389e3e..5d3bccdbd3bf 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -548,11 +548,11 @@ xfs_qm_scall_setqlim( > * Update warnings counter(s) if requested > */ > if (newlim->d_fieldmask & QC_SPC_WARNS) > - ddq->d_bwarns = cpu_to_be16(newlim->d_spc_warns); > + dqp->q_blk.warnings = newlim->d_spc_warns; > if (newlim->d_fieldmask & QC_INO_WARNS) > - ddq->d_iwarns = cpu_to_be16(newlim->d_ino_warns); > + dqp->q_ino.warnings = newlim->d_ino_warns; > if (newlim->d_fieldmask & QC_RT_SPC_WARNS) > - ddq->d_rtbwarns = cpu_to_be16(newlim->d_rt_spc_warns); > + dqp->q_rtb.warnings = newlim->d_rt_spc_warns; > > if (id == 0) { > if (newlim->d_fieldmask & QC_SPC_WARNS) > @@ -627,13 +627,13 @@ xfs_qm_scall_getquota_fill_qc( > dst->d_ino_count = dqp->q_ino.reserved; > dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); > dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); > - dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); > - dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns); > + dst->d_ino_warns = dqp->q_ino.warnings; > + dst->d_spc_warns = dqp->q_blk.warnings; > dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); > dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); > dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); > dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > - dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); > + dst->d_rt_spc_warns = dqp->q_rtb.warnings; > > /* > * Internally, we don't reset all the timers when quota enforcement > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index b36d747989a7..21ed8eda3c80 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -592,7 +592,7 @@ xfs_trans_dqresv( > if (!softlimit) > softlimit = defq->bsoftlimit; > timer = be32_to_cpu(dqp->q_core.d_btimer); > - warns = be16_to_cpu(dqp->q_core.d_bwarns); > + warns = dqp->q_blk.warnings; > warnlimit = defq->bwarnlimit; > resbcountp = &dqp->q_blk.reserved; > } else { > @@ -604,7 +604,7 @@ xfs_trans_dqresv( > if (!softlimit) > softlimit = defq->rtbsoftlimit; > timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > - warns = be16_to_cpu(dqp->q_core.d_rtbwarns); > + warns = dqp->q_rtb.warnings; > warnlimit = defq->rtbwarnlimit; > resbcountp = &dqp->q_rtb.reserved; > } > @@ -639,7 +639,7 @@ xfs_trans_dqresv( > if (ninos > 0) { > total_count = dqp->q_ino.reserved + ninos; > timer = be32_to_cpu(dqp->q_core.d_itimer); > - warns = be16_to_cpu(dqp->q_core.d_iwarns); > + warns = dqp->q_ino.warnings; > warnlimit = defq->iwarnlimit; > hardlimit = dqp->q_ino.hardlimit; > if (!hardlimit) > > -- chandan
On Tue, Jun 30, 2020 at 08:41:56AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we
> can't lock the dquot buf to flush the dquot. This prevents the AIL from
> blocking on the dquot, but it also forgets to clear the FREEING flag on
> its way out. A subsequent purge attempt will see the FREEING flag is
> set and bail out, which leads to dqpurge_all failing to purge all the
> dquots. This causes unmounts and quotaoff operations to hang.
>
> Fixes: 8d3d7e2b35ea ("xfs: trylock underlying buffer on dquot flush")
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Looks like Dave submitted this as a separate fix just after you..
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tuesday 30 June 2020 9:12:54 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Add timers fields to 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. > The changes are logically correct. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_dquot.c | 41 +++++++++++++++++++++++------------------ > fs/xfs/xfs_dquot.h | 7 +++++++ > fs/xfs/xfs_qm.c | 15 ++++++--------- > fs/xfs/xfs_qm_syscalls.c | 18 ++++++++---------- > fs/xfs/xfs_trans_dquot.c | 6 +++--- > 5 files changed, 47 insertions(+), 40 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index a1edb49ceda5..7434ee57ec43 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -116,7 +116,6 @@ xfs_qm_adjust_dqtimers( > struct xfs_dquot *dq) > { > struct xfs_quotainfo *qi = mp->m_quotainfo; > - struct xfs_disk_dquot *d = &dq->q_core; > struct xfs_def_quota *defq; > > ASSERT(dq->q_id); > @@ -131,13 +130,13 @@ xfs_qm_adjust_dqtimers( > ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit); > #endif > > - if (!d->d_btimer) { > + if (!dq->q_blk.timer) { > if ((dq->q_blk.softlimit && > (dq->q_blk.count > dq->q_blk.softlimit)) || > (dq->q_blk.hardlimit && > (dq->q_blk.count > dq->q_blk.hardlimit))) { > - d->d_btimer = cpu_to_be32(ktime_get_real_seconds() + > - defq->btimelimit); > + dq->q_blk.timer = ktime_get_real_seconds() + > + defq->btimelimit; > } else { > dq->q_blk.warnings = 0; > } > @@ -146,17 +145,17 @@ xfs_qm_adjust_dqtimers( > (dq->q_blk.count <= dq->q_blk.softlimit)) && > (!dq->q_blk.hardlimit || > (dq->q_blk.count <= dq->q_blk.hardlimit))) { > - d->d_btimer = 0; > + dq->q_blk.timer = 0; > } > } > > - if (!d->d_itimer) { > + if (!dq->q_ino.timer) { > if ((dq->q_ino.softlimit && > (dq->q_ino.count > dq->q_ino.softlimit)) || > (dq->q_ino.hardlimit && > (dq->q_ino.count > dq->q_ino.hardlimit))) { > - d->d_itimer = cpu_to_be32(ktime_get_real_seconds() + > - defq->itimelimit); > + dq->q_ino.timer = ktime_get_real_seconds() + > + defq->itimelimit; > } else { > dq->q_ino.warnings = 0; > } > @@ -165,17 +164,17 @@ xfs_qm_adjust_dqtimers( > (dq->q_ino.count <= dq->q_ino.softlimit)) && > (!dq->q_ino.hardlimit || > (dq->q_ino.count <= dq->q_ino.hardlimit))) { > - d->d_itimer = 0; > + dq->q_ino.timer = 0; > } > } > > - if (!d->d_rtbtimer) { > + if (!dq->q_rtb.timer) { > if ((dq->q_rtb.softlimit && > (dq->q_rtb.count > dq->q_rtb.softlimit)) || > (dq->q_rtb.hardlimit && > (dq->q_rtb.count > dq->q_rtb.hardlimit))) { > - d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() + > - defq->rtbtimelimit); > + dq->q_rtb.timer = ktime_get_real_seconds() + > + defq->rtbtimelimit; > } else { > dq->q_rtb.warnings = 0; > } > @@ -184,7 +183,7 @@ xfs_qm_adjust_dqtimers( > (dq->q_rtb.count <= dq->q_rtb.softlimit)) && > (!dq->q_rtb.hardlimit || > (dq->q_rtb.count <= dq->q_rtb.hardlimit))) { > - d->d_rtbtimer = 0; > + dq->q_rtb.timer = 0; > } > } > } > @@ -546,6 +545,10 @@ xfs_dquot_from_disk( > dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns); > dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns); > > + dqp->q_blk.timer = be32_to_cpu(ddqp->d_btimer); > + dqp->q_ino.timer = be32_to_cpu(ddqp->d_itimer); > + dqp->q_rtb.timer = be32_to_cpu(ddqp->d_rtbtimer); > + > /* > * Reservation counters are defined as reservation plus current usage > * to avoid having to add every time. > @@ -581,6 +584,10 @@ xfs_dquot_to_disk( > ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings); > ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings); > ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings); > + > + ddqp->d_btimer = cpu_to_be32(dqp->q_blk.timer); > + ddqp->d_itimer = cpu_to_be32(dqp->q_ino.timer); > + ddqp->d_rtbtimer = cpu_to_be32(dqp->q_rtb.timer); > } > > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > @@ -1135,8 +1142,6 @@ static xfs_failaddr_t > xfs_qm_dqflush_check( > struct xfs_dquot *dqp) > { > - struct xfs_disk_dquot *ddq = &dqp->q_core; > - > if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) > return __this_address; > > @@ -1144,15 +1149,15 @@ xfs_qm_dqflush_check( > return NULL; > > if (dqp->q_blk.softlimit && dqp->q_blk.count > dqp->q_blk.softlimit && > - !ddq->d_btimer) > + !dqp->q_blk.timer) > return __this_address; > > if (dqp->q_ino.softlimit && dqp->q_ino.count > dqp->q_ino.softlimit && > - !ddq->d_itimer) > + !dqp->q_ino.timer) > return __this_address; > > if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit && > - !ddq->d_rtbtimer) > + !dqp->q_rtb.timer) > return __this_address; > > return NULL; > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 5840bc54b772..414bae537b1d 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -38,6 +38,13 @@ struct xfs_dquot_res { > xfs_qcnt_t hardlimit; > xfs_qcnt_t softlimit; > > + /* > + * For root dquots, this is the default grace period, in seconds. > + * Otherwise, this is when the quota grace period expires, > + * in seconds since the Unix epoch. > + */ > + time64_t timer; > + > /* > * For root dquots, this is the maximum number of warnings that will > * be issued for this quota type. Otherwise, this is the number of > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 4e233cfef46d..a56c6e4a5d99 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -579,7 +579,6 @@ xfs_qm_init_timelimits( > { > struct xfs_quotainfo *qinf = mp->m_quotainfo; > struct xfs_def_quota *defq; > - struct xfs_disk_dquot *ddqp; > struct xfs_dquot *dqp; > int error; > > @@ -603,19 +602,17 @@ xfs_qm_init_timelimits( > if (error) > return; > > - ddqp = &dqp->q_core; > - > /* > * The warnings and timers set the grace period given to > * a user or group before he or she can not perform any > * more writing. If it is zero, a default is used. > */ > - if (ddqp->d_btimer) > - defq->btimelimit = be32_to_cpu(ddqp->d_btimer); > - if (ddqp->d_itimer) > - defq->itimelimit = be32_to_cpu(ddqp->d_itimer); > - if (ddqp->d_rtbtimer) > - defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer); > + if (dqp->q_blk.timer) > + defq->btimelimit = dqp->q_blk.timer; > + if (dqp->q_ino.timer) > + defq->itimelimit = dqp->q_ino.timer; > + if (dqp->q_rtb.timer) > + defq->rtbtimelimit = dqp->q_rtb.timer; > if (dqp->q_blk.warnings) > defq->bwarnlimit = dqp->q_blk.warnings; > if (dqp->q_ino.warnings) > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 5d3bccdbd3bf..1b2b70b1660f 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -447,7 +447,6 @@ xfs_qm_scall_setqlim( > struct qc_dqblk *newlim) > { > struct xfs_quotainfo *q = mp->m_quotainfo; > - struct xfs_disk_dquot *ddq; > struct xfs_dquot *dqp; > struct xfs_trans *tp; > struct xfs_def_quota *defq; > @@ -488,7 +487,6 @@ xfs_qm_scall_setqlim( > > xfs_dqlock(dqp); > xfs_trans_dqjoin(tp, dqp); > - ddq = &dqp->q_core; > > /* > * Make sure that hardlimits are >= soft limits before changing. > @@ -573,11 +571,11 @@ xfs_qm_scall_setqlim( > * the soft limit. > */ > if (newlim->d_fieldmask & QC_SPC_TIMER) > - ddq->d_btimer = cpu_to_be32(newlim->d_spc_timer); > + dqp->q_blk.timer = newlim->d_spc_timer; > if (newlim->d_fieldmask & QC_INO_TIMER) > - ddq->d_itimer = cpu_to_be32(newlim->d_ino_timer); > + dqp->q_ino.timer = newlim->d_ino_timer; > if (newlim->d_fieldmask & QC_RT_SPC_TIMER) > - ddq->d_rtbtimer = cpu_to_be32(newlim->d_rt_spc_timer); > + dqp->q_rtb.timer = newlim->d_rt_spc_timer; > > if (id == 0) { > if (newlim->d_fieldmask & QC_SPC_TIMER) > @@ -621,18 +619,18 @@ xfs_qm_scall_getquota_fill_qc( > memset(dst, 0, sizeof(*dst)); > dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit); > dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit); > - dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); > - dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); > + dst->d_ino_hardlimit = dqp->q_ino.hardlimit; > + dst->d_ino_softlimit = dqp->q_ino.softlimit; > dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); > dst->d_ino_count = dqp->q_ino.reserved; > - dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); > - dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); > + dst->d_spc_timer = dqp->q_blk.timer; > + dst->d_ino_timer = dqp->q_ino.timer; > dst->d_ino_warns = dqp->q_ino.warnings; > dst->d_spc_warns = dqp->q_blk.warnings; > dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); > dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); > dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); > - dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > + dst->d_rt_spc_timer = dqp->q_rtb.timer; > dst->d_rt_spc_warns = dqp->q_rtb.warnings; > > /* > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 21ed8eda3c80..28b59a4069a3 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -591,7 +591,7 @@ xfs_trans_dqresv( > softlimit = dqp->q_blk.softlimit; > if (!softlimit) > softlimit = defq->bsoftlimit; > - timer = be32_to_cpu(dqp->q_core.d_btimer); > + timer = dqp->q_blk.timer; > warns = dqp->q_blk.warnings; > warnlimit = defq->bwarnlimit; > resbcountp = &dqp->q_blk.reserved; > @@ -603,7 +603,7 @@ xfs_trans_dqresv( > softlimit = dqp->q_rtb.softlimit; > if (!softlimit) > softlimit = defq->rtbsoftlimit; > - timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > + timer = dqp->q_rtb.timer; > warns = dqp->q_rtb.warnings; > warnlimit = defq->rtbwarnlimit; > resbcountp = &dqp->q_rtb.reserved; > @@ -638,7 +638,7 @@ xfs_trans_dqresv( > } > if (ninos > 0) { > total_count = dqp->q_ino.reserved + ninos; > - timer = be32_to_cpu(dqp->q_core.d_itimer); > + timer = dqp->q_ino.timer; > warns = dqp->q_ino.warnings; > warnlimit = defq->iwarnlimit; > hardlimit = dqp->q_ino.hardlimit; > > -- chandan
On Tuesday 30 June 2020 9:13:01 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Now that we've stopped using qcore entirely, drop it from the incore > dquot. > The changes are logically correct. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/scrub/quota.c | 4 ---- > fs/xfs/xfs_dquot.c | 29 +++++++++-------------------- > fs/xfs/xfs_dquot.h | 1 - > 3 files changed, 9 insertions(+), 25 deletions(-) > > > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index 2fc2625feca0..f4aad5b00188 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -79,7 +79,6 @@ xchk_quota_item( > struct xchk_quota_info *sqi = priv; > struct xfs_scrub *sc = sqi->sc; > struct xfs_mount *mp = sc->mp; > - struct xfs_disk_dquot *d = &dq->q_core; > struct xfs_quotainfo *qi = mp->m_quotainfo; > xfs_fileoff_t offset; > xfs_ino_t fs_icount; > @@ -98,9 +97,6 @@ xchk_quota_item( > > sqi->last_id = dq->q_id; > > - if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) > - xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > - > /* > * Warn if the hard limits are larger than the fs. > * Administrators can do this, though in production this seems > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 7434ee57ec43..2d6b50760962 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -529,7 +529,6 @@ 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); > @@ -568,8 +567,13 @@ xfs_dquot_to_disk( > struct xfs_disk_dquot *ddqp, > struct xfs_dquot *dqp) > { > - memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); > + ddqp->d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); > + ddqp->d_version = XFS_DQUOT_VERSION; > ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK; > + ddqp->d_id = cpu_to_be32(dqp->q_id); > + ddqp->d_pad0 = 0; > + ddqp->d_pad = 0; > + > 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); > @@ -1180,7 +1184,6 @@ xfs_qm_dqflush( > struct xfs_log_item *lip = &dqp->q_logitem.qli_item; > struct xfs_buf *bp; > struct xfs_dqblk *dqb; > - struct xfs_disk_dquot *ddqp; > xfs_failaddr_t fa; > int error; > > @@ -1204,22 +1207,6 @@ xfs_qm_dqflush( > if (error) > goto out_abort; > > - /* > - * Calculate the location of the dquot inside the buffer. > - */ > - dqb = bp->b_addr + dqp->q_bufoffset; > - ddqp = &dqb->dd_diskdq; > - > - /* sanity check the in-core structure before we flush */ > - fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0); > - if (fa) { > - xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > - dqp->q_id, fa); > - xfs_buf_relse(bp); > - error = -EFSCORRUPTED; > - goto out_abort; > - } > - > fa = xfs_qm_dqflush_check(dqp); > if (fa) { > xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > @@ -1229,7 +1216,9 @@ xfs_qm_dqflush( > goto out_abort; > } > > - xfs_dquot_to_disk(ddqp, dqp); > + /* Flush the incore dquot to the ondisk buffer. */ > + dqb = bp->b_addr + dqp->q_bufoffset; > + xfs_dquot_to_disk(&dqb->dd_diskdq, dqp); > > /* > * Clear the dirty field and remember the flush lsn for later use. > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 414bae537b1d..62b0fc6e0133 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -71,7 +71,6 @@ struct xfs_dquot { > struct xfs_dquot_res q_ino; /* inodes */ > struct xfs_dquot_res q_rtb; /* realtime blocks */ > > - struct xfs_disk_dquot q_core; > struct xfs_dq_logitem q_logitem; > > xfs_qcnt_t q_prealloc_lo_wmark; > > -- chandan
On Tuesday 30 June 2020 9:12:16 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Use the incore dq_flags to figure out the dquot type. This is the first > step towards removing xfs_disk_dquot from the incore dquot. > The changes are logically correct. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/libxfs/xfs_quota_defs.h | 2 ++ > fs/xfs/scrub/quota.c | 4 ---- > fs/xfs/xfs_dquot.c | 33 +++++++++++++++++++++++++++++++-- > fs/xfs/xfs_dquot.h | 2 ++ > fs/xfs/xfs_dquot_item.c | 6 ++++-- > fs/xfs/xfs_qm.c | 4 ++-- > fs/xfs/xfs_qm.h | 2 +- > fs/xfs/xfs_qm_syscalls.c | 9 +++------ > 8 files changed, 45 insertions(+), 17 deletions(-) > > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h > index 56d9dd787e7b..459023b0a304 100644 > --- a/fs/xfs/libxfs/xfs_quota_defs.h > +++ b/fs/xfs/libxfs/xfs_quota_defs.h > @@ -29,6 +29,8 @@ typedef uint16_t xfs_qwarncnt_t; > > #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) > > +#define XFS_DQ_ONDISK (XFS_DQ_ALLTYPES) > + > #define XFS_DQ_FLAGS \ > { XFS_DQ_USER, "USER" }, \ > { XFS_DQ_PROJ, "PROJ" }, \ > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index 905a34558361..710659d3fa28 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -108,10 +108,6 @@ xchk_quota_item( > > sqi->last_id = id; > > - /* Did we get the dquot type we wanted? */ > - if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES)) > - xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > - > if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 46c8ca83c04d..59d1bce34a98 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -561,6 +561,16 @@ xfs_dquot_from_disk( > return 0; > } > > +/* Copy the in-core quota fields into the on-disk buffer. */ > +void > +xfs_dquot_to_disk( > + struct xfs_disk_dquot *ddqp, > + struct xfs_dquot *dqp) > +{ > + memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); > + ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK; > +} > + > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > static int > xfs_qm_dqread_alloc( > @@ -1108,6 +1118,17 @@ xfs_qm_dqflush_done( > xfs_dqfunlock(dqp); > } > > +/* Check incore dquot for errors before we flush. */ > +static xfs_failaddr_t > +xfs_qm_dqflush_check( > + struct xfs_dquot *dqp) > +{ > + if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) > + return __this_address; > + > + return NULL; > +} > + > /* > * Write a modified dquot to disk. > * The dquot must be locked and the flush lock too taken by caller. > @@ -1166,8 +1187,16 @@ xfs_qm_dqflush( > goto out_abort; > } > > - /* This is the only portion of data that needs to persist */ > - memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); > + fa = xfs_qm_dqflush_check(dqp); > + if (fa) { > + xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > + be32_to_cpu(dqp->q_core.d_id), fa); > + xfs_buf_relse(bp); > + error = -EFSCORRUPTED; > + goto out_abort; > + } > + > + xfs_dquot_to_disk(ddqp, dqp); > > /* > * Clear the dirty field and remember the flush lsn for later use. > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 71e36c85e20b..1b1a4261a580 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -144,6 +144,8 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp) > return false; > } > > +void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp); > + > #define XFS_DQ_IS_LOCKED(dqp) (mutex_is_locked(&((dqp)->q_qlock))) > #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) > #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) > diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c > index 349c92d26570..ff0ab65cf413 100644 > --- a/fs/xfs/xfs_dquot_item.c > +++ b/fs/xfs/xfs_dquot_item.c > @@ -45,6 +45,7 @@ xfs_qm_dquot_logitem_format( > struct xfs_log_item *lip, > struct xfs_log_vec *lv) > { > + struct xfs_disk_dquot ddq; > struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); > struct xfs_log_iovec *vecp = NULL; > struct xfs_dq_logformat *qlf; > @@ -58,8 +59,9 @@ xfs_qm_dquot_logitem_format( > qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset; > xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat)); > > - xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, > - &qlip->qli_dquot->q_core, > + xfs_dquot_to_disk(&ddq, qlip->qli_dquot); > + > + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, &ddq, > sizeof(struct xfs_disk_dquot)); > } > > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 938023dd8ce5..632025c2f00b 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -161,7 +161,7 @@ xfs_qm_dqpurge( > xfs_dqfunlock(dqp); > xfs_dqunlock(dqp); > > - radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags), > + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), > be32_to_cpu(dqp->q_core.d_id)); > qi->qi_dquots--; > > @@ -1598,7 +1598,7 @@ xfs_qm_dqfree_one( > struct xfs_quotainfo *qi = mp->m_quotainfo; > > mutex_lock(&qi->qi_tree_lock); > - radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags), > + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), > be32_to_cpu(dqp->q_core.d_id)); > > qi->qi_dquots--; > diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h > index 7b0e771fcbce..43b4650cdcdf 100644 > --- a/fs/xfs/xfs_qm.h > +++ b/fs/xfs/xfs_qm.h > @@ -85,7 +85,7 @@ xfs_dquot_tree( > struct xfs_quotainfo *qi, > int type) > { > - switch (type) { > + switch (type & XFS_DQ_ALLTYPES) { > case XFS_DQ_USER: > return &qi->qi_uquota_tree; > case XFS_DQ_GROUP: > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 7effd7a28136..8cbb65f01bf1 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -644,12 +644,9 @@ xfs_qm_scall_getquota_fill_qc( > * gets turned off. No need to confuse the user level code, > * so return zeroes in that case. > */ > - if ((!XFS_IS_UQUOTA_ENFORCED(mp) && > - dqp->q_core.d_flags == XFS_DQ_USER) || > - (!XFS_IS_GQUOTA_ENFORCED(mp) && > - dqp->q_core.d_flags == XFS_DQ_GROUP) || > - (!XFS_IS_PQUOTA_ENFORCED(mp) && > - dqp->q_core.d_flags == XFS_DQ_PROJ)) { > + if ((!XFS_IS_UQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_USER)) || > + (!XFS_IS_GQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_GROUP)) || > + (!XFS_IS_PQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_PROJ))) { > dst->d_spc_timer = 0; > dst->d_ino_timer = 0; > dst->d_rt_spc_timer = 0; > > -- chandan
Looks good, Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tue, Jun 30, 2020 at 08:42:09AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> While loading dquot records off disk, make sure that the quota type
> flags are the same between the incore dquot and the ondisk dquot.
>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
> fs/xfs/xfs_dquot.c | 23 ++++++++++++++++++++---
> 1 file changed, 20 insertions(+), 3 deletions(-)
>
>
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index d5b7f03e93c8..46c8ca83c04d 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -524,13 +524,27 @@ xfs_dquot_alloc(
> }
>
> /* Copy the in-core quota fields in from the on-disk buffer. */
> -STATIC void
> +STATIC int
> xfs_dquot_from_disk(
> struct xfs_dquot *dqp,
> struct xfs_buf *bp)
> {
> struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset;
>
> + /*
> + * The only field the verifier didn't check was the quota type flag, so
> + * do that here.
> + */
> + if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
> + (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
> + dqp->q_core.d_id != ddqp->d_id) {
The comment looks a little weird, as this also checks d_id. Also
xfs_dquot_verify verifies d_flags against generally bogus value, it
just doesn't check that it matches the type we are looking for.
Last but not least dqp->dq_flags only contains the type at this
point.
So what about something like:
/*
* Ensure we got the type and ID we were looking for. Everything else
* we checked by the verifier.
*/
if ((ddqp->d_flags & XFS_DQ_ALLTYPES) != dqp->dq_flags ||
ddqp->d_id != dqp->q_core.d_id)
> #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
>
> +#define XFS_DQ_ONDISK (XFS_DQ_ALLTYPES)
> +
I really wonder if we should split the on-disk type and the in-core
flags properly instead.
That is propagate the u8 flags from the on-disk field directly,
and use a separate field for the in-memory flags dirty and freeing
flags, as that this kind of mixing up is bound to eventually create
problems.
On Tue, Jun 30, 2020 at 08:42:23AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> Add a dquot id field to the incore dquot, and use that instead of the
> one in qcore. This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
>
> We also rearrange the start of xfs_dquot to remove padding holes, saving
> 8 bytes.
>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tue, Jun 30, 2020 at 08:42:29AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> Introduce a new struct xfs_dquot_res that we'll use to track all the
> incore data for a particular resource type (block, inode, rt block).
> This will help us (once we've eliminated q_core) to declutter quota
> functions that currently open-code field access or pass around fields
> around explicitly.
>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tue, Jun 30, 2020 at 08:42:36AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> 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: Darrick J. Wong <darrick.wong@oracle.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tue, Jun 30, 2020 at 08:42:42AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> Add counter fields to 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: Darrick J. Wong <darrick.wong@oracle.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tue, Jun 30, 2020 at 08:42:48AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> Add warning counter fields to 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: Darrick J. Wong <darrick.wong@oracle.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tue, Jun 30, 2020 at 08:42:54AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> Add timers fields to 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: Darrick J. Wong <darrick.wong@oracle.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tue, Jun 30, 2020 at 08:43:01AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> Now that we've stopped using qcore entirely, drop it from the incore
> dquot.
>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tuesday 30 June 2020 9:13:07 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Now that we've split up the dquot resource fields into separate structs, > do the same for the default limits to enable further refactoring. > The changes look good to me. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_dquot.c | 30 +++++++++++++++--------------- > fs/xfs/xfs_qm.c | 36 ++++++++++++++++++------------------ > fs/xfs/xfs_qm.h | 22 ++++++++++------------ > fs/xfs/xfs_qm_syscalls.c | 24 ++++++++++++------------ > fs/xfs/xfs_quotaops.c | 12 ++++++------ > fs/xfs/xfs_trans_dquot.c | 18 +++++++++--------- > 6 files changed, 70 insertions(+), 72 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 2d6b50760962..6975c27145fc 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -76,22 +76,22 @@ xfs_qm_adjust_dqlimits( > ASSERT(dq->q_id); > defq = xfs_get_defquota(q, xfs_dquot_type(dq)); > > - if (defq->bsoftlimit && !dq->q_blk.softlimit) { > - dq->q_blk.softlimit = defq->bsoftlimit; > + if (defq->dfq_blk.softlimit && !dq->q_blk.softlimit) { > + dq->q_blk.softlimit = defq->dfq_blk.softlimit; > prealloc = 1; > } > - if (defq->bhardlimit && !dq->q_blk.hardlimit) { > - dq->q_blk.hardlimit = defq->bhardlimit; > + if (defq->dfq_blk.hardlimit && !dq->q_blk.hardlimit) { > + dq->q_blk.hardlimit = defq->dfq_blk.hardlimit; > prealloc = 1; > } > - 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 (defq->dfq_ino.softlimit && !dq->q_ino.softlimit) > + dq->q_ino.softlimit = defq->dfq_ino.softlimit; > + if (defq->dfq_ino.hardlimit && !dq->q_ino.hardlimit) > + dq->q_ino.hardlimit = defq->dfq_ino.hardlimit; > + if (defq->dfq_rtb.softlimit && !dq->q_rtb.softlimit) > + dq->q_rtb.softlimit = defq->dfq_rtb.softlimit; > + if (defq->dfq_rtb.hardlimit && !dq->q_rtb.hardlimit) > + dq->q_rtb.hardlimit = defq->dfq_rtb.hardlimit; > > if (prealloc) > xfs_dquot_set_prealloc_limits(dq); > @@ -136,7 +136,7 @@ xfs_qm_adjust_dqtimers( > (dq->q_blk.hardlimit && > (dq->q_blk.count > dq->q_blk.hardlimit))) { > dq->q_blk.timer = ktime_get_real_seconds() + > - defq->btimelimit; > + defq->dfq_blk.timelimit; > } else { > dq->q_blk.warnings = 0; > } > @@ -155,7 +155,7 @@ xfs_qm_adjust_dqtimers( > (dq->q_ino.hardlimit && > (dq->q_ino.count > dq->q_ino.hardlimit))) { > dq->q_ino.timer = ktime_get_real_seconds() + > - defq->itimelimit; > + defq->dfq_ino.timelimit; > } else { > dq->q_ino.warnings = 0; > } > @@ -174,7 +174,7 @@ xfs_qm_adjust_dqtimers( > (dq->q_rtb.hardlimit && > (dq->q_rtb.count > dq->q_rtb.hardlimit))) { > dq->q_rtb.timer = ktime_get_real_seconds() + > - defq->rtbtimelimit; > + defq->dfq_rtb.timelimit; > } else { > dq->q_rtb.warnings = 0; > } > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index a56c6e4a5d99..28326a6264a8 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -562,12 +562,12 @@ xfs_qm_set_defquota( > * Timers and warnings have been already set, let's just set the > * default limits for this quota type > */ > - 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; > + defq->dfq_blk.hardlimit = dqp->q_blk.hardlimit; > + defq->dfq_blk.softlimit = dqp->q_blk.softlimit; > + defq->dfq_ino.hardlimit = dqp->q_ino.hardlimit; > + defq->dfq_ino.softlimit = dqp->q_ino.softlimit; > + defq->dfq_rtb.hardlimit = dqp->q_rtb.hardlimit; > + defq->dfq_rtb.softlimit = dqp->q_rtb.softlimit; > xfs_qm_dqdestroy(dqp); > } > > @@ -584,12 +584,12 @@ xfs_qm_init_timelimits( > > defq = xfs_get_defquota(qinf, type); > > - defq->btimelimit = XFS_QM_BTIMELIMIT; > - defq->itimelimit = XFS_QM_ITIMELIMIT; > - defq->rtbtimelimit = XFS_QM_RTBTIMELIMIT; > - defq->bwarnlimit = XFS_QM_BWARNLIMIT; > - defq->iwarnlimit = XFS_QM_IWARNLIMIT; > - defq->rtbwarnlimit = XFS_QM_RTBWARNLIMIT; > + defq->dfq_blk.timelimit = XFS_QM_BTIMELIMIT; > + defq->dfq_ino.timelimit = XFS_QM_ITIMELIMIT; > + defq->dfq_rtb.timelimit = XFS_QM_RTBTIMELIMIT; > + defq->dfq_blk.warnlimit = XFS_QM_BWARNLIMIT; > + defq->dfq_ino.warnlimit = XFS_QM_IWARNLIMIT; > + defq->dfq_rtb.warnlimit = XFS_QM_RTBWARNLIMIT; > > /* > * We try to get the limits from the superuser's limits fields. > @@ -608,17 +608,17 @@ xfs_qm_init_timelimits( > * more writing. If it is zero, a default is used. > */ > if (dqp->q_blk.timer) > - defq->btimelimit = dqp->q_blk.timer; > + defq->dfq_blk.timelimit = dqp->q_blk.timer; > if (dqp->q_ino.timer) > - defq->itimelimit = dqp->q_ino.timer; > + defq->dfq_ino.timelimit = dqp->q_ino.timer; > if (dqp->q_rtb.timer) > - defq->rtbtimelimit = dqp->q_rtb.timer; > + defq->dfq_rtb.timelimit = dqp->q_rtb.timer; > if (dqp->q_blk.warnings) > - defq->bwarnlimit = dqp->q_blk.warnings; > + defq->dfq_blk.warnlimit = dqp->q_blk.warnings; > if (dqp->q_ino.warnings) > - defq->iwarnlimit = dqp->q_ino.warnings; > + defq->dfq_ino.warnlimit = dqp->q_ino.warnings; > if (dqp->q_rtb.warnings) > - defq->rtbwarnlimit = dqp->q_rtb.warnings; > + defq->dfq_rtb.warnlimit = dqp->q_rtb.warnings; > > xfs_qm_dqdestroy(dqp); > } > diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h > index 6ed4ae942603..e2f0027f0ac1 100644 > --- a/fs/xfs/xfs_qm.h > +++ b/fs/xfs/xfs_qm.h > @@ -41,20 +41,18 @@ extern struct kmem_zone *xfs_qm_dqtrxzone; > */ > #define XFS_DQUOT_CLUSTER_SIZE_FSB (xfs_filblks_t)1 > > +struct xfs_def_qres { > + xfs_qcnt_t hardlimit; /* default hard limit */ > + xfs_qcnt_t softlimit; /* default soft limit */ > + time64_t timelimit; /* limit for timers */ > + xfs_qwarncnt_t warnlimit; /* limit for warnings */ > +}; > + > /* Defaults for each quota type: time limits, warn limits, usage limits */ > struct xfs_def_quota { > - time64_t btimelimit; /* limit for blks timer */ > - time64_t itimelimit; /* limit for inodes timer */ > - time64_t rtbtimelimit; /* limit for rt blks timer */ > - xfs_qwarncnt_t bwarnlimit; /* limit for blks warnings */ > - xfs_qwarncnt_t iwarnlimit; /* limit for inodes warnings */ > - xfs_qwarncnt_t rtbwarnlimit; /* limit for rt blks warnings */ > - xfs_qcnt_t bhardlimit; /* default data blk hard limit */ > - xfs_qcnt_t bsoftlimit; /* default data blk soft limit */ > - xfs_qcnt_t ihardlimit; /* default inode count hard limit */ > - xfs_qcnt_t isoftlimit; /* default inode count soft limit */ > - xfs_qcnt_t rtbhardlimit; /* default realtime blk hard limit */ > - xfs_qcnt_t rtbsoftlimit; /* default realtime blk soft limit */ > + struct xfs_def_qres dfq_blk; > + struct xfs_def_qres dfq_ino; > + struct xfs_def_qres dfq_rtb; > }; > > /* > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 1b2b70b1660f..393b88612cc8 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -502,8 +502,8 @@ xfs_qm_scall_setqlim( > dqp->q_blk.softlimit = soft; > xfs_dquot_set_prealloc_limits(dqp); > if (id == 0) { > - defq->bhardlimit = hard; > - defq->bsoftlimit = soft; > + defq->dfq_blk.hardlimit = hard; > + defq->dfq_blk.softlimit = soft; > } > } else { > xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft); > @@ -518,8 +518,8 @@ xfs_qm_scall_setqlim( > dqp->q_rtb.hardlimit = hard; > dqp->q_rtb.softlimit = soft; > if (id == 0) { > - defq->rtbhardlimit = hard; > - defq->rtbsoftlimit = soft; > + defq->dfq_rtb.hardlimit = hard; > + defq->dfq_rtb.softlimit = soft; > } > } else { > xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft); > @@ -535,8 +535,8 @@ xfs_qm_scall_setqlim( > dqp->q_ino.hardlimit = hard; > dqp->q_ino.softlimit = soft; > if (id == 0) { > - defq->ihardlimit = hard; > - defq->isoftlimit = soft; > + defq->dfq_ino.hardlimit = hard; > + defq->dfq_ino.softlimit = soft; > } > } else { > xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft); > @@ -554,11 +554,11 @@ xfs_qm_scall_setqlim( > > if (id == 0) { > if (newlim->d_fieldmask & QC_SPC_WARNS) > - defq->bwarnlimit = newlim->d_spc_warns; > + defq->dfq_blk.warnlimit = newlim->d_spc_warns; > if (newlim->d_fieldmask & QC_INO_WARNS) > - defq->iwarnlimit = newlim->d_ino_warns; > + defq->dfq_ino.warnlimit = newlim->d_ino_warns; > if (newlim->d_fieldmask & QC_RT_SPC_WARNS) > - defq->rtbwarnlimit = newlim->d_rt_spc_warns; > + defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns; > } > > /* > @@ -579,11 +579,11 @@ xfs_qm_scall_setqlim( > > if (id == 0) { > if (newlim->d_fieldmask & QC_SPC_TIMER) > - defq->btimelimit = newlim->d_spc_timer; > + defq->dfq_blk.timelimit = newlim->d_spc_timer; > if (newlim->d_fieldmask & QC_INO_TIMER) > - defq->itimelimit = newlim->d_ino_timer; > + defq->dfq_ino.timelimit = newlim->d_ino_timer; > if (newlim->d_fieldmask & QC_RT_SPC_TIMER) > - defq->rtbtimelimit = newlim->d_rt_spc_timer; > + defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer; > } > > if (id != 0) { > diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c > index bf809b77a316..c86a6fe263da 100644 > --- a/fs/xfs/xfs_quotaops.c > +++ b/fs/xfs/xfs_quotaops.c > @@ -37,12 +37,12 @@ xfs_qm_fill_state( > tstate->flags |= QCI_SYSFILE; > tstate->blocks = ip->i_d.di_nblocks; > tstate->nextents = ip->i_df.if_nextents; > - tstate->spc_timelimit = (u32)defq->btimelimit; > - tstate->ino_timelimit = (u32)defq->itimelimit; > - tstate->rt_spc_timelimit = (u32)defq->rtbtimelimit; > - tstate->spc_warnlimit = defq->bwarnlimit; > - tstate->ino_warnlimit = defq->iwarnlimit; > - tstate->rt_spc_warnlimit = defq->rtbwarnlimit; > + tstate->spc_timelimit = (u32)defq->dfq_blk.timelimit; > + tstate->ino_timelimit = (u32)defq->dfq_ino.timelimit; > + tstate->rt_spc_timelimit = (u32)defq->dfq_rtb.timelimit; > + tstate->spc_warnlimit = defq->dfq_blk.warnlimit; > + tstate->ino_warnlimit = defq->dfq_ino.warnlimit; > + tstate->rt_spc_warnlimit = defq->dfq_rtb.warnlimit; > if (tempqip) > xfs_irele(ip); > } > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 28b59a4069a3..392e51baad6f 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -587,25 +587,25 @@ xfs_trans_dqresv( > if (flags & XFS_TRANS_DQ_RES_BLKS) { > hardlimit = dqp->q_blk.hardlimit; > if (!hardlimit) > - hardlimit = defq->bhardlimit; > + hardlimit = defq->dfq_blk.hardlimit; > softlimit = dqp->q_blk.softlimit; > if (!softlimit) > - softlimit = defq->bsoftlimit; > + softlimit = defq->dfq_blk.softlimit; > timer = dqp->q_blk.timer; > warns = dqp->q_blk.warnings; > - warnlimit = defq->bwarnlimit; > + warnlimit = defq->dfq_blk.warnlimit; > resbcountp = &dqp->q_blk.reserved; > } else { > ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); > hardlimit = dqp->q_rtb.hardlimit; > if (!hardlimit) > - hardlimit = defq->rtbhardlimit; > + hardlimit = defq->dfq_rtb.hardlimit; > softlimit = dqp->q_rtb.softlimit; > if (!softlimit) > - softlimit = defq->rtbsoftlimit; > + softlimit = defq->dfq_rtb.softlimit; > timer = dqp->q_rtb.timer; > warns = dqp->q_rtb.warnings; > - warnlimit = defq->rtbwarnlimit; > + warnlimit = defq->dfq_rtb.warnlimit; > resbcountp = &dqp->q_rtb.reserved; > } > > @@ -640,13 +640,13 @@ xfs_trans_dqresv( > total_count = dqp->q_ino.reserved + ninos; > timer = dqp->q_ino.timer; > warns = dqp->q_ino.warnings; > - warnlimit = defq->iwarnlimit; > + warnlimit = defq->dfq_ino.warnlimit; > hardlimit = dqp->q_ino.hardlimit; > if (!hardlimit) > - hardlimit = defq->ihardlimit; > + hardlimit = defq->dfq_ino.hardlimit; > softlimit = dqp->q_ino.softlimit; > if (!softlimit) > - softlimit = defq->isoftlimit; > + softlimit = defq->dfq_ino.softlimit; > > if (hardlimit && total_count > hardlimit) { > xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN); > > -- chandan
On Tue, Jun 30, 2020 at 08:43:07AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> Now that we've split up the dquot resource fields into separate structs,
> do the same for the default limits to enable further refactoring.
>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tue, Jun 30, 2020 at 08:43:13AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> struct xfs_dquot already has a pointer to the xfs mount, so remove the
> redundant parameter from xfs_qm_adjust_dq*.
>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tue, Jun 30, 2020 at 08:43:20AM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Refactor the open-coded test for whether or not we're over quota. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_dquot.c | 95 ++++++++++++++++------------------------------------ > 1 file changed, 30 insertions(+), 65 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 35a113d1b42b..ef34c82c28a0 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits( > xfs_dquot_set_prealloc_limits(dq); > } > > +/* > + * Determine if this quota counter is over either limit and set the quota > + * timers as appropriate. > + */ > +static inline void > +xfs_qm_adjust_res_timer( > + struct xfs_dquot_res *res, > + struct xfs_def_qres *dres) > +{ > + bool over; > + > +#ifdef DEBUG > + if (res->hardlimit) > + ASSERT(res->softlimit <= res->hardlimit); > +#endif Maybe: ASSERRT(!res->hardlimit || res->softlimit <= res->hardlimit); > + > + over = (res->softlimit && res->count > res->softlimit) || > + (res->hardlimit && res->count > res->hardlimit); > + > + if (over && res->timer == 0) > + res->timer = ktime_get_real_seconds() + dres->timelimit; > + else if (!over && res->timer != 0) > + res->timer = 0; > + else if (!over && res->timer == 0) > + res->warnings = 0; What about: if ((res->softlimit && res->count > res->softlimit) || (res->hardlimit && res->count > res->hardlimit)) { if (res->timer == 0) res->timer = ktime_get_real_seconds() + dres->timelimit; } else { if (res->timer) res->timer = 0; else res->warnings = 0; }
On Tue, Jun 30, 2020 at 08:43:26AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> Now that we can pass around quota resource and limit structures, clean
> up the open-coded field setting in xfs_qm_scall_setqlim.
>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tuesday 30 June 2020 9:13:13 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > struct xfs_dquot already has a pointer to the xfs mount, so remove the > redundant parameter from xfs_qm_adjust_dq*. > The changes look good to me. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_dquot.c | 4 ++-- > fs/xfs/xfs_dquot.h | 6 ++---- > fs/xfs/xfs_qm.c | 4 ++-- > fs/xfs/xfs_qm_syscalls.c | 2 +- > fs/xfs/xfs_trans_dquot.c | 4 ++-- > 5 files changed, 9 insertions(+), 11 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 6975c27145fc..35a113d1b42b 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -66,9 +66,9 @@ xfs_qm_dqdestroy( > */ > void > xfs_qm_adjust_dqlimits( > - struct xfs_mount *mp, > struct xfs_dquot *dq) > { > + struct xfs_mount *mp = dq->q_mount; > struct xfs_quotainfo *q = mp->m_quotainfo; > struct xfs_def_quota *defq; > int prealloc = 0; > @@ -112,9 +112,9 @@ xfs_qm_adjust_dqlimits( > */ > void > xfs_qm_adjust_dqtimers( > - struct xfs_mount *mp, > struct xfs_dquot *dq) > { > + struct xfs_mount *mp = dq->q_mount; > struct xfs_quotainfo *qi = mp->m_quotainfo; > struct xfs_def_quota *defq; > > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 62b0fc6e0133..e37b4bebc1ea 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -181,10 +181,8 @@ void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp); > void xfs_qm_dqdestroy(struct xfs_dquot *dqp); > int xfs_qm_dqflush(struct xfs_dquot *dqp, struct xfs_buf **bpp); > void xfs_qm_dqunpin_wait(struct xfs_dquot *dqp); > -void xfs_qm_adjust_dqtimers(struct xfs_mount *mp, > - struct xfs_dquot *d); > -void xfs_qm_adjust_dqlimits(struct xfs_mount *mp, > - struct xfs_dquot *d); > +void xfs_qm_adjust_dqtimers(struct xfs_dquot *d); > +void xfs_qm_adjust_dqlimits(struct xfs_dquot *d); > xfs_dqid_t xfs_qm_id_for_quotatype(struct xfs_inode *ip, uint type); > int xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id, > uint type, bool can_alloc, > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 28326a6264a8..30deb6cf6a7a 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -1107,8 +1107,8 @@ xfs_qm_quotacheck_dqadjust( > * There are no timers for the default values set in the root dquot. > */ > if (dqp->q_id) { > - xfs_qm_adjust_dqlimits(mp, dqp); > - xfs_qm_adjust_dqtimers(mp, dqp); > + xfs_qm_adjust_dqlimits(dqp); > + xfs_qm_adjust_dqtimers(dqp); > } > > dqp->dq_flags |= XFS_DQ_DIRTY; > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 393b88612cc8..5423e02f9837 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -594,7 +594,7 @@ xfs_qm_scall_setqlim( > * is on or off. We don't really want to bother with iterating > * over all ondisk dquots and turning the timers on/off. > */ > - xfs_qm_adjust_dqtimers(mp, dqp); > + xfs_qm_adjust_dqtimers(dqp); > } > dqp->dq_flags |= XFS_DQ_DIRTY; > xfs_trans_log_dquot(tp, dqp); > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 392e51baad6f..2712814d696d 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -382,8 +382,8 @@ xfs_trans_apply_dquot_deltas( > * Start/reset the timer(s) if needed. > */ > if (dqp->q_id) { > - xfs_qm_adjust_dqlimits(tp->t_mountp, dqp); > - xfs_qm_adjust_dqtimers(tp->t_mountp, dqp); > + xfs_qm_adjust_dqlimits(dqp); > + xfs_qm_adjust_dqtimers(dqp); > } > > dqp->dq_flags |= XFS_DQ_DIRTY; > > -- chandan
On Tuesday 30 June 2020 9:13:20 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Refactor the open-coded test for whether or not we're over quota. > The changes look good to me. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_dquot.c | 95 ++++++++++++++++------------------------------------ > 1 file changed, 30 insertions(+), 65 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 35a113d1b42b..ef34c82c28a0 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits( > xfs_dquot_set_prealloc_limits(dq); > } > > +/* > + * Determine if this quota counter is over either limit and set the quota > + * timers as appropriate. > + */ > +static inline void > +xfs_qm_adjust_res_timer( > + struct xfs_dquot_res *res, > + struct xfs_def_qres *dres) > +{ > + bool over; > + > +#ifdef DEBUG > + if (res->hardlimit) > + ASSERT(res->softlimit <= res->hardlimit); > +#endif > + > + over = (res->softlimit && res->count > res->softlimit) || > + (res->hardlimit && res->count > res->hardlimit); > + > + if (over && res->timer == 0) > + res->timer = ktime_get_real_seconds() + dres->timelimit; > + else if (!over && res->timer != 0) > + res->timer = 0; > + else if (!over && res->timer == 0) > + res->warnings = 0; > +} > + > /* > * Check the limits and timers of a dquot and start or reset timers > * if necessary. > @@ -121,71 +148,9 @@ xfs_qm_adjust_dqtimers( > ASSERT(dq->q_id); > defq = xfs_get_defquota(qi, xfs_dquot_type(dq)); > > -#ifdef DEBUG > - 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 (!dq->q_blk.timer) { > - if ((dq->q_blk.softlimit && > - (dq->q_blk.count > dq->q_blk.softlimit)) || > - (dq->q_blk.hardlimit && > - (dq->q_blk.count > dq->q_blk.hardlimit))) { > - dq->q_blk.timer = ktime_get_real_seconds() + > - defq->dfq_blk.timelimit; > - } else { > - dq->q_blk.warnings = 0; > - } > - } else { > - if ((!dq->q_blk.softlimit || > - (dq->q_blk.count <= dq->q_blk.softlimit)) && > - (!dq->q_blk.hardlimit || > - (dq->q_blk.count <= dq->q_blk.hardlimit))) { > - dq->q_blk.timer = 0; > - } > - } > - > - if (!dq->q_ino.timer) { > - if ((dq->q_ino.softlimit && > - (dq->q_ino.count > dq->q_ino.softlimit)) || > - (dq->q_ino.hardlimit && > - (dq->q_ino.count > dq->q_ino.hardlimit))) { > - dq->q_ino.timer = ktime_get_real_seconds() + > - defq->dfq_ino.timelimit; > - } else { > - dq->q_ino.warnings = 0; > - } > - } else { > - if ((!dq->q_ino.softlimit || > - (dq->q_ino.count <= dq->q_ino.softlimit)) && > - (!dq->q_ino.hardlimit || > - (dq->q_ino.count <= dq->q_ino.hardlimit))) { > - dq->q_ino.timer = 0; > - } > - } > - > - if (!dq->q_rtb.timer) { > - if ((dq->q_rtb.softlimit && > - (dq->q_rtb.count > dq->q_rtb.softlimit)) || > - (dq->q_rtb.hardlimit && > - (dq->q_rtb.count > dq->q_rtb.hardlimit))) { > - dq->q_rtb.timer = ktime_get_real_seconds() + > - defq->dfq_rtb.timelimit; > - } else { > - dq->q_rtb.warnings = 0; > - } > - } else { > - if ((!dq->q_rtb.softlimit || > - (dq->q_rtb.count <= dq->q_rtb.softlimit)) && > - (!dq->q_rtb.hardlimit || > - (dq->q_rtb.count <= dq->q_rtb.hardlimit))) { > - dq->q_rtb.timer = 0; > - } > - } > + xfs_qm_adjust_res_timer(&dq->q_blk, &defq->dfq_blk); > + xfs_qm_adjust_res_timer(&dq->q_ino, &defq->dfq_ino); > + xfs_qm_adjust_res_timer(&dq->q_rtb, &defq->dfq_rtb); > } > > /* > > -- chandan
On Wed, Jul 01, 2020 at 09:56:21AM +0100, Christoph Hellwig wrote: > On Tue, Jun 30, 2020 at 08:43:20AM -0700, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > Refactor the open-coded test for whether or not we're over quota. > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > > --- > > fs/xfs/xfs_dquot.c | 95 ++++++++++++++++------------------------------------ > > 1 file changed, 30 insertions(+), 65 deletions(-) > > > > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > > index 35a113d1b42b..ef34c82c28a0 100644 > > --- a/fs/xfs/xfs_dquot.c > > +++ b/fs/xfs/xfs_dquot.c > > @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits( > > xfs_dquot_set_prealloc_limits(dq); > > } > > > > +/* > > + * Determine if this quota counter is over either limit and set the quota > > + * timers as appropriate. > > + */ > > +static inline void > > +xfs_qm_adjust_res_timer( > > + struct xfs_dquot_res *res, > > + struct xfs_def_qres *dres) > > +{ > > + bool over; > > + > > +#ifdef DEBUG > > + if (res->hardlimit) > > + ASSERT(res->softlimit <= res->hardlimit); > > +#endif > > Maybe: > ASSERRT(!res->hardlimit || res->softlimit <= res->hardlimit); Changed. > > > + > > + over = (res->softlimit && res->count > res->softlimit) || > > + (res->hardlimit && res->count > res->hardlimit); > > + > > + if (over && res->timer == 0) > > + res->timer = ktime_get_real_seconds() + dres->timelimit; > > + else if (!over && res->timer != 0) > > + res->timer = 0; > > + else if (!over && res->timer == 0) > > + res->warnings = 0; > > What about: > > if ((res->softlimit && res->count > res->softlimit) || > (res->hardlimit && res->count > res->hardlimit)) { > if (res->timer == 0) > res->timer = ktime_get_real_seconds() + dres->timelimit; > } else { > if (res->timer) > res->timer = 0; > else > res->warnings = 0; > } I don't care either way, but the last time I sent this patch out, Eric and Amir seemed to want a flatter if structure: https://lore.kernel.org/linux-xfs/b979d33d-361b-88cd-699c-7e5f1c621698@sandeen.net/ https://lore.kernel.org/linux-xfs/CAOQ4uxiveTQu8_7UOvN07=P4o9hBBZTCyu4sSw5UpbrNPQL2pQ@mail.gmail.com/ Granted that was before I pulled the whole thing into a separate helper function, so maybe the context is different here...? --D
On Wed, Jul 01, 2020 at 09:42:08AM +0100, Christoph Hellwig wrote: > On Tue, Jun 30, 2020 at 08:42:09AM -0700, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > While loading dquot records off disk, make sure that the quota type > > flags are the same between the incore dquot and the ondisk dquot. > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > > --- > > fs/xfs/xfs_dquot.c | 23 ++++++++++++++++++++--- > > 1 file changed, 20 insertions(+), 3 deletions(-) > > > > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > > index d5b7f03e93c8..46c8ca83c04d 100644 > > --- a/fs/xfs/xfs_dquot.c > > +++ b/fs/xfs/xfs_dquot.c > > @@ -524,13 +524,27 @@ xfs_dquot_alloc( > > } > > > > /* Copy the in-core quota fields in from the on-disk buffer. */ > > -STATIC void > > +STATIC int > > xfs_dquot_from_disk( > > struct xfs_dquot *dqp, > > struct xfs_buf *bp) > > { > > struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset; > > > > + /* > > + * The only field the verifier didn't check was the quota type flag, so > > + * do that here. > > + */ > > + if ((dqp->dq_flags & XFS_DQ_ALLTYPES) != > > + (ddqp->d_flags & XFS_DQ_ALLTYPES) || > > + dqp->q_core.d_id != ddqp->d_id) { > > The comment looks a little weird, as this also checks d_id. Also > xfs_dquot_verify verifies d_flags against generally bogus value, it > just doesn't check that it matches the type we are looking for. > Last but not least dqp->dq_flags only contains the type at this > point. > > So what about something like: > > /* > * Ensure we got the type and ID we were looking for. Everything else > * we checked by the verifier. > */ > if ((ddqp->d_flags & XFS_DQ_ALLTYPES) != dqp->dq_flags || > ddqp->d_id != dqp->q_core.d_id) Sounds good to me. I'll make that change. --D >
On 7/1/20 12:51 PM, Darrick J. Wong wrote:
> On Wed, Jul 01, 2020 at 09:56:21AM +0100, Christoph Hellwig wrote:
>> On Tue, Jun 30, 2020 at 08:43:20AM -0700, Darrick J. Wong wrote:
>>> From: Darrick J. Wong <darrick.wong@oracle.com>
>>>
>>> Refactor the open-coded test for whether or not we're over quota.
>>>
>>> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
>>> ---
>>> fs/xfs/xfs_dquot.c | 95 ++++++++++++++++------------------------------------
>>> 1 file changed, 30 insertions(+), 65 deletions(-)
>>>
>>>
>>> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
>>> index 35a113d1b42b..ef34c82c28a0 100644
>>> --- a/fs/xfs/xfs_dquot.c
>>> +++ b/fs/xfs/xfs_dquot.c
>>> @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits(
>>> xfs_dquot_set_prealloc_limits(dq);
>>> }
>>>
>>> +/*
>>> + * Determine if this quota counter is over either limit and set the quota
>>> + * timers as appropriate.
>>> + */
>>> +static inline void
>>> +xfs_qm_adjust_res_timer(
>>> + struct xfs_dquot_res *res,
>>> + struct xfs_def_qres *dres)
>>> +{
>>> + bool over;
>>> +
>>> +#ifdef DEBUG
>>> + if (res->hardlimit)
>>> + ASSERT(res->softlimit <= res->hardlimit);
>>> +#endif
>>
>> Maybe:
>> ASSERRT(!res->hardlimit || res->softlimit <= res->hardlimit);
>
> Changed.
>
>>
>>> +
>>> + over = (res->softlimit && res->count > res->softlimit) ||
>>> + (res->hardlimit && res->count > res->hardlimit);
>>> +
>>> + if (over && res->timer == 0)
>>> + res->timer = ktime_get_real_seconds() + dres->timelimit;
>>> + else if (!over && res->timer != 0)
>>> + res->timer = 0;
>>> + else if (!over && res->timer == 0)
>>> + res->warnings = 0;
>>
>> What about:
>>
>> if ((res->softlimit && res->count > res->softlimit) ||
>> (res->hardlimit && res->count > res->hardlimit)) {
>> if (res->timer == 0)
>> res->timer = ktime_get_real_seconds() + dres->timelimit;
>> } else {
>> if (res->timer)
>> res->timer = 0;
>> else
>> res->warnings = 0;
>> }
>
> I don't care either way, but the last time I sent this patch out, Eric
> and Amir seemed to want a flatter if structure:
>
> https://lore.kernel.org/linux-xfs/b979d33d-361b-88cd-699c-7e5f1c621698@sandeen.net/
> https://lore.kernel.org/linux-xfs/CAOQ4uxiveTQu8_7UOvN07=P4o9hBBZTCyu4sSw5UpbrNPQL2pQ@mail.gmail.com/
>
> Granted that was before I pulled the whole thing into a separate helper
> function, so maybe the context is different here...?
I think it is different. I'm not too hung up about either way and
can't promise to dedicate time to thinking about it soon, so -
as you wish. :)
-Eric
On Wed, Jul 01, 2020 at 09:47:14AM +0100, Christoph Hellwig wrote:
> > #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
> >
> > +#define XFS_DQ_ONDISK (XFS_DQ_ALLTYPES)
> > +
>
> I really wonder if we should split the on-disk type and the in-core
> flags properly instead.
>
> That is propagate the u8 flags from the on-disk field directly,
> and use a separate field for the in-memory flags dirty and freeing
> flags, as that this kind of mixing up is bound to eventually create
> problems.
I was already half-inclined to try to separate them anyway, guess I'll
add that to this series.
--D
On 6/30/20 8:42 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Use the incore dq_flags to figure out the dquot type. This is the first > step towards removing xfs_disk_dquot from the incore dquot. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Ok, seems reasonable Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/libxfs/xfs_quota_defs.h | 2 ++ > fs/xfs/scrub/quota.c | 4 ---- > fs/xfs/xfs_dquot.c | 33 +++++++++++++++++++++++++++++++-- > fs/xfs/xfs_dquot.h | 2 ++ > fs/xfs/xfs_dquot_item.c | 6 ++++-- > fs/xfs/xfs_qm.c | 4 ++-- > fs/xfs/xfs_qm.h | 2 +- > fs/xfs/xfs_qm_syscalls.c | 9 +++------ > 8 files changed, 45 insertions(+), 17 deletions(-) > > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h > index 56d9dd787e7b..459023b0a304 100644 > --- a/fs/xfs/libxfs/xfs_quota_defs.h > +++ b/fs/xfs/libxfs/xfs_quota_defs.h > @@ -29,6 +29,8 @@ typedef uint16_t xfs_qwarncnt_t; > > #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) > > +#define XFS_DQ_ONDISK (XFS_DQ_ALLTYPES) > + > #define XFS_DQ_FLAGS \ > { XFS_DQ_USER, "USER" }, \ > { XFS_DQ_PROJ, "PROJ" }, \ > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index 905a34558361..710659d3fa28 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -108,10 +108,6 @@ xchk_quota_item( > > sqi->last_id = id; > > - /* Did we get the dquot type we wanted? */ > - if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES)) > - xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > - > if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 46c8ca83c04d..59d1bce34a98 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -561,6 +561,16 @@ xfs_dquot_from_disk( > return 0; > } > > +/* Copy the in-core quota fields into the on-disk buffer. */ > +void > +xfs_dquot_to_disk( > + struct xfs_disk_dquot *ddqp, > + struct xfs_dquot *dqp) > +{ > + memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); > + ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK; > +} > + > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > static int > xfs_qm_dqread_alloc( > @@ -1108,6 +1118,17 @@ xfs_qm_dqflush_done( > xfs_dqfunlock(dqp); > } > > +/* Check incore dquot for errors before we flush. */ > +static xfs_failaddr_t > +xfs_qm_dqflush_check( > + struct xfs_dquot *dqp) > +{ > + if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) > + return __this_address; > + > + return NULL; > +} > + > /* > * Write a modified dquot to disk. > * The dquot must be locked and the flush lock too taken by caller. > @@ -1166,8 +1187,16 @@ xfs_qm_dqflush( > goto out_abort; > } > > - /* This is the only portion of data that needs to persist */ > - memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); > + fa = xfs_qm_dqflush_check(dqp); > + if (fa) { > + xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > + be32_to_cpu(dqp->q_core.d_id), fa); > + xfs_buf_relse(bp); > + error = -EFSCORRUPTED; > + goto out_abort; > + } > + > + xfs_dquot_to_disk(ddqp, dqp); > > /* > * Clear the dirty field and remember the flush lsn for later use. > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 71e36c85e20b..1b1a4261a580 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -144,6 +144,8 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp) > return false; > } > > +void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp); > + > #define XFS_DQ_IS_LOCKED(dqp) (mutex_is_locked(&((dqp)->q_qlock))) > #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) > #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) > diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c > index 349c92d26570..ff0ab65cf413 100644 > --- a/fs/xfs/xfs_dquot_item.c > +++ b/fs/xfs/xfs_dquot_item.c > @@ -45,6 +45,7 @@ xfs_qm_dquot_logitem_format( > struct xfs_log_item *lip, > struct xfs_log_vec *lv) > { > + struct xfs_disk_dquot ddq; > struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); > struct xfs_log_iovec *vecp = NULL; > struct xfs_dq_logformat *qlf; > @@ -58,8 +59,9 @@ xfs_qm_dquot_logitem_format( > qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset; > xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat)); > > - xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, > - &qlip->qli_dquot->q_core, > + xfs_dquot_to_disk(&ddq, qlip->qli_dquot); > + > + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, &ddq, > sizeof(struct xfs_disk_dquot)); > } > > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 938023dd8ce5..632025c2f00b 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -161,7 +161,7 @@ xfs_qm_dqpurge( > xfs_dqfunlock(dqp); > xfs_dqunlock(dqp); > > - radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags), > + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), > be32_to_cpu(dqp->q_core.d_id)); > qi->qi_dquots--; > > @@ -1598,7 +1598,7 @@ xfs_qm_dqfree_one( > struct xfs_quotainfo *qi = mp->m_quotainfo; > > mutex_lock(&qi->qi_tree_lock); > - radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags), > + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), > be32_to_cpu(dqp->q_core.d_id)); > > qi->qi_dquots--; > diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h > index 7b0e771fcbce..43b4650cdcdf 100644 > --- a/fs/xfs/xfs_qm.h > +++ b/fs/xfs/xfs_qm.h > @@ -85,7 +85,7 @@ xfs_dquot_tree( > struct xfs_quotainfo *qi, > int type) > { > - switch (type) { > + switch (type & XFS_DQ_ALLTYPES) { > case XFS_DQ_USER: > return &qi->qi_uquota_tree; > case XFS_DQ_GROUP: > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 7effd7a28136..8cbb65f01bf1 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -644,12 +644,9 @@ xfs_qm_scall_getquota_fill_qc( > * gets turned off. No need to confuse the user level code, > * so return zeroes in that case. > */ > - if ((!XFS_IS_UQUOTA_ENFORCED(mp) && > - dqp->q_core.d_flags == XFS_DQ_USER) || > - (!XFS_IS_GQUOTA_ENFORCED(mp) && > - dqp->q_core.d_flags == XFS_DQ_GROUP) || > - (!XFS_IS_PQUOTA_ENFORCED(mp) && > - dqp->q_core.d_flags == XFS_DQ_PROJ)) { > + if ((!XFS_IS_UQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_USER)) || > + (!XFS_IS_GQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_GROUP)) || > + (!XFS_IS_PQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_PROJ))) { > dst->d_spc_timer = 0; > dst->d_ino_timer = 0; > dst->d_rt_spc_timer = 0; >
On 6/30/20 8:42 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Add a dquot id field to the incore dquot, and use that instead of the > one in qcore. This eliminates a bunch of endian conversions and will > eventually allow us to remove qcore entirely. > > We also rearrange the start of xfs_dquot to remove padding holes, saving > 8 bytes. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Ok looks straight forward to me Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/scrub/quota.c | 19 ++++++++++++------- > fs/xfs/xfs_dquot.c | 25 +++++++++++-------------- > fs/xfs/xfs_dquot.h | 5 +++-- > fs/xfs/xfs_dquot_item.c | 2 +- > fs/xfs/xfs_qm.c | 22 ++++++++++------------ > fs/xfs/xfs_qm_syscalls.c | 4 ++-- > fs/xfs/xfs_trace.h | 2 +- > fs/xfs/xfs_trans_dquot.c | 8 +++----- > 8 files changed, 43 insertions(+), 44 deletions(-) > > > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index 710659d3fa28..9a271f115882 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -92,7 +92,6 @@ xchk_quota_item( > unsigned long long icount; > unsigned long long rcount; > xfs_ino_t fs_icount; > - xfs_dqid_t id = be32_to_cpu(d->d_id); > int error = 0; > > if (xchk_should_terminate(sc, &error)) > @@ -102,11 +101,11 @@ xchk_quota_item( > * Except for the root dquot, the actual dquot we got must either have > * the same or higher id as we saw before. > */ > - offset = id / qi->qi_dqperchunk; > - if (id && id <= sqi->last_id) > + offset = dq->q_id / qi->qi_dqperchunk; > + if (dq->q_id && dq->q_id <= sqi->last_id) > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > > - sqi->last_id = id; > + sqi->last_id = dq->q_id; > > if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > @@ -171,13 +170,19 @@ xchk_quota_item( > * lower limit than the actual usage. However, we flag it for > * admin review. > */ > - if (id != 0 && bhard != 0 && bcount > bhard) > + if (dq->q_id == 0) > + goto out; > + > + if (bhard != 0 && bcount > bhard) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > - if (id != 0 && ihard != 0 && icount > ihard) > + > + if (ihard != 0 && icount > ihard) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > - if (id != 0 && rhard != 0 && rcount > rhard) > + > + if (rhard != 0 && rcount > rhard) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > > +out: > if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) > return -EFSCORRUPTED; > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 59d1bce34a98..76b35888e726 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -74,7 +74,7 @@ xfs_qm_adjust_dqlimits( > struct xfs_def_quota *defq; > int prealloc = 0; > > - ASSERT(d->d_id); > + ASSERT(dq->q_id); > defq = xfs_get_defquota(q, xfs_dquot_type(dq)); > > if (defq->bsoftlimit && !d->d_blk_softlimit) { > @@ -120,7 +120,7 @@ xfs_qm_adjust_dqtimers( > struct xfs_disk_dquot *d = &dq->q_core; > struct xfs_def_quota *defq; > > - ASSERT(d->d_id); > + ASSERT(dq->q_id); > defq = xfs_get_defquota(qi, xfs_dquot_type(dq)); > > #ifdef DEBUG > @@ -365,7 +365,7 @@ xfs_dquot_disk_alloc( > * Make a chunk of dquots out of this buffer and log > * the entire thing. > */ > - xfs_qm_init_dquot_blk(tp, mp, be32_to_cpu(dqp->q_core.d_id), > + xfs_qm_init_dquot_blk(tp, mp, dqp->q_id, > dqp->dq_flags & XFS_DQ_ALLTYPES, bp); > xfs_buf_set_ref(bp, XFS_DQUOT_REF); > > @@ -478,7 +478,7 @@ xfs_dquot_alloc( > dqp = kmem_zone_zalloc(xfs_qm_dqzone, 0); > > dqp->dq_flags = type; > - dqp->q_core.d_id = cpu_to_be32(id); > + dqp->q_id = id; > dqp->q_mount = mp; > INIT_LIST_HEAD(&dqp->q_lru); > mutex_init(&dqp->q_qlock); > @@ -537,10 +537,10 @@ xfs_dquot_from_disk( > */ > if ((dqp->dq_flags & XFS_DQ_ALLTYPES) != > (ddqp->d_flags & XFS_DQ_ALLTYPES) || > - dqp->q_core.d_id != ddqp->d_id) { > + dqp->q_id != be32_to_cpu(ddqp->d_id)) { > xfs_alert(bp->b_mount, > "Metadata corruption detected at %pS, quota %u", > - __this_address, be32_to_cpu(dqp->q_core.d_id)); > + __this_address, dqp->q_id); > xfs_alert(bp->b_mount, "Unmount and run xfs_repair"); > return -EFSCORRUPTED; > } > @@ -1177,11 +1177,10 @@ xfs_qm_dqflush( > ddqp = &dqb->dd_diskdq; > > /* sanity check the in-core structure before we flush */ > - fa = xfs_dquot_verify(mp, &dqp->q_core, be32_to_cpu(dqp->q_core.d_id), > - 0); > + fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0); > if (fa) { > xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > - be32_to_cpu(dqp->q_core.d_id), fa); > + dqp->q_id, fa); > xfs_buf_relse(bp); > error = -EFSCORRUPTED; > goto out_abort; > @@ -1190,7 +1189,7 @@ xfs_qm_dqflush( > fa = xfs_qm_dqflush_check(dqp); > if (fa) { > xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > - be32_to_cpu(dqp->q_core.d_id), fa); > + dqp->q_id, fa); > xfs_buf_relse(bp); > error = -EFSCORRUPTED; > goto out_abort; > @@ -1263,8 +1262,7 @@ xfs_dqlock2( > { > if (d1 && d2) { > ASSERT(d1 != d2); > - if (be32_to_cpu(d1->q_core.d_id) > > - be32_to_cpu(d2->q_core.d_id)) { > + if (d1->q_id > d2->q_id) { > mutex_lock(&d2->q_qlock); > mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED); > } else { > @@ -1332,9 +1330,8 @@ xfs_qm_dqiterate( > return error; > > error = iter_fn(dq, dqtype, priv); > - id = be32_to_cpu(dq->q_core.d_id); > + id = dq->q_id + 1; > xfs_qm_dqput(dq); > - id++; > } while (error == 0 && id != 0); > > return error; > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 1b1a4261a580..5ea1f1515979 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -31,12 +31,13 @@ enum { > * The incore dquot structure > */ > struct xfs_dquot { > - uint dq_flags; > struct list_head q_lru; > struct xfs_mount *q_mount; > + xfs_dqid_t q_id; > + uint dq_flags; > uint q_nrefs; > - xfs_daddr_t q_blkno; > int q_bufoffset; > + xfs_daddr_t q_blkno; > xfs_fileoff_t q_fileoffset; > > struct xfs_disk_dquot q_core; > diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c > index ff0ab65cf413..378d919997f1 100644 > --- a/fs/xfs/xfs_dquot_item.c > +++ b/fs/xfs/xfs_dquot_item.c > @@ -53,7 +53,7 @@ xfs_qm_dquot_logitem_format( > qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT); > qlf->qlf_type = XFS_LI_DQUOT; > qlf->qlf_size = 2; > - qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id); > + qlf->qlf_id = qlip->qli_dquot->q_id; > qlf->qlf_blkno = qlip->qli_dquot->q_blkno; > qlf->qlf_len = 1; > qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset; > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 632025c2f00b..95e51186bd57 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -79,7 +79,7 @@ xfs_qm_dquot_walk( > for (i = 0; i < nr_found; i++) { > struct xfs_dquot *dqp = batch[i]; > > - next_index = be32_to_cpu(dqp->q_core.d_id) + 1; > + next_index = dqp->q_id + 1; > > error = execute(batch[i], data); > if (error == -EAGAIN) { > @@ -161,8 +161,7 @@ xfs_qm_dqpurge( > xfs_dqfunlock(dqp); > xfs_dqunlock(dqp); > > - radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), > - be32_to_cpu(dqp->q_core.d_id)); > + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id); > qi->qi_dquots--; > > /* > @@ -1112,7 +1111,7 @@ xfs_qm_quotacheck_dqadjust( > * > * There are no timers for the default values set in the root dquot. > */ > - if (dqp->q_core.d_id) { > + if (dqp->q_id) { > xfs_qm_adjust_dqlimits(mp, dqp); > xfs_qm_adjust_dqtimers(mp, dqp); > } > @@ -1598,8 +1597,7 @@ xfs_qm_dqfree_one( > struct xfs_quotainfo *qi = mp->m_quotainfo; > > mutex_lock(&qi->qi_tree_lock); > - radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), > - be32_to_cpu(dqp->q_core.d_id)); > + radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id); > > qi->qi_dquots--; > mutex_unlock(&qi->qi_tree_lock); > @@ -1823,7 +1821,7 @@ xfs_qm_vop_chown_reserve( > XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS; > > if (XFS_IS_UQUOTA_ON(mp) && udqp && > - i_uid_read(VFS_I(ip)) != be32_to_cpu(udqp->q_core.d_id)) { > + i_uid_read(VFS_I(ip)) != udqp->q_id) { > udq_delblks = udqp; > /* > * If there are delayed allocation blocks, then we have to > @@ -1836,7 +1834,7 @@ xfs_qm_vop_chown_reserve( > } > } > if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp && > - i_gid_read(VFS_I(ip)) != be32_to_cpu(gdqp->q_core.d_id)) { > + i_gid_read(VFS_I(ip)) != gdqp->q_id) { > gdq_delblks = gdqp; > if (delblks) { > ASSERT(ip->i_gdquot); > @@ -1845,7 +1843,7 @@ xfs_qm_vop_chown_reserve( > } > > if (XFS_IS_PQUOTA_ON(ip->i_mount) && pdqp && > - ip->i_d.di_projid != be32_to_cpu(pdqp->q_core.d_id)) { > + ip->i_d.di_projid != pdqp->q_id) { > pdq_delblks = pdqp; > if (delblks) { > ASSERT(ip->i_pdquot); > @@ -1929,21 +1927,21 @@ xfs_qm_vop_create_dqattach( > > if (udqp && XFS_IS_UQUOTA_ON(mp)) { > ASSERT(ip->i_udquot == NULL); > - ASSERT(i_uid_read(VFS_I(ip)) == be32_to_cpu(udqp->q_core.d_id)); > + ASSERT(i_uid_read(VFS_I(ip)) == udqp->q_id); > > ip->i_udquot = xfs_qm_dqhold(udqp); > xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1); > } > if (gdqp && XFS_IS_GQUOTA_ON(mp)) { > ASSERT(ip->i_gdquot == NULL); > - ASSERT(i_gid_read(VFS_I(ip)) == be32_to_cpu(gdqp->q_core.d_id)); > + ASSERT(i_gid_read(VFS_I(ip)) == gdqp->q_id); > > ip->i_gdquot = xfs_qm_dqhold(gdqp); > xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1); > } > if (pdqp && XFS_IS_PQUOTA_ON(mp)) { > ASSERT(ip->i_pdquot == NULL); > - ASSERT(ip->i_d.di_projid == be32_to_cpu(pdqp->q_core.d_id)); > + ASSERT(ip->i_d.di_projid == pdqp->q_id); > > ip->i_pdquot = xfs_qm_dqhold(pdqp); > xfs_trans_mod_dquot(tp, pdqp, XFS_TRANS_DQ_ICOUNT, 1); > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 8cbb65f01bf1..90a11e7daf92 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -656,7 +656,7 @@ xfs_qm_scall_getquota_fill_qc( > if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) || > (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) || > (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) && > - dqp->q_core.d_id != 0) { > + dqp->q_id != 0) { > if ((dst->d_space > dst->d_spc_softlimit) && > (dst->d_spc_softlimit > 0)) { > ASSERT(dst->d_spc_timer != 0); > @@ -723,7 +723,7 @@ xfs_qm_scall_getquota_next( > return error; > > /* Fill in the ID we actually read from disk */ > - *id = be32_to_cpu(dqp->q_core.d_id); > + *id = dqp->q_id; > > xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); > > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 2c5df8315351..78d9dbc7614d 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -876,7 +876,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, > ), \ > TP_fast_assign( > __entry->dev = dqp->q_mount->m_super->s_dev; > - __entry->id = be32_to_cpu(dqp->q_core.d_id); > + __entry->id = dqp->q_id; > __entry->flags = dqp->dq_flags; > __entry->nrefs = dqp->q_nrefs; > __entry->res_bcount = dqp->q_res_bcount; > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index ed0ce8b301b4..a2656ec6ea76 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -386,7 +386,7 @@ xfs_trans_apply_dquot_deltas( > * Get any default limits in use. > * Start/reset the timer(s) if needed. > */ > - if (d->d_id) { > + if (dqp->q_id) { > xfs_qm_adjust_dqlimits(tp->t_mountp, dqp); > xfs_qm_adjust_dqtimers(tp->t_mountp, dqp); > } > @@ -558,8 +558,7 @@ xfs_quota_warn( > else > qtype = GRPQUOTA; > > - quota_send_warning(make_kqid(&init_user_ns, qtype, > - be32_to_cpu(dqp->q_core.d_id)), > + quota_send_warning(make_kqid(&init_user_ns, qtype, dqp->q_id), > mp->m_super->s_dev, type); > } > > @@ -618,8 +617,7 @@ xfs_trans_dqresv( > resbcountp = &dqp->q_res_rtbcount; > } > > - if ((flags & XFS_QMOPT_FORCE_RES) == 0 && > - dqp->q_core.d_id && > + if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_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)))) { >
On 6/30/20 8:42 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Introduce a new struct xfs_dquot_res that we'll use to track all the > incore data for a particular resource type (block, inode, rt block). > This will help us (once we've eliminated q_core) to declutter quota > functions that currently open-code field access or pass around fields > around explicitly. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Looks ok Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_dquot.c | 6 +++--- > fs/xfs/xfs_dquot.h | 18 +++++++++++------- > fs/xfs/xfs_iomap.c | 6 +++--- > fs/xfs/xfs_qm.c | 6 +++--- > fs/xfs/xfs_qm_bhv.c | 8 ++++---- > fs/xfs/xfs_qm_syscalls.c | 6 +++--- > fs/xfs/xfs_trace.h | 2 +- > fs/xfs/xfs_trans_dquot.c | 42 +++++++++++++++++++++--------------------- > 8 files changed, 49 insertions(+), 45 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 76b35888e726..03624a8f0566 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -552,9 +552,9 @@ xfs_dquot_from_disk( > * Reservation counters are defined as reservation plus current usage > * to avoid having to add every time. > */ > - dqp->q_res_bcount = be64_to_cpu(ddqp->d_bcount); > - dqp->q_res_icount = be64_to_cpu(ddqp->d_icount); > - dqp->q_res_rtbcount = be64_to_cpu(ddqp->d_rtbcount); > + dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount); > + dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount); > + dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount); > > /* initialize the dquot speculative prealloc thresholds */ > xfs_dquot_set_prealloc_limits(dqp); > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 5ea1f1515979..cb20df1e774f 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -27,6 +27,11 @@ enum { > XFS_QLOWSP_MAX > }; > > +struct xfs_dquot_res { > + /* Total resources allocated and reserved. */ > + xfs_qcnt_t reserved; > +}; > + > /* > * The incore dquot structure > */ > @@ -40,14 +45,13 @@ struct xfs_dquot { > xfs_daddr_t q_blkno; > xfs_fileoff_t q_fileoffset; > > + struct xfs_dquot_res q_blk; /* regular blocks */ > + struct xfs_dquot_res q_ino; /* inodes */ > + struct xfs_dquot_res q_rtb; /* realtime blocks */ > + > struct xfs_disk_dquot q_core; > struct xfs_dq_logitem q_logitem; > - /* total regular nblks used+reserved */ > - xfs_qcnt_t q_res_bcount; > - /* total inos allocd+reserved */ > - xfs_qcnt_t q_res_icount; > - /* total realtime blks used+reserved */ > - xfs_qcnt_t q_res_rtbcount; > + > xfs_qcnt_t q_prealloc_lo_wmark; > xfs_qcnt_t q_prealloc_hi_wmark; > int64_t q_low_space[XFS_QLOWSP_MAX]; > @@ -138,7 +142,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_res_bcount; > + freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_blk.reserved; > if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT]) > return true; > > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > index b9a8c3798e08..f60a6e44363b 100644 > --- a/fs/xfs/xfs_iomap.c > +++ b/fs/xfs/xfs_iomap.c > @@ -307,7 +307,7 @@ xfs_quota_need_throttle( > return false; > > /* under the lo watermark, no throttle */ > - if (dq->q_res_bcount + alloc_blocks < dq->q_prealloc_lo_wmark) > + if (dq->q_blk.reserved + alloc_blocks < dq->q_prealloc_lo_wmark) > return false; > > return true; > @@ -326,13 +326,13 @@ xfs_quota_calc_throttle( > struct xfs_dquot *dq = xfs_inode_dquot(ip, type); > > /* no dq, or over hi wmark, squash the prealloc completely */ > - if (!dq || dq->q_res_bcount >= dq->q_prealloc_hi_wmark) { > + if (!dq || dq->q_blk.reserved >= dq->q_prealloc_hi_wmark) { > *qblocks = 0; > *qfreesp = 0; > return; > } > > - freesp = dq->q_prealloc_hi_wmark - dq->q_res_bcount; > + freesp = dq->q_prealloc_hi_wmark - dq->q_blk.reserved; > if (freesp < dq->q_low_space[XFS_QLOWSP_5_PCNT]) { > shift = 2; > if (freesp < dq->q_low_space[XFS_QLOWSP_3_PCNT]) > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 95e51186bd57..6ce3a4402041 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -1096,14 +1096,14 @@ xfs_qm_quotacheck_dqadjust( > * resource usage. > */ > be64_add_cpu(&dqp->q_core.d_icount, 1); > - dqp->q_res_icount++; > + dqp->q_ino.reserved++; > if (nblks) { > be64_add_cpu(&dqp->q_core.d_bcount, nblks); > - dqp->q_res_bcount += nblks; > + dqp->q_blk.reserved += nblks; > } > if (rtblks) { > be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks); > - dqp->q_res_rtbcount += rtblks; > + dqp->q_rtb.reserved += rtblks; > } > > /* > diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c > index fc2fa418919f..94b2b4b0fc17 100644 > --- a/fs/xfs/xfs_qm_bhv.c > +++ b/fs/xfs/xfs_qm_bhv.c > @@ -29,8 +29,8 @@ xfs_fill_statvfs_from_dquot( > if (limit && statp->f_blocks > limit) { > statp->f_blocks = limit; > statp->f_bfree = statp->f_bavail = > - (statp->f_blocks > dqp->q_res_bcount) ? > - (statp->f_blocks - dqp->q_res_bcount) : 0; > + (statp->f_blocks > dqp->q_blk.reserved) ? > + (statp->f_blocks - dqp->q_blk.reserved) : 0; > } > > limit = dqp->q_core.d_ino_softlimit ? > @@ -39,8 +39,8 @@ xfs_fill_statvfs_from_dquot( > if (limit && statp->f_files > limit) { > statp->f_files = limit; > statp->f_ffree = > - (statp->f_files > dqp->q_res_icount) ? > - (statp->f_files - dqp->q_res_icount) : 0; > + (statp->f_files > dqp->q_ino.reserved) ? > + (statp->f_files - dqp->q_ino.reserved) : 0; > } > } > > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 90a11e7daf92..56fe80395679 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -625,8 +625,8 @@ xfs_qm_scall_getquota_fill_qc( > XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit)); > dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); > dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); > - dst->d_space = XFS_FSB_TO_B(mp, dqp->q_res_bcount); > - dst->d_ino_count = dqp->q_res_icount; > + dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); > + dst->d_ino_count = dqp->q_ino.reserved; > dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); > dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); > dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); > @@ -635,7 +635,7 @@ xfs_qm_scall_getquota_fill_qc( > XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit)); > dst->d_rt_spc_softlimit = > XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit)); > - dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_res_rtbcount); > + dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); > dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); > > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 78d9dbc7614d..71567ed367f2 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -879,7 +879,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, > __entry->id = dqp->q_id; > __entry->flags = dqp->dq_flags; > __entry->nrefs = dqp->q_nrefs; > - __entry->res_bcount = dqp->q_res_bcount; > + __entry->res_bcount = dqp->q_blk.reserved; > __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); > __entry->icount = be64_to_cpu(dqp->q_core.d_icount); > __entry->blk_hardlimit = > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index a2656ec6ea76..469bf7946d3d 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -409,11 +409,11 @@ xfs_trans_apply_dquot_deltas( > > if (qtrx->qt_blk_res != blk_res_used) { > if (qtrx->qt_blk_res > blk_res_used) > - dqp->q_res_bcount -= (xfs_qcnt_t) > + dqp->q_blk.reserved -= (xfs_qcnt_t) > (qtrx->qt_blk_res - > blk_res_used); > else > - dqp->q_res_bcount -= (xfs_qcnt_t) > + dqp->q_blk.reserved -= (xfs_qcnt_t) > (blk_res_used - > qtrx->qt_blk_res); > } > @@ -426,7 +426,7 @@ xfs_trans_apply_dquot_deltas( > * deliberately skip quota reservations. > */ > if (qtrx->qt_bcount_delta) { > - dqp->q_res_bcount += > + dqp->q_blk.reserved += > (xfs_qcnt_t)qtrx->qt_bcount_delta; > } > } > @@ -437,17 +437,17 @@ xfs_trans_apply_dquot_deltas( > if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) { > if (qtrx->qt_rtblk_res > > qtrx->qt_rtblk_res_used) > - dqp->q_res_rtbcount -= (xfs_qcnt_t) > + dqp->q_rtb.reserved -= (xfs_qcnt_t) > (qtrx->qt_rtblk_res - > qtrx->qt_rtblk_res_used); > else > - dqp->q_res_rtbcount -= (xfs_qcnt_t) > + dqp->q_rtb.reserved -= (xfs_qcnt_t) > (qtrx->qt_rtblk_res_used - > qtrx->qt_rtblk_res); > } > } else { > if (qtrx->qt_rtbcount_delta) > - dqp->q_res_rtbcount += > + dqp->q_rtb.reserved += > (xfs_qcnt_t)qtrx->qt_rtbcount_delta; > } > > @@ -458,20 +458,20 @@ xfs_trans_apply_dquot_deltas( > ASSERT(qtrx->qt_ino_res >= > qtrx->qt_ino_res_used); > if (qtrx->qt_ino_res > qtrx->qt_ino_res_used) > - dqp->q_res_icount -= (xfs_qcnt_t) > + dqp->q_ino.reserved -= (xfs_qcnt_t) > (qtrx->qt_ino_res - > qtrx->qt_ino_res_used); > } else { > if (qtrx->qt_icount_delta) > - dqp->q_res_icount += > + dqp->q_ino.reserved += > (xfs_qcnt_t)qtrx->qt_icount_delta; > } > > - ASSERT(dqp->q_res_bcount >= > + ASSERT(dqp->q_blk.reserved >= > be64_to_cpu(dqp->q_core.d_bcount)); > - ASSERT(dqp->q_res_icount >= > + ASSERT(dqp->q_ino.reserved >= > be64_to_cpu(dqp->q_core.d_icount)); > - ASSERT(dqp->q_res_rtbcount >= > + ASSERT(dqp->q_rtb.reserved >= > be64_to_cpu(dqp->q_core.d_rtbcount)); > } > } > @@ -516,7 +516,7 @@ xfs_trans_unreserve_and_mod_dquots( > if (qtrx->qt_blk_res) { > xfs_dqlock(dqp); > locked = true; > - dqp->q_res_bcount -= > + dqp->q_blk.reserved -= > (xfs_qcnt_t)qtrx->qt_blk_res; > } > if (qtrx->qt_ino_res) { > @@ -524,7 +524,7 @@ xfs_trans_unreserve_and_mod_dquots( > xfs_dqlock(dqp); > locked = true; > } > - dqp->q_res_icount -= > + dqp->q_ino.reserved -= > (xfs_qcnt_t)qtrx->qt_ino_res; > } > > @@ -533,7 +533,7 @@ xfs_trans_unreserve_and_mod_dquots( > xfs_dqlock(dqp); > locked = true; > } > - dqp->q_res_rtbcount -= > + dqp->q_rtb.reserved -= > (xfs_qcnt_t)qtrx->qt_rtblk_res; > } > if (locked) > @@ -602,7 +602,7 @@ xfs_trans_dqresv( > timer = be32_to_cpu(dqp->q_core.d_btimer); > warns = be16_to_cpu(dqp->q_core.d_bwarns); > warnlimit = defq->bwarnlimit; > - resbcountp = &dqp->q_res_bcount; > + resbcountp = &dqp->q_blk.reserved; > } else { > ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); > hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit); > @@ -614,7 +614,7 @@ xfs_trans_dqresv( > timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > warns = be16_to_cpu(dqp->q_core.d_rtbwarns); > warnlimit = defq->rtbwarnlimit; > - resbcountp = &dqp->q_res_rtbcount; > + resbcountp = &dqp->q_rtb.reserved; > } > > if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id && > @@ -675,11 +675,11 @@ xfs_trans_dqresv( > > /* > * Change the reservation, but not the actual usage. > - * Note that q_res_bcount = q_core.d_bcount + resv > + * Note that q_blk.reserved = q_core.d_bcount + resv > */ > (*resbcountp) += (xfs_qcnt_t)nblks; > if (ninos != 0) > - dqp->q_res_icount += (xfs_qcnt_t)ninos; > + dqp->q_ino.reserved += (xfs_qcnt_t)ninos; > > /* > * note the reservation amt in the trans struct too, > @@ -700,9 +700,9 @@ xfs_trans_dqresv( > 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)); > + ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount)); > + ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount)); > + ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount)); > > xfs_dqunlock(dqp); > return 0; >
On 6/30/20 8:42 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > 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: Darrick J. Wong <darrick.wong@oracle.com> Ok, looks reasonable to me Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/scrub/quota.c | 36 ++++-------- > fs/xfs/xfs_dquot.c | 136 ++++++++++++++++++++++++++-------------------- > fs/xfs/xfs_dquot.h | 6 ++ > fs/xfs/xfs_qm.c | 14 ++--- > fs/xfs/xfs_qm.h | 12 ++-- > fs/xfs/xfs_qm_bhv.c | 12 ++-- > fs/xfs/xfs_qm_syscalls.c | 40 ++++++-------- > fs/xfs/xfs_trace.h | 12 +--- > fs/xfs/xfs_trans_dquot.c | 12 ++-- > 9 files changed, 139 insertions(+), 141 deletions(-) > > > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index 9a271f115882..1a1c6996fc69 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -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; > @@ -110,15 +104,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 > @@ -127,19 +112,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. */ > @@ -173,13 +158,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: > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 03624a8f0566..63f744bcbc90 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -70,29 +70,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); > @@ -124,82 +123,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; > } > } > @@ -290,8 +274,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 > @@ -569,6 +559,12 @@ xfs_dquot_to_disk( > { > memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); > ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK; > + 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. */ > @@ -1123,9 +1119,29 @@ static xfs_failaddr_t > xfs_qm_dqflush_check( > struct xfs_dquot *dqp) > { > + struct xfs_disk_dquot *ddq = &dqp->q_core; > + > if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) > 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; > } > > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index cb20df1e774f..edb49788c476 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -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; > }; > > /* > @@ -142,7 +146,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; > > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 6ce3a4402041..54fc3aac1a68 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -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); > } > > diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h > index 43b4650cdcdf..84cb8af468b7 100644 > --- a/fs/xfs/xfs_qm.h > +++ b/fs/xfs/xfs_qm.h > @@ -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) > diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c > index 94b2b4b0fc17..0993217e5ac8 100644 > --- a/fs/xfs/xfs_qm_bhv.c > +++ b/fs/xfs/xfs_qm_bhv.c > @@ -23,9 +23,9 @@ xfs_fill_statvfs_from_dquot( > { > uint64_t limit; > > - limit = dqp->q_core.d_blk_softlimit ? > - be64_to_cpu(dqp->q_core.d_blk_softlimit) : > - be64_to_cpu(dqp->q_core.d_blk_hardlimit); > + limit = dqp->q_blk.softlimit ? > + dqp->q_blk.softlimit : > + dqp->q_blk.hardlimit; > if (limit && statp->f_blocks > limit) { > statp->f_blocks = limit; > statp->f_bfree = statp->f_bavail = > @@ -33,9 +33,9 @@ xfs_fill_statvfs_from_dquot( > (statp->f_blocks - dqp->q_blk.reserved) : 0; > } > > - limit = dqp->q_core.d_ino_softlimit ? > - be64_to_cpu(dqp->q_core.d_ino_softlimit) : > - be64_to_cpu(dqp->q_core.d_ino_hardlimit); > + limit = dqp->q_ino.softlimit ? > + dqp->q_ino.softlimit : > + dqp->q_ino.hardlimit; > if (limit && statp->f_files > limit) { > statp->f_files = limit; > statp->f_ffree = > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 56fe80395679..ab596d389e3e 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -495,13 +495,13 @@ xfs_qm_scall_setqlim( > */ > hard = (newlim->d_fieldmask & QC_SPC_HARD) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : > - be64_to_cpu(ddq->d_blk_hardlimit); > + dqp->q_blk.hardlimit; > soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : > - be64_to_cpu(ddq->d_blk_softlimit); > + dqp->q_blk.softlimit; > if (hard == 0 || hard >= soft) { > - ddq->d_blk_hardlimit = cpu_to_be64(hard); > - ddq->d_blk_softlimit = cpu_to_be64(soft); > + dqp->q_blk.hardlimit = hard; > + dqp->q_blk.softlimit = soft; > xfs_dquot_set_prealloc_limits(dqp); > if (id == 0) { > defq->bhardlimit = hard; > @@ -512,13 +512,13 @@ xfs_qm_scall_setqlim( > } > hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : > - be64_to_cpu(ddq->d_rtb_hardlimit); > + dqp->q_rtb.hardlimit; > soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : > - be64_to_cpu(ddq->d_rtb_softlimit); > + dqp->q_rtb.softlimit; > if (hard == 0 || hard >= soft) { > - ddq->d_rtb_hardlimit = cpu_to_be64(hard); > - ddq->d_rtb_softlimit = cpu_to_be64(soft); > + dqp->q_rtb.hardlimit = hard; > + dqp->q_rtb.softlimit = soft; > if (id == 0) { > defq->rtbhardlimit = hard; > defq->rtbsoftlimit = soft; > @@ -529,13 +529,13 @@ xfs_qm_scall_setqlim( > > hard = (newlim->d_fieldmask & QC_INO_HARD) ? > (xfs_qcnt_t) newlim->d_ino_hardlimit : > - be64_to_cpu(ddq->d_ino_hardlimit); > + dqp->q_ino.hardlimit; > soft = (newlim->d_fieldmask & QC_INO_SOFT) ? > (xfs_qcnt_t) newlim->d_ino_softlimit : > - be64_to_cpu(ddq->d_ino_softlimit); > + dqp->q_ino.softlimit; > if (hard == 0 || hard >= soft) { > - ddq->d_ino_hardlimit = cpu_to_be64(hard); > - ddq->d_ino_softlimit = cpu_to_be64(soft); > + dqp->q_ino.hardlimit = hard; > + dqp->q_ino.softlimit = soft; > if (id == 0) { > defq->ihardlimit = hard; > defq->isoftlimit = soft; > @@ -619,10 +619,8 @@ xfs_qm_scall_getquota_fill_qc( > struct qc_dqblk *dst) > { > memset(dst, 0, sizeof(*dst)); > - dst->d_spc_hardlimit = > - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit)); > - dst->d_spc_softlimit = > - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit)); > + dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit); > + dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit); > dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); > dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); > dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); > @@ -631,10 +629,8 @@ xfs_qm_scall_getquota_fill_qc( > dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); > dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); > dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns); > - dst->d_rt_spc_hardlimit = > - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit)); > - dst->d_rt_spc_softlimit = > - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit)); > + dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); > + dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); > dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); > dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); > @@ -661,8 +657,8 @@ xfs_qm_scall_getquota_fill_qc( > (dst->d_spc_softlimit > 0)) { > ASSERT(dst->d_spc_timer != 0); > } > - if ((dst->d_ino_count > dst->d_ino_softlimit) && > - (dst->d_ino_softlimit > 0)) { > + if ((dst->d_ino_count > dqp->q_ino.softlimit) && > + (dqp->q_ino.softlimit > 0)) { > ASSERT(dst->d_ino_timer != 0); > } > } > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 71567ed367f2..7f744a37dc0e 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -882,14 +882,10 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, > __entry->res_bcount = dqp->q_blk.reserved; > __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); > __entry->icount = be64_to_cpu(dqp->q_core.d_icount); > - __entry->blk_hardlimit = > - be64_to_cpu(dqp->q_core.d_blk_hardlimit); > - __entry->blk_softlimit = > - be64_to_cpu(dqp->q_core.d_blk_softlimit); > - __entry->ino_hardlimit = > - be64_to_cpu(dqp->q_core.d_ino_hardlimit); > - __entry->ino_softlimit = > - be64_to_cpu(dqp->q_core.d_ino_softlimit); > + __entry->blk_hardlimit = dqp->q_blk.hardlimit; > + __entry->blk_softlimit = dqp->q_blk.softlimit; > + __entry->ino_hardlimit = dqp->q_ino.hardlimit; > + __entry->ino_softlimit = dqp->q_ino.softlimit; > ), > TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx " > "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx " > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 469bf7946d3d..7a3d64eb9fbf 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -593,10 +593,10 @@ xfs_trans_dqresv( > defq = xfs_get_defquota(q, xfs_dquot_type(dqp)); > > if (flags & XFS_TRANS_DQ_RES_BLKS) { > - hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit); > + hardlimit = dqp->q_blk.hardlimit; > if (!hardlimit) > hardlimit = defq->bhardlimit; > - softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit); > + softlimit = dqp->q_blk.softlimit; > if (!softlimit) > softlimit = defq->bsoftlimit; > timer = be32_to_cpu(dqp->q_core.d_btimer); > @@ -605,10 +605,10 @@ xfs_trans_dqresv( > resbcountp = &dqp->q_blk.reserved; > } else { > ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); > - hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit); > + hardlimit = dqp->q_rtb.hardlimit; > if (!hardlimit) > hardlimit = defq->rtbhardlimit; > - softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit); > + softlimit = dqp->q_rtb.softlimit; > if (!softlimit) > softlimit = defq->rtbsoftlimit; > timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > @@ -649,10 +649,10 @@ xfs_trans_dqresv( > timer = be32_to_cpu(dqp->q_core.d_itimer); > warns = be16_to_cpu(dqp->q_core.d_iwarns); > warnlimit = defq->iwarnlimit; > - hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); > + hardlimit = dqp->q_ino.hardlimit; > if (!hardlimit) > hardlimit = defq->ihardlimit; > - softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); > + softlimit = dqp->q_ino.softlimit; > if (!softlimit) > softlimit = defq->isoftlimit; > >
On Tue, Jun 30, 2020 at 08:42:09AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> While loading dquot records off disk, make sure that the quota type
> flags are the same between the incore dquot and the ondisk dquot.
>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
> fs/xfs/xfs_dquot.c | 23 ++++++++++++++++++++---
> 1 file changed, 20 insertions(+), 3 deletions(-)
>
>
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index d5b7f03e93c8..46c8ca83c04d 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -524,13 +524,27 @@ xfs_dquot_alloc(
> }
>
> /* Copy the in-core quota fields in from the on-disk buffer. */
> -STATIC void
> +STATIC int
> xfs_dquot_from_disk(
> struct xfs_dquot *dqp,
> struct xfs_buf *bp)
> {
> struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset;
>
> + /*
> + * The only field the verifier didn't check was the quota type flag, so
> + * do that here.
> + */
> + if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
> + (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
> + dqp->q_core.d_id != ddqp->d_id) {
> + xfs_alert(bp->b_mount,
> + "Metadata corruption detected at %pS, quota %u",
> + __this_address, be32_to_cpu(dqp->q_core.d_id));
Probably should indicate which quota type is invalid, too. Also,
looking at xfs_buf_corruption_error(), it also uses
xfs_alert_tag(mp, XFS_PTAG_VERIFIER_ERROR, ....
Should that be used here, too?
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
On Wed, Jul 01, 2020 at 09:33:58AM +0100, Christoph Hellwig wrote:
> On Tue, Jun 30, 2020 at 08:41:56AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> >
> > In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we
> > can't lock the dquot buf to flush the dquot. This prevents the AIL from
> > blocking on the dquot, but it also forgets to clear the FREEING flag on
> > its way out. A subsequent purge attempt will see the FREEING flag is
> > set and bail out, which leads to dqpurge_all failing to purge all the
> > dquots. This causes unmounts and quotaoff operations to hang.
> >
> > Fixes: 8d3d7e2b35ea ("xfs: trylock underlying buffer on dquot flush")
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
>
> Looks like Dave submitted this as a separate fix just after you..
Ah, I didn't look at this patchset yesterday so didn't notice that
Darrick had already posted it. I'm happy for this version to be
merged...
Reviewed-by: Dave Chinner <dchinner@redhat.com>
--
Dave Chinner
david@fromorbit.com
On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Use the incore dq_flags to figure out the dquot type. This is the first > step towards removing xfs_disk_dquot from the incore dquot. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/libxfs/xfs_quota_defs.h | 2 ++ > fs/xfs/scrub/quota.c | 4 ---- > fs/xfs/xfs_dquot.c | 33 +++++++++++++++++++++++++++++++-- > fs/xfs/xfs_dquot.h | 2 ++ > fs/xfs/xfs_dquot_item.c | 6 ++++-- > fs/xfs/xfs_qm.c | 4 ++-- > fs/xfs/xfs_qm.h | 2 +- > fs/xfs/xfs_qm_syscalls.c | 9 +++------ > 8 files changed, 45 insertions(+), 17 deletions(-) > > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h > index 56d9dd787e7b..459023b0a304 100644 > --- a/fs/xfs/libxfs/xfs_quota_defs.h > +++ b/fs/xfs/libxfs/xfs_quota_defs.h > @@ -29,6 +29,8 @@ typedef uint16_t xfs_qwarncnt_t; > > #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) > > +#define XFS_DQ_ONDISK (XFS_DQ_ALLTYPES) That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK? > + > #define XFS_DQ_FLAGS \ > { XFS_DQ_USER, "USER" }, \ > { XFS_DQ_PROJ, "PROJ" }, \ > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index 905a34558361..710659d3fa28 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -108,10 +108,6 @@ xchk_quota_item( > > sqi->last_id = id; > > - /* Did we get the dquot type we wanted? */ > - if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES)) > - xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > - > if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 46c8ca83c04d..59d1bce34a98 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -561,6 +561,16 @@ xfs_dquot_from_disk( > return 0; > } > > +/* Copy the in-core quota fields into the on-disk buffer. */ > +void > +xfs_dquot_to_disk( > + struct xfs_disk_dquot *ddqp, > + struct xfs_dquot *dqp) > +{ > + memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); > + ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK; > +} > + > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > static int > xfs_qm_dqread_alloc( > @@ -1108,6 +1118,17 @@ xfs_qm_dqflush_done( > xfs_dqfunlock(dqp); > } > > +/* Check incore dquot for errors before we flush. */ > +static xfs_failaddr_t > +xfs_qm_dqflush_check( > + struct xfs_dquot *dqp) > +{ > + if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) > + return __this_address; This only checks the low 8 bits in dq_flags, which is a 32 bit field. If we ever renumber the dq flags and the dquot types end up outside the LSB, this code will break. I don't really see a need to micro-optimise the code so much it leaves landmines like this in the code... Cheers, Dave. -- Dave Chinner david@fromorbit.com
On Tue, Jun 30, 2020 at 08:42:36AM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > 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: Darrick J. Wong <darrick.wong@oracle.com> .... > @@ -124,82 +123,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 You can get rid of the ifdef DEBUG here - if ASSERT is not defined then the compiler will elide all this code anyway. > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > @@ -1123,9 +1119,29 @@ static xfs_failaddr_t > xfs_qm_dqflush_check( > struct xfs_dquot *dqp) > { > + struct xfs_disk_dquot *ddq = &dqp->q_core; > + > if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) > 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; These are new in this patch. These are checked by xfs_dquot_verify(), so what's the reason for duplicating the checks here? Cheers, Dave. -- Dave Chinner david@fromorbit.com
On Tue, Jun 30, 2020 at 08:43:01AM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Now that we've stopped using qcore entirely, drop it from the incore > dquot. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> .... > @@ -1180,7 +1184,6 @@ xfs_qm_dqflush( > struct xfs_log_item *lip = &dqp->q_logitem.qli_item; > struct xfs_buf *bp; > struct xfs_dqblk *dqb; > - struct xfs_disk_dquot *ddqp; > xfs_failaddr_t fa; > int error; > > @@ -1204,22 +1207,6 @@ xfs_qm_dqflush( > if (error) > goto out_abort; > > - /* > - * Calculate the location of the dquot inside the buffer. > - */ > - dqb = bp->b_addr + dqp->q_bufoffset; > - ddqp = &dqb->dd_diskdq; > - > - /* sanity check the in-core structure before we flush */ > - fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0); > - if (fa) { > - xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > - dqp->q_id, fa); > - xfs_buf_relse(bp); > - error = -EFSCORRUPTED; > - goto out_abort; > - } > - > fa = xfs_qm_dqflush_check(dqp); > if (fa) { > xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > @@ -1229,7 +1216,9 @@ xfs_qm_dqflush( > goto out_abort; > } > > - xfs_dquot_to_disk(ddqp, dqp); > + /* Flush the incore dquot to the ondisk buffer. */ > + dqb = bp->b_addr + dqp->q_bufoffset; > + xfs_dquot_to_disk(&dqb->dd_diskdq, dqp); Oh, this is really hard to read now. d, q, b, and p are all the same shape just at different rotations/mirroring, so this now just looks like a jumble of random letter salad... Can you rename dqb to dqblk so it's clearly the pointer to the on-disk dquot block and so easy to differentiate at a glance from the in-memory dquot pointer? Cheers, Dave. -- Dave Chinner david@fromorbit.com
On Thu, Jul 02, 2020 at 09:01:36AM +1000, Dave Chinner wrote: > On Tue, Jun 30, 2020 at 08:42:36AM -0700, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > 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: Darrick J. Wong <darrick.wong@oracle.com> > .... > > @@ -124,82 +123,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 > > You can get rid of the ifdef DEBUG here - if ASSERT is not defined > then the compiler will elide all this code anyway. OK. > > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > > @@ -1123,9 +1119,29 @@ static xfs_failaddr_t > > xfs_qm_dqflush_check( > > struct xfs_dquot *dqp) > > { > > + struct xfs_disk_dquot *ddq = &dqp->q_core; > > + > > if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) > > 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; > > These are new in this patch. These are checked by > xfs_dquot_verify(), so what's the reason for duplicating the checks > here? The new functions perform spot-checks of the incore dquot before we start flushing them out to disk, because the goal of this patch is to further decouple the incore and ondisk dquots ahead of the y2038 support series. --D > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com
On Thu, Jul 02, 2020 at 09:07:54AM +1000, Dave Chinner wrote: > On Tue, Jun 30, 2020 at 08:43:01AM -0700, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > Now that we've stopped using qcore entirely, drop it from the incore > > dquot. > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > .... > > @@ -1180,7 +1184,6 @@ xfs_qm_dqflush( > > struct xfs_log_item *lip = &dqp->q_logitem.qli_item; > > struct xfs_buf *bp; > > struct xfs_dqblk *dqb; > > - struct xfs_disk_dquot *ddqp; > > xfs_failaddr_t fa; > > int error; > > > > @@ -1204,22 +1207,6 @@ xfs_qm_dqflush( > > if (error) > > goto out_abort; > > > > - /* > > - * Calculate the location of the dquot inside the buffer. > > - */ > > - dqb = bp->b_addr + dqp->q_bufoffset; > > - ddqp = &dqb->dd_diskdq; > > - > > - /* sanity check the in-core structure before we flush */ > > - fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0); > > - if (fa) { > > - xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > > - dqp->q_id, fa); > > - xfs_buf_relse(bp); > > - error = -EFSCORRUPTED; > > - goto out_abort; > > - } > > - > > fa = xfs_qm_dqflush_check(dqp); > > if (fa) { > > xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > > @@ -1229,7 +1216,9 @@ xfs_qm_dqflush( > > goto out_abort; > > } > > > > - xfs_dquot_to_disk(ddqp, dqp); > > + /* Flush the incore dquot to the ondisk buffer. */ > > + dqb = bp->b_addr + dqp->q_bufoffset; > > + xfs_dquot_to_disk(&dqb->dd_diskdq, dqp); > > Oh, this is really hard to read now. d, q, b, and p are all the same > shape just at different rotations/mirroring, so this now just looks > like a jumble of random letter salad... > > Can you rename dqb to dqblk so it's clearly the pointer to the > on-disk dquot block and so easy to differentiate at a glance from > the in-memory dquot pointer? Ok. --D > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com
On Thu, Jul 02, 2020 at 08:41:12AM +1000, Dave Chinner wrote: > On Tue, Jun 30, 2020 at 08:42:09AM -0700, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > While loading dquot records off disk, make sure that the quota type > > flags are the same between the incore dquot and the ondisk dquot. > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > > --- > > fs/xfs/xfs_dquot.c | 23 ++++++++++++++++++++--- > > 1 file changed, 20 insertions(+), 3 deletions(-) > > > > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > > index d5b7f03e93c8..46c8ca83c04d 100644 > > --- a/fs/xfs/xfs_dquot.c > > +++ b/fs/xfs/xfs_dquot.c > > @@ -524,13 +524,27 @@ xfs_dquot_alloc( > > } > > > > /* Copy the in-core quota fields in from the on-disk buffer. */ > > -STATIC void > > +STATIC int > > xfs_dquot_from_disk( > > struct xfs_dquot *dqp, > > struct xfs_buf *bp) > > { > > struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset; > > > > + /* > > + * The only field the verifier didn't check was the quota type flag, so > > + * do that here. > > + */ > > + if ((dqp->dq_flags & XFS_DQ_ALLTYPES) != > > + (ddqp->d_flags & XFS_DQ_ALLTYPES) || > > + dqp->q_core.d_id != ddqp->d_id) { > > + xfs_alert(bp->b_mount, > > + "Metadata corruption detected at %pS, quota %u", > > + __this_address, be32_to_cpu(dqp->q_core.d_id)); > > Probably should indicate which quota type is invalid, too. Also, > looking at xfs_buf_corruption_error(), it also uses > > xfs_alert_tag(mp, XFS_PTAG_VERIFIER_ERROR, .... > > Should that be used here, too? Yeah. Will fix. --D > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com
On Thu, Jul 02, 2020 at 08:50:53AM +1000, Dave Chinner wrote: > On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > Use the incore dq_flags to figure out the dquot type. This is the first > > step towards removing xfs_disk_dquot from the incore dquot. > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > > --- > > fs/xfs/libxfs/xfs_quota_defs.h | 2 ++ > > fs/xfs/scrub/quota.c | 4 ---- > > fs/xfs/xfs_dquot.c | 33 +++++++++++++++++++++++++++++++-- > > fs/xfs/xfs_dquot.h | 2 ++ > > fs/xfs/xfs_dquot_item.c | 6 ++++-- > > fs/xfs/xfs_qm.c | 4 ++-- > > fs/xfs/xfs_qm.h | 2 +- > > fs/xfs/xfs_qm_syscalls.c | 9 +++------ > > 8 files changed, 45 insertions(+), 17 deletions(-) > > > > > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h > > index 56d9dd787e7b..459023b0a304 100644 > > --- a/fs/xfs/libxfs/xfs_quota_defs.h > > +++ b/fs/xfs/libxfs/xfs_quota_defs.h > > @@ -29,6 +29,8 @@ typedef uint16_t xfs_qwarncnt_t; > > > > #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) > > > > +#define XFS_DQ_ONDISK (XFS_DQ_ALLTYPES) > > That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK? Well, based on Christoph's suggestions I broke the incore dquot flags (XFS_DQ_*) apart from the ondisk dquot flags (XFS_DQFLAG_*). Not sure if that's really better, but at least the namespaces are separate now. > > + > > #define XFS_DQ_FLAGS \ > > { XFS_DQ_USER, "USER" }, \ > > { XFS_DQ_PROJ, "PROJ" }, \ > > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > > index 905a34558361..710659d3fa28 100644 > > --- a/fs/xfs/scrub/quota.c > > +++ b/fs/xfs/scrub/quota.c > > @@ -108,10 +108,6 @@ xchk_quota_item( > > > > sqi->last_id = id; > > > > - /* Did we get the dquot type we wanted? */ > > - if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES)) > > - xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > > - > > if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) > > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > > index 46c8ca83c04d..59d1bce34a98 100644 > > --- a/fs/xfs/xfs_dquot.c > > +++ b/fs/xfs/xfs_dquot.c > > @@ -561,6 +561,16 @@ xfs_dquot_from_disk( > > return 0; > > } > > > > +/* Copy the in-core quota fields into the on-disk buffer. */ > > +void > > +xfs_dquot_to_disk( > > + struct xfs_disk_dquot *ddqp, > > + struct xfs_dquot *dqp) > > +{ > > + memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); > > + ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK; > > +} > > + > > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > > static int > > xfs_qm_dqread_alloc( > > @@ -1108,6 +1118,17 @@ xfs_qm_dqflush_done( > > xfs_dqfunlock(dqp); > > } > > > > +/* Check incore dquot for errors before we flush. */ > > +static xfs_failaddr_t > > +xfs_qm_dqflush_check( > > + struct xfs_dquot *dqp) > > +{ > > + if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) > > + return __this_address; > > This only checks the low 8 bits in dq_flags, which is a 32 bit > field. If we ever renumber the dq flags and the dquot types end up > outside the LSB, this code will break. > > I don't really see a need to micro-optimise the code so much it > leaves landmines like this in the code... Ok. Fixed. --D > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com
On 6/30/20 8:42 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Add counter fields to 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: Darrick J. Wong <darrick.wong@oracle.com> Ok, looks good Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/scrub/quota.c | 18 ++++++------------ > fs/xfs/xfs_dquot.c | 47 +++++++++++++++++++++++++--------------------- > fs/xfs/xfs_dquot.h | 3 +++ > fs/xfs/xfs_qm.c | 6 +++--- > fs/xfs/xfs_qm.h | 6 +++--- > fs/xfs/xfs_trace.h | 4 ++-- > fs/xfs/xfs_trans_dquot.c | 36 ++++++++++++++--------------------- > 7 files changed, 57 insertions(+), 63 deletions(-) > > > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index 1a1c6996fc69..2fc2625feca0 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -82,9 +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 bcount; > - unsigned long long icount; > - unsigned long long rcount; > xfs_ino_t fs_icount; > int error = 0; > > @@ -128,9 +125,6 @@ xchk_quota_item( > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > > /* Check the resource counts. */ > - bcount = be64_to_cpu(d->d_bcount); > - icount = be64_to_cpu(d->d_icount); > - rcount = be64_to_cpu(d->d_rtbcount); > fs_icount = percpu_counter_sum(&mp->m_icount); > > /* > @@ -139,15 +133,15 @@ xchk_quota_item( > * if there are no quota limits. > */ > if (xfs_sb_version_hasreflink(&mp->m_sb)) { > - if (mp->m_sb.sb_dblocks < bcount) > + if (mp->m_sb.sb_dblocks < dq->q_blk.count) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, > offset); > } else { > - if (mp->m_sb.sb_dblocks < bcount) > + if (mp->m_sb.sb_dblocks < dq->q_blk.count) > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, > offset); > } > - if (icount > fs_icount || rcount > mp->m_sb.sb_rblocks) > + if (dq->q_ino.count > fs_icount || dq->q_rtb.count > mp->m_sb.sb_rblocks) > xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > > /* > @@ -159,15 +153,15 @@ xchk_quota_item( > goto out; > > if (dq->q_blk.hardlimit != 0 && > - bcount > dq->q_blk.hardlimit) > + dq->q_blk.count > dq->q_blk.hardlimit) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > > if (dq->q_ino.hardlimit != 0 && > - icount > dq->q_ino.hardlimit) > + dq->q_ino.count > dq->q_ino.hardlimit) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > > if (dq->q_rtb.hardlimit != 0 && > - rcount > dq->q_rtb.hardlimit) > + dq->q_rtb.count > dq->q_rtb.hardlimit) > xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); > > out: > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 63f744bcbc90..02eae8c2ba1b 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -133,9 +133,9 @@ xfs_qm_adjust_dqtimers( > > if (!d->d_btimer) { > if ((dq->q_blk.softlimit && > - (be64_to_cpu(d->d_bcount) > dq->q_blk.softlimit)) || > + (dq->q_blk.count > dq->q_blk.softlimit)) || > (dq->q_blk.hardlimit && > - (be64_to_cpu(d->d_bcount) > dq->q_blk.hardlimit))) { > + (dq->q_blk.count > dq->q_blk.hardlimit))) { > d->d_btimer = cpu_to_be32(ktime_get_real_seconds() + > defq->btimelimit); > } else { > @@ -143,18 +143,18 @@ xfs_qm_adjust_dqtimers( > } > } else { > if ((!dq->q_blk.softlimit || > - (be64_to_cpu(d->d_bcount) <= dq->q_blk.softlimit)) && > + (dq->q_blk.count <= dq->q_blk.softlimit)) && > (!dq->q_blk.hardlimit || > - (be64_to_cpu(d->d_bcount) <= dq->q_blk.hardlimit))) { > + (dq->q_blk.count <= dq->q_blk.hardlimit))) { > d->d_btimer = 0; > } > } > > if (!d->d_itimer) { > if ((dq->q_ino.softlimit && > - (be64_to_cpu(d->d_icount) > dq->q_ino.softlimit)) || > + (dq->q_ino.count > dq->q_ino.softlimit)) || > (dq->q_ino.hardlimit && > - (be64_to_cpu(d->d_icount) > dq->q_ino.hardlimit))) { > + (dq->q_ino.count > dq->q_ino.hardlimit))) { > d->d_itimer = cpu_to_be32(ktime_get_real_seconds() + > defq->itimelimit); > } else { > @@ -162,18 +162,18 @@ xfs_qm_adjust_dqtimers( > } > } else { > if ((!dq->q_ino.softlimit || > - (be64_to_cpu(d->d_icount) <= dq->q_ino.softlimit)) && > + (dq->q_ino.count <= dq->q_ino.softlimit)) && > (!dq->q_ino.hardlimit || > - (be64_to_cpu(d->d_icount) <= dq->q_ino.hardlimit))) { > + (dq->q_ino.count <= dq->q_ino.hardlimit))) { > d->d_itimer = 0; > } > } > > if (!d->d_rtbtimer) { > if ((dq->q_rtb.softlimit && > - (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.softlimit)) || > + (dq->q_rtb.count > dq->q_rtb.softlimit)) || > (dq->q_rtb.hardlimit && > - (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.hardlimit))) { > + (dq->q_rtb.count > dq->q_rtb.hardlimit))) { > d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() + > defq->rtbtimelimit); > } else { > @@ -181,9 +181,9 @@ xfs_qm_adjust_dqtimers( > } > } else { > if ((!dq->q_rtb.softlimit || > - (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.softlimit)) && > + (dq->q_rtb.count <= dq->q_rtb.softlimit)) && > (!dq->q_rtb.hardlimit || > - (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.hardlimit))) { > + (dq->q_rtb.count <= dq->q_rtb.hardlimit))) { > d->d_rtbtimer = 0; > } > } > @@ -538,13 +538,17 @@ xfs_dquot_from_disk( > dqp->q_rtb.hardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit); > dqp->q_rtb.softlimit = be64_to_cpu(ddqp->d_rtb_softlimit); > > + dqp->q_blk.count = be64_to_cpu(ddqp->d_bcount); > + dqp->q_ino.count = be64_to_cpu(ddqp->d_icount); > + dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount); > + > /* > * Reservation counters are defined as reservation plus current usage > * to avoid having to add every time. > */ > - dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount); > - dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount); > - dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount); > + dqp->q_blk.reserved = dqp->q_blk.count; > + dqp->q_ino.reserved = dqp->q_ino.count; > + dqp->q_rtb.reserved = dqp->q_rtb.count; > > /* initialize the dquot speculative prealloc thresholds */ > xfs_dquot_set_prealloc_limits(dqp); > @@ -565,6 +569,10 @@ xfs_dquot_to_disk( > 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); > + > + ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count); > + ddqp->d_icount = cpu_to_be64(dqp->q_ino.count); > + ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count); > } > > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > @@ -1127,18 +1135,15 @@ xfs_qm_dqflush_check( > if (dqp->q_id == 0) > return NULL; > > - if (dqp->q_blk.softlimit && > - be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit && > + if (dqp->q_blk.softlimit && dqp->q_blk.count > 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 && > + if (dqp->q_ino.softlimit && dqp->q_ino.count > 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 && > + if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit && > !ddq->d_rtbtimer) > return __this_address; > > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index edb49788c476..23e05b0d7567 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -31,6 +31,9 @@ struct xfs_dquot_res { > /* Total resources allocated and reserved. */ > xfs_qcnt_t reserved; > > + /* Total resources allocated. */ > + xfs_qcnt_t count; > + > /* Absolute and preferred limits. */ > xfs_qcnt_t hardlimit; > xfs_qcnt_t softlimit; > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 54fc3aac1a68..b47bba204240 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -1093,14 +1093,14 @@ xfs_qm_quotacheck_dqadjust( > * Adjust the inode count and the block count to reflect this inode's > * resource usage. > */ > - be64_add_cpu(&dqp->q_core.d_icount, 1); > + dqp->q_ino.count++; > dqp->q_ino.reserved++; > if (nblks) { > - be64_add_cpu(&dqp->q_core.d_bcount, nblks); > + dqp->q_blk.count += nblks; > dqp->q_blk.reserved += nblks; > } > if (rtblks) { > - be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks); > + dqp->q_rtb.count += rtblks; > dqp->q_rtb.reserved += rtblks; > } > > diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h > index 84cb8af468b7..6ed4ae942603 100644 > --- a/fs/xfs/xfs_qm.h > +++ b/fs/xfs/xfs_qm.h > @@ -26,9 +26,9 @@ extern struct kmem_zone *xfs_qm_dqtrxzone; > !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) > + !dqp->q_blk.count && \ > + !dqp->q_rtb.count && \ > + !dqp->q_ino.count) > > /* > * This defines the unit of allocation of dquots. > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 7f744a37dc0e..851f97dfe9e3 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -880,8 +880,8 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, > __entry->flags = dqp->dq_flags; > __entry->nrefs = dqp->q_nrefs; > __entry->res_bcount = dqp->q_blk.reserved; > - __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); > - __entry->icount = be64_to_cpu(dqp->q_core.d_icount); > + __entry->bcount = dqp->q_blk.count; > + __entry->icount = dqp->q_ino.count; > __entry->blk_hardlimit = dqp->q_blk.hardlimit; > __entry->blk_softlimit = dqp->q_blk.softlimit; > __entry->ino_hardlimit = dqp->q_ino.hardlimit; > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 7a3d64eb9fbf..b36d747989a7 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -309,7 +309,6 @@ xfs_trans_apply_dquot_deltas( > int i, j; > struct xfs_dquot *dqp; > struct xfs_dqtrx *qtrx, *qa; > - struct xfs_disk_dquot *d; > int64_t totalbdelta; > int64_t totalrtbdelta; > > @@ -341,7 +340,6 @@ xfs_trans_apply_dquot_deltas( > /* > * adjust the actual number of blocks used > */ > - d = &dqp->q_core; > > /* > * The issue here is - sometimes we don't make a blkquota > @@ -362,25 +360,22 @@ xfs_trans_apply_dquot_deltas( > qtrx->qt_delrtb_delta; > #ifdef DEBUG > if (totalbdelta < 0) > - ASSERT(be64_to_cpu(d->d_bcount) >= > - -totalbdelta); > + ASSERT(dqp->q_blk.count >= -totalbdelta); > > if (totalrtbdelta < 0) > - ASSERT(be64_to_cpu(d->d_rtbcount) >= > - -totalrtbdelta); > + ASSERT(dqp->q_rtb.count >= -totalrtbdelta); > > if (qtrx->qt_icount_delta < 0) > - ASSERT(be64_to_cpu(d->d_icount) >= > - -qtrx->qt_icount_delta); > + ASSERT(dqp->q_ino.count >= -qtrx->qt_icount_delta); > #endif > if (totalbdelta) > - be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta); > + dqp->q_blk.count += totalbdelta; > > if (qtrx->qt_icount_delta) > - be64_add_cpu(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta); > + dqp->q_ino.count += qtrx->qt_icount_delta; > > if (totalrtbdelta) > - be64_add_cpu(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta); > + dqp->q_rtb.count += totalrtbdelta; > > /* > * Get any default limits in use. > @@ -467,12 +462,9 @@ xfs_trans_apply_dquot_deltas( > (xfs_qcnt_t)qtrx->qt_icount_delta; > } > > - ASSERT(dqp->q_blk.reserved >= > - be64_to_cpu(dqp->q_core.d_bcount)); > - ASSERT(dqp->q_ino.reserved >= > - be64_to_cpu(dqp->q_core.d_icount)); > - ASSERT(dqp->q_rtb.reserved >= > - be64_to_cpu(dqp->q_core.d_rtbcount)); > + ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count); > + ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count); > + ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count); > } > } > } > @@ -645,7 +637,7 @@ xfs_trans_dqresv( > } > } > if (ninos > 0) { > - total_count = dqp->q_res_icount + ninos; > + total_count = dqp->q_ino.reserved + ninos; > timer = be32_to_cpu(dqp->q_core.d_itimer); > warns = be16_to_cpu(dqp->q_core.d_iwarns); > warnlimit = defq->iwarnlimit; > @@ -675,7 +667,7 @@ xfs_trans_dqresv( > > /* > * Change the reservation, but not the actual usage. > - * Note that q_blk.reserved = q_core.d_bcount + resv > + * Note that q_blk.reserved = q_blk.count + resv > */ > (*resbcountp) += (xfs_qcnt_t)nblks; > if (ninos != 0) > @@ -700,9 +692,9 @@ xfs_trans_dqresv( > XFS_TRANS_DQ_RES_INOS, > ninos); > } > - ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount)); > - ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount)); > - ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount)); > + ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count); > + ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count); > + ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count); > > xfs_dqunlock(dqp); > return 0; >
On 6/30/20 8:42 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Add warning counter fields to 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: Darrick J. Wong <darrick.wong@oracle.com> Looks ok Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_dquot.c | 14 +++++++++++--- > fs/xfs/xfs_dquot.h | 8 ++++++++ > fs/xfs/xfs_qm.c | 12 ++++++------ > fs/xfs/xfs_qm_syscalls.c | 12 ++++++------ > fs/xfs/xfs_trans_dquot.c | 6 +++--- > 5 files changed, 34 insertions(+), 18 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 02eae8c2ba1b..a1edb49ceda5 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -139,7 +139,7 @@ xfs_qm_adjust_dqtimers( > d->d_btimer = cpu_to_be32(ktime_get_real_seconds() + > defq->btimelimit); > } else { > - d->d_bwarns = 0; > + dq->q_blk.warnings = 0; > } > } else { > if ((!dq->q_blk.softlimit || > @@ -158,7 +158,7 @@ xfs_qm_adjust_dqtimers( > d->d_itimer = cpu_to_be32(ktime_get_real_seconds() + > defq->itimelimit); > } else { > - d->d_iwarns = 0; > + dq->q_ino.warnings = 0; > } > } else { > if ((!dq->q_ino.softlimit || > @@ -177,7 +177,7 @@ xfs_qm_adjust_dqtimers( > d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() + > defq->rtbtimelimit); > } else { > - d->d_rtbwarns = 0; > + dq->q_rtb.warnings = 0; > } > } else { > if ((!dq->q_rtb.softlimit || > @@ -542,6 +542,10 @@ xfs_dquot_from_disk( > dqp->q_ino.count = be64_to_cpu(ddqp->d_icount); > dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount); > > + dqp->q_blk.warnings = be16_to_cpu(ddqp->d_bwarns); > + dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns); > + dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns); > + > /* > * Reservation counters are defined as reservation plus current usage > * to avoid having to add every time. > @@ -573,6 +577,10 @@ xfs_dquot_to_disk( > ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count); > ddqp->d_icount = cpu_to_be64(dqp->q_ino.count); > ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count); > + > + ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings); > + ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings); > + ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings); > } > > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 23e05b0d7567..5840bc54b772 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -37,6 +37,14 @@ struct xfs_dquot_res { > /* Absolute and preferred limits. */ > xfs_qcnt_t hardlimit; > xfs_qcnt_t softlimit; > + > + /* > + * For root dquots, this is the maximum number of warnings that will > + * be issued for this quota type. Otherwise, this is the number of > + * warnings issued against this quota. Note that none of this is > + * implemented. > + */ > + xfs_qwarncnt_t warnings; > }; > > /* > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index b47bba204240..4e233cfef46d 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -616,12 +616,12 @@ xfs_qm_init_timelimits( > defq->itimelimit = be32_to_cpu(ddqp->d_itimer); > if (ddqp->d_rtbtimer) > defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer); > - if (ddqp->d_bwarns) > - defq->bwarnlimit = be16_to_cpu(ddqp->d_bwarns); > - if (ddqp->d_iwarns) > - defq->iwarnlimit = be16_to_cpu(ddqp->d_iwarns); > - if (ddqp->d_rtbwarns) > - defq->rtbwarnlimit = be16_to_cpu(ddqp->d_rtbwarns); > + if (dqp->q_blk.warnings) > + defq->bwarnlimit = dqp->q_blk.warnings; > + if (dqp->q_ino.warnings) > + defq->iwarnlimit = dqp->q_ino.warnings; > + if (dqp->q_rtb.warnings) > + defq->rtbwarnlimit = dqp->q_rtb.warnings; > > xfs_qm_dqdestroy(dqp); > } > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index ab596d389e3e..5d3bccdbd3bf 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -548,11 +548,11 @@ xfs_qm_scall_setqlim( > * Update warnings counter(s) if requested > */ > if (newlim->d_fieldmask & QC_SPC_WARNS) > - ddq->d_bwarns = cpu_to_be16(newlim->d_spc_warns); > + dqp->q_blk.warnings = newlim->d_spc_warns; > if (newlim->d_fieldmask & QC_INO_WARNS) > - ddq->d_iwarns = cpu_to_be16(newlim->d_ino_warns); > + dqp->q_ino.warnings = newlim->d_ino_warns; > if (newlim->d_fieldmask & QC_RT_SPC_WARNS) > - ddq->d_rtbwarns = cpu_to_be16(newlim->d_rt_spc_warns); > + dqp->q_rtb.warnings = newlim->d_rt_spc_warns; > > if (id == 0) { > if (newlim->d_fieldmask & QC_SPC_WARNS) > @@ -627,13 +627,13 @@ xfs_qm_scall_getquota_fill_qc( > dst->d_ino_count = dqp->q_ino.reserved; > dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); > dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); > - dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); > - dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns); > + dst->d_ino_warns = dqp->q_ino.warnings; > + dst->d_spc_warns = dqp->q_blk.warnings; > dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); > dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); > dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); > dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > - dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); > + dst->d_rt_spc_warns = dqp->q_rtb.warnings; > > /* > * Internally, we don't reset all the timers when quota enforcement > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index b36d747989a7..21ed8eda3c80 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -592,7 +592,7 @@ xfs_trans_dqresv( > if (!softlimit) > softlimit = defq->bsoftlimit; > timer = be32_to_cpu(dqp->q_core.d_btimer); > - warns = be16_to_cpu(dqp->q_core.d_bwarns); > + warns = dqp->q_blk.warnings; > warnlimit = defq->bwarnlimit; > resbcountp = &dqp->q_blk.reserved; > } else { > @@ -604,7 +604,7 @@ xfs_trans_dqresv( > if (!softlimit) > softlimit = defq->rtbsoftlimit; > timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > - warns = be16_to_cpu(dqp->q_core.d_rtbwarns); > + warns = dqp->q_rtb.warnings; > warnlimit = defq->rtbwarnlimit; > resbcountp = &dqp->q_rtb.reserved; > } > @@ -639,7 +639,7 @@ xfs_trans_dqresv( > if (ninos > 0) { > total_count = dqp->q_ino.reserved + ninos; > timer = be32_to_cpu(dqp->q_core.d_itimer); > - warns = be16_to_cpu(dqp->q_core.d_iwarns); > + warns = dqp->q_ino.warnings; > warnlimit = defq->iwarnlimit; > hardlimit = dqp->q_ino.hardlimit; > if (!hardlimit) >
On 6/30/20 8:42 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Add timers fields to 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: Darrick J. Wong <darrick.wong@oracle.com> Looks good Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_dquot.c | 41 +++++++++++++++++++++++------------------ > fs/xfs/xfs_dquot.h | 7 +++++++ > fs/xfs/xfs_qm.c | 15 ++++++--------- > fs/xfs/xfs_qm_syscalls.c | 18 ++++++++---------- > fs/xfs/xfs_trans_dquot.c | 6 +++--- > 5 files changed, 47 insertions(+), 40 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index a1edb49ceda5..7434ee57ec43 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -116,7 +116,6 @@ xfs_qm_adjust_dqtimers( > struct xfs_dquot *dq) > { > struct xfs_quotainfo *qi = mp->m_quotainfo; > - struct xfs_disk_dquot *d = &dq->q_core; > struct xfs_def_quota *defq; > > ASSERT(dq->q_id); > @@ -131,13 +130,13 @@ xfs_qm_adjust_dqtimers( > ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit); > #endif > > - if (!d->d_btimer) { > + if (!dq->q_blk.timer) { > if ((dq->q_blk.softlimit && > (dq->q_blk.count > dq->q_blk.softlimit)) || > (dq->q_blk.hardlimit && > (dq->q_blk.count > dq->q_blk.hardlimit))) { > - d->d_btimer = cpu_to_be32(ktime_get_real_seconds() + > - defq->btimelimit); > + dq->q_blk.timer = ktime_get_real_seconds() + > + defq->btimelimit; > } else { > dq->q_blk.warnings = 0; > } > @@ -146,17 +145,17 @@ xfs_qm_adjust_dqtimers( > (dq->q_blk.count <= dq->q_blk.softlimit)) && > (!dq->q_blk.hardlimit || > (dq->q_blk.count <= dq->q_blk.hardlimit))) { > - d->d_btimer = 0; > + dq->q_blk.timer = 0; > } > } > > - if (!d->d_itimer) { > + if (!dq->q_ino.timer) { > if ((dq->q_ino.softlimit && > (dq->q_ino.count > dq->q_ino.softlimit)) || > (dq->q_ino.hardlimit && > (dq->q_ino.count > dq->q_ino.hardlimit))) { > - d->d_itimer = cpu_to_be32(ktime_get_real_seconds() + > - defq->itimelimit); > + dq->q_ino.timer = ktime_get_real_seconds() + > + defq->itimelimit; > } else { > dq->q_ino.warnings = 0; > } > @@ -165,17 +164,17 @@ xfs_qm_adjust_dqtimers( > (dq->q_ino.count <= dq->q_ino.softlimit)) && > (!dq->q_ino.hardlimit || > (dq->q_ino.count <= dq->q_ino.hardlimit))) { > - d->d_itimer = 0; > + dq->q_ino.timer = 0; > } > } > > - if (!d->d_rtbtimer) { > + if (!dq->q_rtb.timer) { > if ((dq->q_rtb.softlimit && > (dq->q_rtb.count > dq->q_rtb.softlimit)) || > (dq->q_rtb.hardlimit && > (dq->q_rtb.count > dq->q_rtb.hardlimit))) { > - d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() + > - defq->rtbtimelimit); > + dq->q_rtb.timer = ktime_get_real_seconds() + > + defq->rtbtimelimit; > } else { > dq->q_rtb.warnings = 0; > } > @@ -184,7 +183,7 @@ xfs_qm_adjust_dqtimers( > (dq->q_rtb.count <= dq->q_rtb.softlimit)) && > (!dq->q_rtb.hardlimit || > (dq->q_rtb.count <= dq->q_rtb.hardlimit))) { > - d->d_rtbtimer = 0; > + dq->q_rtb.timer = 0; > } > } > } > @@ -546,6 +545,10 @@ xfs_dquot_from_disk( > dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns); > dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns); > > + dqp->q_blk.timer = be32_to_cpu(ddqp->d_btimer); > + dqp->q_ino.timer = be32_to_cpu(ddqp->d_itimer); > + dqp->q_rtb.timer = be32_to_cpu(ddqp->d_rtbtimer); > + > /* > * Reservation counters are defined as reservation plus current usage > * to avoid having to add every time. > @@ -581,6 +584,10 @@ xfs_dquot_to_disk( > ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings); > ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings); > ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings); > + > + ddqp->d_btimer = cpu_to_be32(dqp->q_blk.timer); > + ddqp->d_itimer = cpu_to_be32(dqp->q_ino.timer); > + ddqp->d_rtbtimer = cpu_to_be32(dqp->q_rtb.timer); > } > > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > @@ -1135,8 +1142,6 @@ static xfs_failaddr_t > xfs_qm_dqflush_check( > struct xfs_dquot *dqp) > { > - struct xfs_disk_dquot *ddq = &dqp->q_core; > - > if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) > return __this_address; > > @@ -1144,15 +1149,15 @@ xfs_qm_dqflush_check( > return NULL; > > if (dqp->q_blk.softlimit && dqp->q_blk.count > dqp->q_blk.softlimit && > - !ddq->d_btimer) > + !dqp->q_blk.timer) > return __this_address; > > if (dqp->q_ino.softlimit && dqp->q_ino.count > dqp->q_ino.softlimit && > - !ddq->d_itimer) > + !dqp->q_ino.timer) > return __this_address; > > if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit && > - !ddq->d_rtbtimer) > + !dqp->q_rtb.timer) > return __this_address; > > return NULL; > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 5840bc54b772..414bae537b1d 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -38,6 +38,13 @@ struct xfs_dquot_res { > xfs_qcnt_t hardlimit; > xfs_qcnt_t softlimit; > > + /* > + * For root dquots, this is the default grace period, in seconds. > + * Otherwise, this is when the quota grace period expires, > + * in seconds since the Unix epoch. > + */ > + time64_t timer; > + > /* > * For root dquots, this is the maximum number of warnings that will > * be issued for this quota type. Otherwise, this is the number of > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 4e233cfef46d..a56c6e4a5d99 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -579,7 +579,6 @@ xfs_qm_init_timelimits( > { > struct xfs_quotainfo *qinf = mp->m_quotainfo; > struct xfs_def_quota *defq; > - struct xfs_disk_dquot *ddqp; > struct xfs_dquot *dqp; > int error; > > @@ -603,19 +602,17 @@ xfs_qm_init_timelimits( > if (error) > return; > > - ddqp = &dqp->q_core; > - > /* > * The warnings and timers set the grace period given to > * a user or group before he or she can not perform any > * more writing. If it is zero, a default is used. > */ > - if (ddqp->d_btimer) > - defq->btimelimit = be32_to_cpu(ddqp->d_btimer); > - if (ddqp->d_itimer) > - defq->itimelimit = be32_to_cpu(ddqp->d_itimer); > - if (ddqp->d_rtbtimer) > - defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer); > + if (dqp->q_blk.timer) > + defq->btimelimit = dqp->q_blk.timer; > + if (dqp->q_ino.timer) > + defq->itimelimit = dqp->q_ino.timer; > + if (dqp->q_rtb.timer) > + defq->rtbtimelimit = dqp->q_rtb.timer; > if (dqp->q_blk.warnings) > defq->bwarnlimit = dqp->q_blk.warnings; > if (dqp->q_ino.warnings) > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 5d3bccdbd3bf..1b2b70b1660f 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -447,7 +447,6 @@ xfs_qm_scall_setqlim( > struct qc_dqblk *newlim) > { > struct xfs_quotainfo *q = mp->m_quotainfo; > - struct xfs_disk_dquot *ddq; > struct xfs_dquot *dqp; > struct xfs_trans *tp; > struct xfs_def_quota *defq; > @@ -488,7 +487,6 @@ xfs_qm_scall_setqlim( > > xfs_dqlock(dqp); > xfs_trans_dqjoin(tp, dqp); > - ddq = &dqp->q_core; > > /* > * Make sure that hardlimits are >= soft limits before changing. > @@ -573,11 +571,11 @@ xfs_qm_scall_setqlim( > * the soft limit. > */ > if (newlim->d_fieldmask & QC_SPC_TIMER) > - ddq->d_btimer = cpu_to_be32(newlim->d_spc_timer); > + dqp->q_blk.timer = newlim->d_spc_timer; > if (newlim->d_fieldmask & QC_INO_TIMER) > - ddq->d_itimer = cpu_to_be32(newlim->d_ino_timer); > + dqp->q_ino.timer = newlim->d_ino_timer; > if (newlim->d_fieldmask & QC_RT_SPC_TIMER) > - ddq->d_rtbtimer = cpu_to_be32(newlim->d_rt_spc_timer); > + dqp->q_rtb.timer = newlim->d_rt_spc_timer; > > if (id == 0) { > if (newlim->d_fieldmask & QC_SPC_TIMER) > @@ -621,18 +619,18 @@ xfs_qm_scall_getquota_fill_qc( > memset(dst, 0, sizeof(*dst)); > dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit); > dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit); > - dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); > - dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); > + dst->d_ino_hardlimit = dqp->q_ino.hardlimit; > + dst->d_ino_softlimit = dqp->q_ino.softlimit; > dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); > dst->d_ino_count = dqp->q_ino.reserved; > - dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); > - dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); > + dst->d_spc_timer = dqp->q_blk.timer; > + dst->d_ino_timer = dqp->q_ino.timer; > dst->d_ino_warns = dqp->q_ino.warnings; > dst->d_spc_warns = dqp->q_blk.warnings; > dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); > dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); > dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); > - dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > + dst->d_rt_spc_timer = dqp->q_rtb.timer; > dst->d_rt_spc_warns = dqp->q_rtb.warnings; > > /* > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 21ed8eda3c80..28b59a4069a3 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -591,7 +591,7 @@ xfs_trans_dqresv( > softlimit = dqp->q_blk.softlimit; > if (!softlimit) > softlimit = defq->bsoftlimit; > - timer = be32_to_cpu(dqp->q_core.d_btimer); > + timer = dqp->q_blk.timer; > warns = dqp->q_blk.warnings; > warnlimit = defq->bwarnlimit; > resbcountp = &dqp->q_blk.reserved; > @@ -603,7 +603,7 @@ xfs_trans_dqresv( > softlimit = dqp->q_rtb.softlimit; > if (!softlimit) > softlimit = defq->rtbsoftlimit; > - timer = be32_to_cpu(dqp->q_core.d_rtbtimer); > + timer = dqp->q_rtb.timer; > warns = dqp->q_rtb.warnings; > warnlimit = defq->rtbwarnlimit; > resbcountp = &dqp->q_rtb.reserved; > @@ -638,7 +638,7 @@ xfs_trans_dqresv( > } > if (ninos > 0) { > total_count = dqp->q_ino.reserved + ninos; > - timer = be32_to_cpu(dqp->q_core.d_itimer); > + timer = dqp->q_ino.timer; > warns = dqp->q_ino.warnings; > warnlimit = defq->iwarnlimit; > hardlimit = dqp->q_ino.hardlimit; >
On Tue, Jun 30, 2020 at 08:43:07AM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Now that we've split up the dquot resource fields into separate structs, > do the same for the default limits to enable further refactoring. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_dquot.c | 30 +++++++++++++++--------------- > fs/xfs/xfs_qm.c | 36 ++++++++++++++++++------------------ > fs/xfs/xfs_qm.h | 22 ++++++++++------------ > fs/xfs/xfs_qm_syscalls.c | 24 ++++++++++++------------ > fs/xfs/xfs_quotaops.c | 12 ++++++------ > fs/xfs/xfs_trans_dquot.c | 18 +++++++++--------- > 6 files changed, 70 insertions(+), 72 deletions(-) A few things here, starting with the "defq" naming. These are quota limits, not "default quotas". I'd suggest taht this whole set of structures need to be renamed as "quota limits". e.g struct xfs_quota_limits { xfs_qcnt_t hard; /* default hard limit */ xfs_qcnt_t soft; /* default soft limit */ time64_t time; /* limit for timers */ xfs_qwarncnt_t warn; /* limit for warnings */ }; Then we have qlim = xfs_qm_get_default_limits(q, xfs_dquot_type(dq)); > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 2d6b50760962..6975c27145fc 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -76,22 +76,22 @@ xfs_qm_adjust_dqlimits( > ASSERT(dq->q_id); > defq = xfs_get_defquota(q, xfs_dquot_type(dq)); > > - if (defq->bsoftlimit && !dq->q_blk.softlimit) { > - dq->q_blk.softlimit = defq->bsoftlimit; > + if (defq->dfq_blk.softlimit && !dq->q_blk.softlimit) { > + dq->q_blk.softlimit = defq->dfq_blk.softlimit; > prealloc = 1; > } > - if (defq->bhardlimit && !dq->q_blk.hardlimit) { > - dq->q_blk.hardlimit = defq->bhardlimit; > + if (defq->dfq_blk.hardlimit && !dq->q_blk.hardlimit) { > + dq->q_blk.hardlimit = defq->dfq_blk.hardlimit; > prealloc = 1; > } > - 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 (defq->dfq_ino.softlimit && !dq->q_ino.softlimit) > + dq->q_ino.softlimit = defq->dfq_ino.softlimit; > + if (defq->dfq_ino.hardlimit && !dq->q_ino.hardlimit) > + dq->q_ino.hardlimit = defq->dfq_ino.hardlimit; > + if (defq->dfq_rtb.softlimit && !dq->q_rtb.softlimit) > + dq->q_rtb.softlimit = defq->dfq_rtb.softlimit; > + if (defq->dfq_rtb.hardlimit && !dq->q_rtb.hardlimit) > + dq->q_rtb.hardlimit = defq->dfq_rtb.hardlimit; And all this turns into somthing much easier to read: .... if (qlim->ino.soft && !dq->q_ino.softlimit) dq->q_ino.softlimit = qlim->ino.soft; if (qlim->ino.hard && !dq->q_ino.hardlimit) dq->q_ino.hardlimit = qlim->ino.hard; .... I'll also suggest we don't need to check qlim values here. It could just be: if (!dq->q_ino.softlimit) dq->q_ino.softlimit = qlim->ino.soft; if (!dq->q_ino.hardlimit) dq->q_ino.hardlimit = qlim->ino.hard; > @@ -41,20 +41,18 @@ extern struct kmem_zone *xfs_qm_dqtrxzone; > */ > #define XFS_DQUOT_CLUSTER_SIZE_FSB (xfs_filblks_t)1 > > +struct xfs_def_qres { > + xfs_qcnt_t hardlimit; /* default hard limit */ > + xfs_qcnt_t softlimit; /* default soft limit */ > + time64_t timelimit; /* limit for timers */ > + xfs_qwarncnt_t warnlimit; /* limit for warnings */ > +}; As I implied above, this is a quota limits structure, not a "default quota" structure. I'm not sure what the "res" in the name means, either... > + > /* Defaults for each quota type: time limits, warn limits, usage limits */ > struct xfs_def_quota { > - time64_t btimelimit; /* limit for blks timer */ > - time64_t itimelimit; /* limit for inodes timer */ > - time64_t rtbtimelimit; /* limit for rt blks timer */ > - xfs_qwarncnt_t bwarnlimit; /* limit for blks warnings */ > - xfs_qwarncnt_t iwarnlimit; /* limit for inodes warnings */ > - xfs_qwarncnt_t rtbwarnlimit; /* limit for rt blks warnings */ > - xfs_qcnt_t bhardlimit; /* default data blk hard limit */ > - xfs_qcnt_t bsoftlimit; /* default data blk soft limit */ > - xfs_qcnt_t ihardlimit; /* default inode count hard limit */ > - xfs_qcnt_t isoftlimit; /* default inode count soft limit */ > - xfs_qcnt_t rtbhardlimit; /* default realtime blk hard limit */ > - xfs_qcnt_t rtbsoftlimit; /* default realtime blk soft limit */ > + struct xfs_def_qres dfq_blk; > + struct xfs_def_qres dfq_ino; > + struct xfs_def_qres dfq_rtb; > }; The namespacing of these variables adds no value. It just makes the code more verbose and harder to read. e.g. > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 1b2b70b1660f..393b88612cc8 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -502,8 +502,8 @@ xfs_qm_scall_setqlim( > dqp->q_blk.softlimit = soft; > xfs_dquot_set_prealloc_limits(dqp); > if (id == 0) { > - defq->bhardlimit = hard; > - defq->bsoftlimit = soft; > + defq->dfq_blk.hardlimit = hard; > + defq->dfq_blk.softlimit = soft; IMO, these sorts of changes decrease the reability of the code. I'd much prefer something like: if (id == 0) { - defq->bhardlimit = hard; - defq->bsoftlimit = soft; + qlim->blk.hard = hard; + qlim->blk.soft = soft; As it is still clear we are changing the hard block quota limits... Cheers, Dave. -- Dave Chinner david@fromorbit.com
On Wed, Jul 01, 2020 at 04:13:43PM -0700, Darrick J. Wong wrote: > On Thu, Jul 02, 2020 at 09:01:36AM +1000, Dave Chinner wrote: > > On Tue, Jun 30, 2020 at 08:42:36AM -0700, Darrick J. Wong wrote: > > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > > > 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: Darrick J. Wong <darrick.wong@oracle.com> > > .... > > > @@ -124,82 +123,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 > > > > You can get rid of the ifdef DEBUG here - if ASSERT is not defined > > then the compiler will elide all this code anyway. > > OK. Actually, not ok. A later patch in this series will refactor this whole ugly function (and in the next round the #ifdefs) out of existence, so I'll leave this part of the patch the way it is. --D > > > /* Allocate and initialize the dquot buffer for this in-core dquot. */ > > > @@ -1123,9 +1119,29 @@ static xfs_failaddr_t > > > xfs_qm_dqflush_check( > > > struct xfs_dquot *dqp) > > > { > > > + struct xfs_disk_dquot *ddq = &dqp->q_core; > > > + > > > if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1) > > > 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; > > > > These are new in this patch. These are checked by > > xfs_dquot_verify(), so what's the reason for duplicating the checks > > here? > > The new functions perform spot-checks of the incore dquot before we start > flushing them out to disk, because the goal of this patch is to further > decouple the incore and ondisk dquots ahead of the y2038 support series. > > --D > > > Cheers, > > > > Dave. > > -- > > Dave Chinner > > david@fromorbit.com
On Wed, Jul 01, 2020 at 10:51:34AM -0700, Darrick J. Wong wrote:
> On Wed, Jul 01, 2020 at 09:56:21AM +0100, Christoph Hellwig wrote:
> > On Tue, Jun 30, 2020 at 08:43:20AM -0700, Darrick J. Wong wrote:
> > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > >
> > > Refactor the open-coded test for whether or not we're over quota.
> > >
> > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > ---
> > > fs/xfs/xfs_dquot.c | 95 ++++++++++++++++------------------------------------
> > > 1 file changed, 30 insertions(+), 65 deletions(-)
> > >
> > >
> > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> > > index 35a113d1b42b..ef34c82c28a0 100644
> > > --- a/fs/xfs/xfs_dquot.c
> > > +++ b/fs/xfs/xfs_dquot.c
> > > @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits(
> > > xfs_dquot_set_prealloc_limits(dq);
> > > }
> > >
> > > +/*
> > > + * Determine if this quota counter is over either limit and set the quota
> > > + * timers as appropriate.
> > > + */
> > > +static inline void
> > > +xfs_qm_adjust_res_timer(
> > > + struct xfs_dquot_res *res,
> > > + struct xfs_def_qres *dres)
> > > +{
> > > + bool over;
> > > +
> > > +#ifdef DEBUG
> > > + if (res->hardlimit)
> > > + ASSERT(res->softlimit <= res->hardlimit);
> > > +#endif
> >
> > Maybe:
> > ASSERRT(!res->hardlimit || res->softlimit <= res->hardlimit);
>
> Changed.
>
> >
> > > +
> > > + over = (res->softlimit && res->count > res->softlimit) ||
> > > + (res->hardlimit && res->count > res->hardlimit);
> > > +
> > > + if (over && res->timer == 0)
> > > + res->timer = ktime_get_real_seconds() + dres->timelimit;
> > > + else if (!over && res->timer != 0)
> > > + res->timer = 0;
> > > + else if (!over && res->timer == 0)
> > > + res->warnings = 0;
> >
> > What about:
> >
> > if ((res->softlimit && res->count > res->softlimit) ||
> > (res->hardlimit && res->count > res->hardlimit)) {
> > if (res->timer == 0)
> > res->timer = ktime_get_real_seconds() + dres->timelimit;
> > } else {
> > if (res->timer)
> > res->timer = 0;
> > else
> > res->warnings = 0;
> > }
>
> I don't care either way, but the last time I sent this patch out, Eric
> and Amir seemed to want a flatter if structure:
I much prefer Christoph's version - I was going to suggest the same
sort of thing myself as the "flatter" version just looks needlessly
convoluted to me.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
On Wed, Jul 01, 2020 at 04:19:10PM -0700, Darrick J. Wong wrote:
> On Thu, Jul 02, 2020 at 08:50:53AM +1000, Dave Chinner wrote:
> > On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote:
> > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > >
> > > Use the incore dq_flags to figure out the dquot type. This is the first
> > > step towards removing xfs_disk_dquot from the incore dquot.
> > >
> > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > ---
> > > fs/xfs/libxfs/xfs_quota_defs.h | 2 ++
> > > fs/xfs/scrub/quota.c | 4 ----
> > > fs/xfs/xfs_dquot.c | 33 +++++++++++++++++++++++++++++++--
> > > fs/xfs/xfs_dquot.h | 2 ++
> > > fs/xfs/xfs_dquot_item.c | 6 ++++--
> > > fs/xfs/xfs_qm.c | 4 ++--
> > > fs/xfs/xfs_qm.h | 2 +-
> > > fs/xfs/xfs_qm_syscalls.c | 9 +++------
> > > 8 files changed, 45 insertions(+), 17 deletions(-)
> > >
> > >
> > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> > > index 56d9dd787e7b..459023b0a304 100644
> > > --- a/fs/xfs/libxfs/xfs_quota_defs.h
> > > +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> > > @@ -29,6 +29,8 @@ typedef uint16_t xfs_qwarncnt_t;
> > >
> > > #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
> > >
> > > +#define XFS_DQ_ONDISK (XFS_DQ_ALLTYPES)
> >
> > That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK?
>
> Well, based on Christoph's suggestions I broke the incore dquot flags
> (XFS_DQ_*) apart from the ondisk dquot flags (XFS_DQFLAG_*). Not sure
> if that's really better, but at least the namespaces are separate now.
Sure, but the point I was trying to make is that "XFS_DQ_ONDISK"
doesn't actually indicate what part of the on-disk dquot it refers
to. We use the phrase "on-disk dquot" to refer to the entire on-disk
dquot, not a subset of flags in a flags field in the on-disk
dquot. Hence the name of this variable needs to be more specific as
to what it applies to in the on-disk dquot...
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
On Wed, Jul 01, 2020 at 04:33:30PM -0700, Darrick J. Wong wrote:
> On Wed, Jul 01, 2020 at 04:13:43PM -0700, Darrick J. Wong wrote:
> > On Thu, Jul 02, 2020 at 09:01:36AM +1000, Dave Chinner wrote:
> > > On Tue, Jun 30, 2020 at 08:42:36AM -0700, Darrick J. Wong wrote:
> > > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > > >
> > > > 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: Darrick J. Wong <darrick.wong@oracle.com>
> > > ....
> > > > @@ -124,82 +123,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
> > >
> > > You can get rid of the ifdef DEBUG here - if ASSERT is not defined
> > > then the compiler will elide all this code anyway.
> >
> > OK.
>
> Actually, not ok. A later patch in this series will refactor this whole
> ugly function (and in the next round the #ifdefs) out of existence, so
> I'll leave this part of the patch the way it is.
Ok.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
On Thu, Jul 02, 2020 at 09:44:35AM +1000, Dave Chinner wrote: > On Wed, Jul 01, 2020 at 04:19:10PM -0700, Darrick J. Wong wrote: > > On Thu, Jul 02, 2020 at 08:50:53AM +1000, Dave Chinner wrote: > > > On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote: > > > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > > > > > Use the incore dq_flags to figure out the dquot type. This is the first > > > > step towards removing xfs_disk_dquot from the incore dquot. > > > > > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > > > > --- > > > > fs/xfs/libxfs/xfs_quota_defs.h | 2 ++ > > > > fs/xfs/scrub/quota.c | 4 ---- > > > > fs/xfs/xfs_dquot.c | 33 +++++++++++++++++++++++++++++++-- > > > > fs/xfs/xfs_dquot.h | 2 ++ > > > > fs/xfs/xfs_dquot_item.c | 6 ++++-- > > > > fs/xfs/xfs_qm.c | 4 ++-- > > > > fs/xfs/xfs_qm.h | 2 +- > > > > fs/xfs/xfs_qm_syscalls.c | 9 +++------ > > > > 8 files changed, 45 insertions(+), 17 deletions(-) > > > > > > > > > > > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h > > > > index 56d9dd787e7b..459023b0a304 100644 > > > > --- a/fs/xfs/libxfs/xfs_quota_defs.h > > > > +++ b/fs/xfs/libxfs/xfs_quota_defs.h > > > > @@ -29,6 +29,8 @@ typedef uint16_t xfs_qwarncnt_t; > > > > > > > > #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) > > > > > > > > +#define XFS_DQ_ONDISK (XFS_DQ_ALLTYPES) > > > > > > That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK? > > > > Well, based on Christoph's suggestions I broke the incore dquot flags > > (XFS_DQ_*) apart from the ondisk dquot flags (XFS_DQFLAG_*). Not sure > > if that's really better, but at least the namespaces are separate now. > > Sure, but the point I was trying to make is that "XFS_DQ_ONDISK" > doesn't actually indicate what part of the on-disk dquot it refers > to. We use the phrase "on-disk dquot" to refer to the entire on-disk > dquot, not a subset of flags in a flags field in the on-disk > dquot. Hence the name of this variable needs to be more specific as > to what it applies to in the on-disk dquot... Sorry, I was typing too fast. xfs_format.h now has: #define XFS_DQFLAG_USER 0x01 /* user dquot record */ #define XFS_DQFLAG_PROJ 0x02 /* project dquot record */ #define XFS_DQFLAG_GROUP 0x04 /* group dquot record */ #define XFS_DQFLAG_TYPE_MASK (XFS_DQFLAG_USER | \ XFS_DQFLAG_PROJ | \ XFS_DQFLAG_GROUP) #define XFS_DQFLAG_ALL (XFS_DQFLAG_TYPE_MASK) /* * This is the main portion of the on-disk representation of quota * information for a user. This is the q_core of the struct xfs_dquot * that is kept in kernel memory. We pad this with some more expansion * room to construct the on disk structure. */ struct xfs_disk_dquot { __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */ __u8 d_version; /* dquot version */ __u8 d_flags; /* XFS_DQFLAG_* */ I'm not particularly thrilled about the DQFLAG/DQ thing though. DDFLAG? (Also note that the future bigtime series will add a new ondisk flag XFS_DQFLAG_BIGTIME, which ofc will get added to XFS_DQFLAG_ALL.) --D > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com
On Thu, Jul 02, 2020 at 09:30:01AM +1000, Dave Chinner wrote: > On Tue, Jun 30, 2020 at 08:43:07AM -0700, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > Now that we've split up the dquot resource fields into separate structs, > > do the same for the default limits to enable further refactoring. > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > > --- > > fs/xfs/xfs_dquot.c | 30 +++++++++++++++--------------- > > fs/xfs/xfs_qm.c | 36 ++++++++++++++++++------------------ > > fs/xfs/xfs_qm.h | 22 ++++++++++------------ > > fs/xfs/xfs_qm_syscalls.c | 24 ++++++++++++------------ > > fs/xfs/xfs_quotaops.c | 12 ++++++------ > > fs/xfs/xfs_trans_dquot.c | 18 +++++++++--------- > > 6 files changed, 70 insertions(+), 72 deletions(-) > > A few things here, starting with the "defq" naming. These are > quota limits, not "default quotas". I'd suggest taht this whole > set of structures need to be renamed as "quota limits". e.g > > struct xfs_quota_limits { > xfs_qcnt_t hard; /* default hard limit */ > xfs_qcnt_t soft; /* default soft limit */ > time64_t time; /* limit for timers */ > xfs_qwarncnt_t warn; /* limit for warnings */ Ahaha, much better naming. Thank you! > }; > > Then we have > > qlim = xfs_qm_get_default_limits(q, xfs_dquot_type(dq)); > > > > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > > index 2d6b50760962..6975c27145fc 100644 > > --- a/fs/xfs/xfs_dquot.c > > +++ b/fs/xfs/xfs_dquot.c > > @@ -76,22 +76,22 @@ xfs_qm_adjust_dqlimits( > > ASSERT(dq->q_id); > > defq = xfs_get_defquota(q, xfs_dquot_type(dq)); > > > > - if (defq->bsoftlimit && !dq->q_blk.softlimit) { > > - dq->q_blk.softlimit = defq->bsoftlimit; > > + if (defq->dfq_blk.softlimit && !dq->q_blk.softlimit) { > > + dq->q_blk.softlimit = defq->dfq_blk.softlimit; > > prealloc = 1; > > } > > - if (defq->bhardlimit && !dq->q_blk.hardlimit) { > > - dq->q_blk.hardlimit = defq->bhardlimit; > > + if (defq->dfq_blk.hardlimit && !dq->q_blk.hardlimit) { > > + dq->q_blk.hardlimit = defq->dfq_blk.hardlimit; > > prealloc = 1; > > } > > - 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 (defq->dfq_ino.softlimit && !dq->q_ino.softlimit) > > + dq->q_ino.softlimit = defq->dfq_ino.softlimit; > > + if (defq->dfq_ino.hardlimit && !dq->q_ino.hardlimit) > > + dq->q_ino.hardlimit = defq->dfq_ino.hardlimit; > > + if (defq->dfq_rtb.softlimit && !dq->q_rtb.softlimit) > > + dq->q_rtb.softlimit = defq->dfq_rtb.softlimit; > > + if (defq->dfq_rtb.hardlimit && !dq->q_rtb.hardlimit) > > + dq->q_rtb.hardlimit = defq->dfq_rtb.hardlimit; > > And all this turns into somthing much easier to read: > > .... > if (qlim->ino.soft && !dq->q_ino.softlimit) > dq->q_ino.softlimit = qlim->ino.soft; > if (qlim->ino.hard && !dq->q_ino.hardlimit) > dq->q_ino.hardlimit = qlim->ino.hard; > .... <nod> Will do. > I'll also suggest we don't need to check qlim values here. It could > just be: > > if (!dq->q_ino.softlimit) > dq->q_ino.softlimit = qlim->ino.soft; > if (!dq->q_ino.hardlimit) > dq->q_ino.hardlimit = qlim->ino.hard; Separate patch, but yes, I don't think we really need to check that the defaults are set, because (afaict) xfs_qm_set_defquota always sets them to something nowadays, even if that something is a zero limit in the root dquot. > > > @@ -41,20 +41,18 @@ extern struct kmem_zone *xfs_qm_dqtrxzone; > > */ > > #define XFS_DQUOT_CLUSTER_SIZE_FSB (xfs_filblks_t)1 > > > > +struct xfs_def_qres { > > + xfs_qcnt_t hardlimit; /* default hard limit */ > > + xfs_qcnt_t softlimit; /* default soft limit */ > > + time64_t timelimit; /* limit for timers */ > > + xfs_qwarncnt_t warnlimit; /* limit for warnings */ > > +}; > > As I implied above, this is a quota limits structure, not a "default > quota" structure. I'm not sure what the "res" in the name means, > either... default quota resource limit, but xfs_quota_limits fits the bill nicely. > > + > > /* Defaults for each quota type: time limits, warn limits, usage limits */ > > struct xfs_def_quota { > > - time64_t btimelimit; /* limit for blks timer */ > > - time64_t itimelimit; /* limit for inodes timer */ > > - time64_t rtbtimelimit; /* limit for rt blks timer */ > > - xfs_qwarncnt_t bwarnlimit; /* limit for blks warnings */ > > - xfs_qwarncnt_t iwarnlimit; /* limit for inodes warnings */ > > - xfs_qwarncnt_t rtbwarnlimit; /* limit for rt blks warnings */ > > - xfs_qcnt_t bhardlimit; /* default data blk hard limit */ > > - xfs_qcnt_t bsoftlimit; /* default data blk soft limit */ > > - xfs_qcnt_t ihardlimit; /* default inode count hard limit */ > > - xfs_qcnt_t isoftlimit; /* default inode count soft limit */ > > - xfs_qcnt_t rtbhardlimit; /* default realtime blk hard limit */ > > - xfs_qcnt_t rtbsoftlimit; /* default realtime blk soft limit */ > > + struct xfs_def_qres dfq_blk; > > + struct xfs_def_qres dfq_ino; > > + struct xfs_def_qres dfq_rtb; > > }; > > The namespacing of these variables adds no value. It just makes the > code more verbose and harder to read. e.g. > > > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > > index 1b2b70b1660f..393b88612cc8 100644 > > --- a/fs/xfs/xfs_qm_syscalls.c > > +++ b/fs/xfs/xfs_qm_syscalls.c > > @@ -502,8 +502,8 @@ xfs_qm_scall_setqlim( > > dqp->q_blk.softlimit = soft; > > xfs_dquot_set_prealloc_limits(dqp); > > if (id == 0) { > > - defq->bhardlimit = hard; > > - defq->bsoftlimit = soft; > > + defq->dfq_blk.hardlimit = hard; > > + defq->dfq_blk.softlimit = soft; > > IMO, these sorts of changes decrease the reability of the code. I'd > much prefer something like: > > if (id == 0) { > - defq->bhardlimit = hard; > - defq->bsoftlimit = soft; > + qlim->blk.hard = hard; > + qlim->blk.soft = soft; > > As it is still clear we are changing the hard block quota limits... <nod> Done. Thanks for slogging through this growing patchset... --D > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com
On 6/30/20 8:43 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Now that we've stopped using qcore entirely, drop it from the incore > dquot. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Looks ok Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/scrub/quota.c | 4 ---- > fs/xfs/xfs_dquot.c | 29 +++++++++-------------------- > fs/xfs/xfs_dquot.h | 1 - > 3 files changed, 9 insertions(+), 25 deletions(-) > > > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index 2fc2625feca0..f4aad5b00188 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -79,7 +79,6 @@ xchk_quota_item( > struct xchk_quota_info *sqi = priv; > struct xfs_scrub *sc = sqi->sc; > struct xfs_mount *mp = sc->mp; > - struct xfs_disk_dquot *d = &dq->q_core; > struct xfs_quotainfo *qi = mp->m_quotainfo; > xfs_fileoff_t offset; > xfs_ino_t fs_icount; > @@ -98,9 +97,6 @@ xchk_quota_item( > > sqi->last_id = dq->q_id; > > - if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) > - xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); > - > /* > * Warn if the hard limits are larger than the fs. > * Administrators can do this, though in production this seems > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 7434ee57ec43..2d6b50760962 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -529,7 +529,6 @@ 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); > @@ -568,8 +567,13 @@ xfs_dquot_to_disk( > struct xfs_disk_dquot *ddqp, > struct xfs_dquot *dqp) > { > - memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); > + ddqp->d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); > + ddqp->d_version = XFS_DQUOT_VERSION; > ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK; > + ddqp->d_id = cpu_to_be32(dqp->q_id); > + ddqp->d_pad0 = 0; > + ddqp->d_pad = 0; > + > 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); > @@ -1180,7 +1184,6 @@ xfs_qm_dqflush( > struct xfs_log_item *lip = &dqp->q_logitem.qli_item; > struct xfs_buf *bp; > struct xfs_dqblk *dqb; > - struct xfs_disk_dquot *ddqp; > xfs_failaddr_t fa; > int error; > > @@ -1204,22 +1207,6 @@ xfs_qm_dqflush( > if (error) > goto out_abort; > > - /* > - * Calculate the location of the dquot inside the buffer. > - */ > - dqb = bp->b_addr + dqp->q_bufoffset; > - ddqp = &dqb->dd_diskdq; > - > - /* sanity check the in-core structure before we flush */ > - fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0); > - if (fa) { > - xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > - dqp->q_id, fa); > - xfs_buf_relse(bp); > - error = -EFSCORRUPTED; > - goto out_abort; > - } > - > fa = xfs_qm_dqflush_check(dqp); > if (fa) { > xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS", > @@ -1229,7 +1216,9 @@ xfs_qm_dqflush( > goto out_abort; > } > > - xfs_dquot_to_disk(ddqp, dqp); > + /* Flush the incore dquot to the ondisk buffer. */ > + dqb = bp->b_addr + dqp->q_bufoffset; > + xfs_dquot_to_disk(&dqb->dd_diskdq, dqp); > > /* > * Clear the dirty field and remember the flush lsn for later use. > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 414bae537b1d..62b0fc6e0133 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -71,7 +71,6 @@ struct xfs_dquot { > struct xfs_dquot_res q_ino; /* inodes */ > struct xfs_dquot_res q_rtb; /* realtime blocks */ > > - struct xfs_disk_dquot q_core; > struct xfs_dq_logitem q_logitem; > > xfs_qcnt_t q_prealloc_lo_wmark; >
On 6/30/20 8:43 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Now that we've split up the dquot resource fields into separate structs, > do the same for the default limits to enable further refactoring. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Ok, looks good Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_dquot.c | 30 +++++++++++++++--------------- > fs/xfs/xfs_qm.c | 36 ++++++++++++++++++------------------ > fs/xfs/xfs_qm.h | 22 ++++++++++------------ > fs/xfs/xfs_qm_syscalls.c | 24 ++++++++++++------------ > fs/xfs/xfs_quotaops.c | 12 ++++++------ > fs/xfs/xfs_trans_dquot.c | 18 +++++++++--------- > 6 files changed, 70 insertions(+), 72 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 2d6b50760962..6975c27145fc 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -76,22 +76,22 @@ xfs_qm_adjust_dqlimits( > ASSERT(dq->q_id); > defq = xfs_get_defquota(q, xfs_dquot_type(dq)); > > - if (defq->bsoftlimit && !dq->q_blk.softlimit) { > - dq->q_blk.softlimit = defq->bsoftlimit; > + if (defq->dfq_blk.softlimit && !dq->q_blk.softlimit) { > + dq->q_blk.softlimit = defq->dfq_blk.softlimit; > prealloc = 1; > } > - if (defq->bhardlimit && !dq->q_blk.hardlimit) { > - dq->q_blk.hardlimit = defq->bhardlimit; > + if (defq->dfq_blk.hardlimit && !dq->q_blk.hardlimit) { > + dq->q_blk.hardlimit = defq->dfq_blk.hardlimit; > prealloc = 1; > } > - 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 (defq->dfq_ino.softlimit && !dq->q_ino.softlimit) > + dq->q_ino.softlimit = defq->dfq_ino.softlimit; > + if (defq->dfq_ino.hardlimit && !dq->q_ino.hardlimit) > + dq->q_ino.hardlimit = defq->dfq_ino.hardlimit; > + if (defq->dfq_rtb.softlimit && !dq->q_rtb.softlimit) > + dq->q_rtb.softlimit = defq->dfq_rtb.softlimit; > + if (defq->dfq_rtb.hardlimit && !dq->q_rtb.hardlimit) > + dq->q_rtb.hardlimit = defq->dfq_rtb.hardlimit; > > if (prealloc) > xfs_dquot_set_prealloc_limits(dq); > @@ -136,7 +136,7 @@ xfs_qm_adjust_dqtimers( > (dq->q_blk.hardlimit && > (dq->q_blk.count > dq->q_blk.hardlimit))) { > dq->q_blk.timer = ktime_get_real_seconds() + > - defq->btimelimit; > + defq->dfq_blk.timelimit; > } else { > dq->q_blk.warnings = 0; > } > @@ -155,7 +155,7 @@ xfs_qm_adjust_dqtimers( > (dq->q_ino.hardlimit && > (dq->q_ino.count > dq->q_ino.hardlimit))) { > dq->q_ino.timer = ktime_get_real_seconds() + > - defq->itimelimit; > + defq->dfq_ino.timelimit; > } else { > dq->q_ino.warnings = 0; > } > @@ -174,7 +174,7 @@ xfs_qm_adjust_dqtimers( > (dq->q_rtb.hardlimit && > (dq->q_rtb.count > dq->q_rtb.hardlimit))) { > dq->q_rtb.timer = ktime_get_real_seconds() + > - defq->rtbtimelimit; > + defq->dfq_rtb.timelimit; > } else { > dq->q_rtb.warnings = 0; > } > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index a56c6e4a5d99..28326a6264a8 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -562,12 +562,12 @@ xfs_qm_set_defquota( > * Timers and warnings have been already set, let's just set the > * default limits for this quota type > */ > - 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; > + defq->dfq_blk.hardlimit = dqp->q_blk.hardlimit; > + defq->dfq_blk.softlimit = dqp->q_blk.softlimit; > + defq->dfq_ino.hardlimit = dqp->q_ino.hardlimit; > + defq->dfq_ino.softlimit = dqp->q_ino.softlimit; > + defq->dfq_rtb.hardlimit = dqp->q_rtb.hardlimit; > + defq->dfq_rtb.softlimit = dqp->q_rtb.softlimit; > xfs_qm_dqdestroy(dqp); > } > > @@ -584,12 +584,12 @@ xfs_qm_init_timelimits( > > defq = xfs_get_defquota(qinf, type); > > - defq->btimelimit = XFS_QM_BTIMELIMIT; > - defq->itimelimit = XFS_QM_ITIMELIMIT; > - defq->rtbtimelimit = XFS_QM_RTBTIMELIMIT; > - defq->bwarnlimit = XFS_QM_BWARNLIMIT; > - defq->iwarnlimit = XFS_QM_IWARNLIMIT; > - defq->rtbwarnlimit = XFS_QM_RTBWARNLIMIT; > + defq->dfq_blk.timelimit = XFS_QM_BTIMELIMIT; > + defq->dfq_ino.timelimit = XFS_QM_ITIMELIMIT; > + defq->dfq_rtb.timelimit = XFS_QM_RTBTIMELIMIT; > + defq->dfq_blk.warnlimit = XFS_QM_BWARNLIMIT; > + defq->dfq_ino.warnlimit = XFS_QM_IWARNLIMIT; > + defq->dfq_rtb.warnlimit = XFS_QM_RTBWARNLIMIT; > > /* > * We try to get the limits from the superuser's limits fields. > @@ -608,17 +608,17 @@ xfs_qm_init_timelimits( > * more writing. If it is zero, a default is used. > */ > if (dqp->q_blk.timer) > - defq->btimelimit = dqp->q_blk.timer; > + defq->dfq_blk.timelimit = dqp->q_blk.timer; > if (dqp->q_ino.timer) > - defq->itimelimit = dqp->q_ino.timer; > + defq->dfq_ino.timelimit = dqp->q_ino.timer; > if (dqp->q_rtb.timer) > - defq->rtbtimelimit = dqp->q_rtb.timer; > + defq->dfq_rtb.timelimit = dqp->q_rtb.timer; > if (dqp->q_blk.warnings) > - defq->bwarnlimit = dqp->q_blk.warnings; > + defq->dfq_blk.warnlimit = dqp->q_blk.warnings; > if (dqp->q_ino.warnings) > - defq->iwarnlimit = dqp->q_ino.warnings; > + defq->dfq_ino.warnlimit = dqp->q_ino.warnings; > if (dqp->q_rtb.warnings) > - defq->rtbwarnlimit = dqp->q_rtb.warnings; > + defq->dfq_rtb.warnlimit = dqp->q_rtb.warnings; > > xfs_qm_dqdestroy(dqp); > } > diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h > index 6ed4ae942603..e2f0027f0ac1 100644 > --- a/fs/xfs/xfs_qm.h > +++ b/fs/xfs/xfs_qm.h > @@ -41,20 +41,18 @@ extern struct kmem_zone *xfs_qm_dqtrxzone; > */ > #define XFS_DQUOT_CLUSTER_SIZE_FSB (xfs_filblks_t)1 > > +struct xfs_def_qres { > + xfs_qcnt_t hardlimit; /* default hard limit */ > + xfs_qcnt_t softlimit; /* default soft limit */ > + time64_t timelimit; /* limit for timers */ > + xfs_qwarncnt_t warnlimit; /* limit for warnings */ > +}; > + > /* Defaults for each quota type: time limits, warn limits, usage limits */ > struct xfs_def_quota { > - time64_t btimelimit; /* limit for blks timer */ > - time64_t itimelimit; /* limit for inodes timer */ > - time64_t rtbtimelimit; /* limit for rt blks timer */ > - xfs_qwarncnt_t bwarnlimit; /* limit for blks warnings */ > - xfs_qwarncnt_t iwarnlimit; /* limit for inodes warnings */ > - xfs_qwarncnt_t rtbwarnlimit; /* limit for rt blks warnings */ > - xfs_qcnt_t bhardlimit; /* default data blk hard limit */ > - xfs_qcnt_t bsoftlimit; /* default data blk soft limit */ > - xfs_qcnt_t ihardlimit; /* default inode count hard limit */ > - xfs_qcnt_t isoftlimit; /* default inode count soft limit */ > - xfs_qcnt_t rtbhardlimit; /* default realtime blk hard limit */ > - xfs_qcnt_t rtbsoftlimit; /* default realtime blk soft limit */ > + struct xfs_def_qres dfq_blk; > + struct xfs_def_qres dfq_ino; > + struct xfs_def_qres dfq_rtb; > }; > > /* > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 1b2b70b1660f..393b88612cc8 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -502,8 +502,8 @@ xfs_qm_scall_setqlim( > dqp->q_blk.softlimit = soft; > xfs_dquot_set_prealloc_limits(dqp); > if (id == 0) { > - defq->bhardlimit = hard; > - defq->bsoftlimit = soft; > + defq->dfq_blk.hardlimit = hard; > + defq->dfq_blk.softlimit = soft; > } > } else { > xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft); > @@ -518,8 +518,8 @@ xfs_qm_scall_setqlim( > dqp->q_rtb.hardlimit = hard; > dqp->q_rtb.softlimit = soft; > if (id == 0) { > - defq->rtbhardlimit = hard; > - defq->rtbsoftlimit = soft; > + defq->dfq_rtb.hardlimit = hard; > + defq->dfq_rtb.softlimit = soft; > } > } else { > xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft); > @@ -535,8 +535,8 @@ xfs_qm_scall_setqlim( > dqp->q_ino.hardlimit = hard; > dqp->q_ino.softlimit = soft; > if (id == 0) { > - defq->ihardlimit = hard; > - defq->isoftlimit = soft; > + defq->dfq_ino.hardlimit = hard; > + defq->dfq_ino.softlimit = soft; > } > } else { > xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft); > @@ -554,11 +554,11 @@ xfs_qm_scall_setqlim( > > if (id == 0) { > if (newlim->d_fieldmask & QC_SPC_WARNS) > - defq->bwarnlimit = newlim->d_spc_warns; > + defq->dfq_blk.warnlimit = newlim->d_spc_warns; > if (newlim->d_fieldmask & QC_INO_WARNS) > - defq->iwarnlimit = newlim->d_ino_warns; > + defq->dfq_ino.warnlimit = newlim->d_ino_warns; > if (newlim->d_fieldmask & QC_RT_SPC_WARNS) > - defq->rtbwarnlimit = newlim->d_rt_spc_warns; > + defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns; > } > > /* > @@ -579,11 +579,11 @@ xfs_qm_scall_setqlim( > > if (id == 0) { > if (newlim->d_fieldmask & QC_SPC_TIMER) > - defq->btimelimit = newlim->d_spc_timer; > + defq->dfq_blk.timelimit = newlim->d_spc_timer; > if (newlim->d_fieldmask & QC_INO_TIMER) > - defq->itimelimit = newlim->d_ino_timer; > + defq->dfq_ino.timelimit = newlim->d_ino_timer; > if (newlim->d_fieldmask & QC_RT_SPC_TIMER) > - defq->rtbtimelimit = newlim->d_rt_spc_timer; > + defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer; > } > > if (id != 0) { > diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c > index bf809b77a316..c86a6fe263da 100644 > --- a/fs/xfs/xfs_quotaops.c > +++ b/fs/xfs/xfs_quotaops.c > @@ -37,12 +37,12 @@ xfs_qm_fill_state( > tstate->flags |= QCI_SYSFILE; > tstate->blocks = ip->i_d.di_nblocks; > tstate->nextents = ip->i_df.if_nextents; > - tstate->spc_timelimit = (u32)defq->btimelimit; > - tstate->ino_timelimit = (u32)defq->itimelimit; > - tstate->rt_spc_timelimit = (u32)defq->rtbtimelimit; > - tstate->spc_warnlimit = defq->bwarnlimit; > - tstate->ino_warnlimit = defq->iwarnlimit; > - tstate->rt_spc_warnlimit = defq->rtbwarnlimit; > + tstate->spc_timelimit = (u32)defq->dfq_blk.timelimit; > + tstate->ino_timelimit = (u32)defq->dfq_ino.timelimit; > + tstate->rt_spc_timelimit = (u32)defq->dfq_rtb.timelimit; > + tstate->spc_warnlimit = defq->dfq_blk.warnlimit; > + tstate->ino_warnlimit = defq->dfq_ino.warnlimit; > + tstate->rt_spc_warnlimit = defq->dfq_rtb.warnlimit; > if (tempqip) > xfs_irele(ip); > } > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 28b59a4069a3..392e51baad6f 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -587,25 +587,25 @@ xfs_trans_dqresv( > if (flags & XFS_TRANS_DQ_RES_BLKS) { > hardlimit = dqp->q_blk.hardlimit; > if (!hardlimit) > - hardlimit = defq->bhardlimit; > + hardlimit = defq->dfq_blk.hardlimit; > softlimit = dqp->q_blk.softlimit; > if (!softlimit) > - softlimit = defq->bsoftlimit; > + softlimit = defq->dfq_blk.softlimit; > timer = dqp->q_blk.timer; > warns = dqp->q_blk.warnings; > - warnlimit = defq->bwarnlimit; > + warnlimit = defq->dfq_blk.warnlimit; > resbcountp = &dqp->q_blk.reserved; > } else { > ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); > hardlimit = dqp->q_rtb.hardlimit; > if (!hardlimit) > - hardlimit = defq->rtbhardlimit; > + hardlimit = defq->dfq_rtb.hardlimit; > softlimit = dqp->q_rtb.softlimit; > if (!softlimit) > - softlimit = defq->rtbsoftlimit; > + softlimit = defq->dfq_rtb.softlimit; > timer = dqp->q_rtb.timer; > warns = dqp->q_rtb.warnings; > - warnlimit = defq->rtbwarnlimit; > + warnlimit = defq->dfq_rtb.warnlimit; > resbcountp = &dqp->q_rtb.reserved; > } > > @@ -640,13 +640,13 @@ xfs_trans_dqresv( > total_count = dqp->q_ino.reserved + ninos; > timer = dqp->q_ino.timer; > warns = dqp->q_ino.warnings; > - warnlimit = defq->iwarnlimit; > + warnlimit = defq->dfq_ino.warnlimit; > hardlimit = dqp->q_ino.hardlimit; > if (!hardlimit) > - hardlimit = defq->ihardlimit; > + hardlimit = defq->dfq_ino.hardlimit; > softlimit = dqp->q_ino.softlimit; > if (!softlimit) > - softlimit = defq->isoftlimit; > + softlimit = defq->dfq_ino.softlimit; > > if (hardlimit && total_count > hardlimit) { > xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN); >
On 6/30/20 8:43 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > struct xfs_dquot already has a pointer to the xfs mount, so remove the > redundant parameter from xfs_qm_adjust_dq*. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Looks fine Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_dquot.c | 4 ++-- > fs/xfs/xfs_dquot.h | 6 ++---- > fs/xfs/xfs_qm.c | 4 ++-- > fs/xfs/xfs_qm_syscalls.c | 2 +- > fs/xfs/xfs_trans_dquot.c | 4 ++-- > 5 files changed, 9 insertions(+), 11 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 6975c27145fc..35a113d1b42b 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -66,9 +66,9 @@ xfs_qm_dqdestroy( > */ > void > xfs_qm_adjust_dqlimits( > - struct xfs_mount *mp, > struct xfs_dquot *dq) > { > + struct xfs_mount *mp = dq->q_mount; > struct xfs_quotainfo *q = mp->m_quotainfo; > struct xfs_def_quota *defq; > int prealloc = 0; > @@ -112,9 +112,9 @@ xfs_qm_adjust_dqlimits( > */ > void > xfs_qm_adjust_dqtimers( > - struct xfs_mount *mp, > struct xfs_dquot *dq) > { > + struct xfs_mount *mp = dq->q_mount; > struct xfs_quotainfo *qi = mp->m_quotainfo; > struct xfs_def_quota *defq; > > diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h > index 62b0fc6e0133..e37b4bebc1ea 100644 > --- a/fs/xfs/xfs_dquot.h > +++ b/fs/xfs/xfs_dquot.h > @@ -181,10 +181,8 @@ void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp); > void xfs_qm_dqdestroy(struct xfs_dquot *dqp); > int xfs_qm_dqflush(struct xfs_dquot *dqp, struct xfs_buf **bpp); > void xfs_qm_dqunpin_wait(struct xfs_dquot *dqp); > -void xfs_qm_adjust_dqtimers(struct xfs_mount *mp, > - struct xfs_dquot *d); > -void xfs_qm_adjust_dqlimits(struct xfs_mount *mp, > - struct xfs_dquot *d); > +void xfs_qm_adjust_dqtimers(struct xfs_dquot *d); > +void xfs_qm_adjust_dqlimits(struct xfs_dquot *d); > xfs_dqid_t xfs_qm_id_for_quotatype(struct xfs_inode *ip, uint type); > int xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id, > uint type, bool can_alloc, > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 28326a6264a8..30deb6cf6a7a 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -1107,8 +1107,8 @@ xfs_qm_quotacheck_dqadjust( > * There are no timers for the default values set in the root dquot. > */ > if (dqp->q_id) { > - xfs_qm_adjust_dqlimits(mp, dqp); > - xfs_qm_adjust_dqtimers(mp, dqp); > + xfs_qm_adjust_dqlimits(dqp); > + xfs_qm_adjust_dqtimers(dqp); > } > > dqp->dq_flags |= XFS_DQ_DIRTY; > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 393b88612cc8..5423e02f9837 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -594,7 +594,7 @@ xfs_qm_scall_setqlim( > * is on or off. We don't really want to bother with iterating > * over all ondisk dquots and turning the timers on/off. > */ > - xfs_qm_adjust_dqtimers(mp, dqp); > + xfs_qm_adjust_dqtimers(dqp); > } > dqp->dq_flags |= XFS_DQ_DIRTY; > xfs_trans_log_dquot(tp, dqp); > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 392e51baad6f..2712814d696d 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -382,8 +382,8 @@ xfs_trans_apply_dquot_deltas( > * Start/reset the timer(s) if needed. > */ > if (dqp->q_id) { > - xfs_qm_adjust_dqlimits(tp->t_mountp, dqp); > - xfs_qm_adjust_dqtimers(tp->t_mountp, dqp); > + xfs_qm_adjust_dqlimits(dqp); > + xfs_qm_adjust_dqtimers(dqp); > } > > dqp->dq_flags |= XFS_DQ_DIRTY; >
On Wed, Jul 01, 2020 at 11:25:08AM -0700, Darrick J. Wong wrote:
> > /*
> > * Ensure we got the type and ID we were looking for. Everything else
> > * we checked by the verifier.
> > */
> > if ((ddqp->d_flags & XFS_DQ_ALLTYPES) != dqp->dq_flags ||
> > ddqp->d_id != dqp->q_core.d_id)
>
> Sounds good to me. I'll make that change.
We also don't need the mask on the on-disk flags, as it never contains
anything but the type, so this can be further simplified.
On Thu, Jul 02, 2020 at 07:30:21AM +0100, Christoph Hellwig wrote:
> On Wed, Jul 01, 2020 at 11:25:08AM -0700, Darrick J. Wong wrote:
> > > /*
> > > * Ensure we got the type and ID we were looking for. Everything else
> > > * we checked by the verifier.
> > > */
> > > if ((ddqp->d_flags & XFS_DQ_ALLTYPES) != dqp->dq_flags ||
> > > ddqp->d_id != dqp->q_core.d_id)
> >
> > Sounds good to me. I'll make that change.
>
> We also don't need the mask on the on-disk flags, as it never contains
> anything but the type, so this can be further simplified.
d_flags will contain more than the type Real Soon Now; I was planning to
send out the y2038 feature patchset (at least for another RFC) right
after landing this series.
--D
On 6/30/20 8:43 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Refactor the open-coded test for whether or not we're over quota. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Ok, the changes look correct. I do not have a preference on the if/else logic mentioned in some of the other reviews. At first glance they both require a bit of a pause, but I didn't find either to be too unsightly to read through. I am amicable to either solution folks prefer. Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_dquot.c | 95 ++++++++++++++++------------------------------------ > 1 file changed, 30 insertions(+), 65 deletions(-) > > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 35a113d1b42b..ef34c82c28a0 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits( > xfs_dquot_set_prealloc_limits(dq); > } > > +/* > + * Determine if this quota counter is over either limit and set the quota > + * timers as appropriate. > + */ > +static inline void > +xfs_qm_adjust_res_timer( > + struct xfs_dquot_res *res, > + struct xfs_def_qres *dres) > +{ > + bool over; > + > +#ifdef DEBUG > + if (res->hardlimit) > + ASSERT(res->softlimit <= res->hardlimit); > +#endif > + > + over = (res->softlimit && res->count > res->softlimit) || > + (res->hardlimit && res->count > res->hardlimit); > + > + if (over && res->timer == 0) > + res->timer = ktime_get_real_seconds() + dres->timelimit; > + else if (!over && res->timer != 0) > + res->timer = 0; > + else if (!over && res->timer == 0) > + res->warnings = 0; > +} > + > /* > * Check the limits and timers of a dquot and start or reset timers > * if necessary. > @@ -121,71 +148,9 @@ xfs_qm_adjust_dqtimers( > ASSERT(dq->q_id); > defq = xfs_get_defquota(qi, xfs_dquot_type(dq)); > > -#ifdef DEBUG > - 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 (!dq->q_blk.timer) { > - if ((dq->q_blk.softlimit && > - (dq->q_blk.count > dq->q_blk.softlimit)) || > - (dq->q_blk.hardlimit && > - (dq->q_blk.count > dq->q_blk.hardlimit))) { > - dq->q_blk.timer = ktime_get_real_seconds() + > - defq->dfq_blk.timelimit; > - } else { > - dq->q_blk.warnings = 0; > - } > - } else { > - if ((!dq->q_blk.softlimit || > - (dq->q_blk.count <= dq->q_blk.softlimit)) && > - (!dq->q_blk.hardlimit || > - (dq->q_blk.count <= dq->q_blk.hardlimit))) { > - dq->q_blk.timer = 0; > - } > - } > - > - if (!dq->q_ino.timer) { > - if ((dq->q_ino.softlimit && > - (dq->q_ino.count > dq->q_ino.softlimit)) || > - (dq->q_ino.hardlimit && > - (dq->q_ino.count > dq->q_ino.hardlimit))) { > - dq->q_ino.timer = ktime_get_real_seconds() + > - defq->dfq_ino.timelimit; > - } else { > - dq->q_ino.warnings = 0; > - } > - } else { > - if ((!dq->q_ino.softlimit || > - (dq->q_ino.count <= dq->q_ino.softlimit)) && > - (!dq->q_ino.hardlimit || > - (dq->q_ino.count <= dq->q_ino.hardlimit))) { > - dq->q_ino.timer = 0; > - } > - } > - > - if (!dq->q_rtb.timer) { > - if ((dq->q_rtb.softlimit && > - (dq->q_rtb.count > dq->q_rtb.softlimit)) || > - (dq->q_rtb.hardlimit && > - (dq->q_rtb.count > dq->q_rtb.hardlimit))) { > - dq->q_rtb.timer = ktime_get_real_seconds() + > - defq->dfq_rtb.timelimit; > - } else { > - dq->q_rtb.warnings = 0; > - } > - } else { > - if ((!dq->q_rtb.softlimit || > - (dq->q_rtb.count <= dq->q_rtb.softlimit)) && > - (!dq->q_rtb.hardlimit || > - (dq->q_rtb.count <= dq->q_rtb.hardlimit))) { > - dq->q_rtb.timer = 0; > - } > - } > + xfs_qm_adjust_res_timer(&dq->q_blk, &defq->dfq_blk); > + xfs_qm_adjust_res_timer(&dq->q_ino, &defq->dfq_ino); > + xfs_qm_adjust_res_timer(&dq->q_rtb, &defq->dfq_rtb); > } > > /* >
On Wed, Jul 01, 2020 at 04:50:31PM -0700, Darrick J. Wong wrote:
> On Thu, Jul 02, 2020 at 09:44:35AM +1000, Dave Chinner wrote:
> > On Wed, Jul 01, 2020 at 04:19:10PM -0700, Darrick J. Wong wrote:
> > > On Thu, Jul 02, 2020 at 08:50:53AM +1000, Dave Chinner wrote:
> > > > On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote:
> > > > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > > > >
> > > > > Use the incore dq_flags to figure out the dquot type. This is the first
> > > > > step towards removing xfs_disk_dquot from the incore dquot.
> > > > >
> > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > > > ---
> > > > > fs/xfs/libxfs/xfs_quota_defs.h | 2 ++
> > > > > fs/xfs/scrub/quota.c | 4 ----
> > > > > fs/xfs/xfs_dquot.c | 33 +++++++++++++++++++++++++++++++--
> > > > > fs/xfs/xfs_dquot.h | 2 ++
> > > > > fs/xfs/xfs_dquot_item.c | 6 ++++--
> > > > > fs/xfs/xfs_qm.c | 4 ++--
> > > > > fs/xfs/xfs_qm.h | 2 +-
> > > > > fs/xfs/xfs_qm_syscalls.c | 9 +++------
> > > > > 8 files changed, 45 insertions(+), 17 deletions(-)
> > > > >
> > > > >
> > > > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> > > > > index 56d9dd787e7b..459023b0a304 100644
> > > > > --- a/fs/xfs/libxfs/xfs_quota_defs.h
> > > > > +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> > > > > @@ -29,6 +29,8 @@ typedef uint16_t xfs_qwarncnt_t;
> > > > >
> > > > > #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
> > > > >
> > > > > +#define XFS_DQ_ONDISK (XFS_DQ_ALLTYPES)
> > > >
> > > > That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK?
> > >
> > > Well, based on Christoph's suggestions I broke the incore dquot flags
> > > (XFS_DQ_*) apart from the ondisk dquot flags (XFS_DQFLAG_*). Not sure
> > > if that's really better, but at least the namespaces are separate now.
> >
> > Sure, but the point I was trying to make is that "XFS_DQ_ONDISK"
> > doesn't actually indicate what part of the on-disk dquot it refers
> > to. We use the phrase "on-disk dquot" to refer to the entire on-disk
> > dquot, not a subset of flags in a flags field in the on-disk
> > dquot. Hence the name of this variable needs to be more specific as
> > to what it applies to in the on-disk dquot...
>
> Sorry, I was typing too fast. xfs_format.h now has:
>
> #define XFS_DQFLAG_USER 0x01 /* user dquot record */
> #define XFS_DQFLAG_PROJ 0x02 /* project dquot record */
> #define XFS_DQFLAG_GROUP 0x04 /* group dquot record */
>
> #define XFS_DQFLAG_TYPE_MASK (XFS_DQFLAG_USER | \
> XFS_DQFLAG_PROJ | \
> XFS_DQFLAG_GROUP)
>
> #define XFS_DQFLAG_ALL (XFS_DQFLAG_TYPE_MASK)
>
> /*
> * This is the main portion of the on-disk representation of quota
> * information for a user. This is the q_core of the struct xfs_dquot
> * that is kept in kernel memory. We pad this with some more expansion
> * room to construct the on disk structure.
> */
> struct xfs_disk_dquot {
> __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */
> __u8 d_version; /* dquot version */
> __u8 d_flags; /* XFS_DQFLAG_* */
>
> I'm not particularly thrilled about the DQFLAG/DQ thing though. DDFLAG?
> (Also note that the future bigtime series will add a new ondisk flag
> XFS_DQFLAG_BIGTIME, which ofc will get added to XFS_DQFLAG_ALL.)
/me shrugs
I don't have any good ideas, but I think that DQFLAG is a bad choice
for an on-disk flag namespace because it's way too generic. It's
more a type/feature indicator so perhaps we should rename d_flags to
d_type or d_features and use:
#define XFS_DDQTYPE_USER
#define XFS_DDQTYPE_PROJ
#define XFS_DDQTYPE_GROUP
#define XFS_DDQTYPE_BIGTIME
#define XFS_DDQTYPE_QUOTA_MASK (XFS_DDQTYPE_USER | ...
#define XFS_DDQTYPE_ALL (XFS_DDQTYPE_QUOTA_MASK | XFS_DDQTYPE_BIGTIME)
Or something like that...
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
On 6/30/20 8:43 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Now that we can pass around quota resource and limit structures, clean > up the open-coded field setting in xfs_qm_scall_setqlim. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Ok, I followed it through, and I think it looks ok Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_qm_syscalls.c | 164 ++++++++++++++++++++++++++-------------------- > 1 file changed, 93 insertions(+), 71 deletions(-) > > > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 5423e02f9837..5044c333af5c 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -436,6 +436,58 @@ xfs_qm_scall_quotaon( > #define XFS_QC_MASK \ > (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK) > > +/* > + * Adjust limits of this quota, and the defaults if passed in. Returns true > + * if the new limits made sense and were applied, false otherwise. > + */ > +static inline bool > +xfs_setqlim_limits( > + struct xfs_mount *mp, > + struct xfs_dquot_res *res, > + struct xfs_def_qres *dres, > + xfs_qcnt_t hard, > + xfs_qcnt_t soft, > + const char *tag) > +{ > + /* The hard limit can't be less than the soft limit. */ > + if (hard != 0 && hard < soft) { > + xfs_debug(mp, "%shard %lld < %ssoft %lld", tag, hard, tag, > + soft); > + return false; > + } > + > + res->hardlimit = hard; > + res->softlimit = soft; > + if (dres) { > + dres->hardlimit = hard; > + dres->softlimit = soft; > + } > + > + return true; > +} > + > +static inline void > +xfs_setqlim_warns( > + struct xfs_dquot_res *res, > + struct xfs_def_qres *dres, > + int warns) > +{ > + res->warnings = warns; > + if (dres) > + dres->warnlimit = warns; > +} > + > +static inline void > +xfs_setqlim_timer( > + struct xfs_dquot_res *res, > + struct xfs_def_qres *dres, > + s64 timer) > +{ > + res->timer = timer; > + if (dres) > + dres->timelimit = timer; > +} > + > /* > * Adjust quota limits, and start/stop timers accordingly. > */ > @@ -450,6 +502,8 @@ xfs_qm_scall_setqlim( > struct xfs_dquot *dqp; > struct xfs_trans *tp; > struct xfs_def_quota *defq; > + struct xfs_dquot_res *res; > + struct xfs_def_qres *dres; > int error; > xfs_qcnt_t hard, soft; > > @@ -489,102 +543,70 @@ xfs_qm_scall_setqlim( > xfs_trans_dqjoin(tp, dqp); > > /* > + * Update quota limits, warnings, and timers, and the defaults > + * if we're touching id == 0. > + * > * Make sure that hardlimits are >= soft limits before changing. > + * > + * Update warnings counter(s) if requested. > + * > + * Timelimits for the super user set the relative time the other users > + * can be over quota for this file system. If it is zero a default is > + * used. Ditto for the default soft and hard limit values (already > + * done, above), and for warnings. > + * > + * For other IDs, userspace can bump out the grace period if over > + * the soft limit. > */ > + > + /* Blocks on the data device. */ > hard = (newlim->d_fieldmask & QC_SPC_HARD) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : > dqp->q_blk.hardlimit; > soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : > dqp->q_blk.softlimit; > - if (hard == 0 || hard >= soft) { > - dqp->q_blk.hardlimit = hard; > - dqp->q_blk.softlimit = soft; > + res = &dqp->q_blk; > + dres = id == 0 ? &defq->dfq_blk : NULL; > + > + if (xfs_setqlim_limits(mp, res, dres, hard, soft, "blk")) > xfs_dquot_set_prealloc_limits(dqp); > - if (id == 0) { > - defq->dfq_blk.hardlimit = hard; > - defq->dfq_blk.softlimit = soft; > - } > - } else { > - xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft); > - } > + if (newlim->d_fieldmask & QC_SPC_WARNS) > + xfs_setqlim_warns(res, dres, newlim->d_spc_warns); > + if (newlim->d_fieldmask & QC_SPC_TIMER) > + xfs_setqlim_timer(res, dres, newlim->d_spc_timer); > + > + /* Blocks on the realtime device. */ > hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : > dqp->q_rtb.hardlimit; > soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : > dqp->q_rtb.softlimit; > - if (hard == 0 || hard >= soft) { > - dqp->q_rtb.hardlimit = hard; > - dqp->q_rtb.softlimit = soft; > - if (id == 0) { > - defq->dfq_rtb.hardlimit = hard; > - defq->dfq_rtb.softlimit = soft; > - } > - } else { > - xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft); > - } > + res = &dqp->q_rtb; > + dres = id == 0 ? &defq->dfq_rtb : NULL; > > + xfs_setqlim_limits(mp, res, dres, hard, soft, "rtb"); > + if (newlim->d_fieldmask & QC_RT_SPC_WARNS) > + xfs_setqlim_warns(res, dres, newlim->d_rt_spc_warns); > + if (newlim->d_fieldmask & QC_RT_SPC_TIMER) > + xfs_setqlim_timer(res, dres, newlim->d_rt_spc_timer); > + > + /* Inodes */ > hard = (newlim->d_fieldmask & QC_INO_HARD) ? > (xfs_qcnt_t) newlim->d_ino_hardlimit : > dqp->q_ino.hardlimit; > soft = (newlim->d_fieldmask & QC_INO_SOFT) ? > (xfs_qcnt_t) newlim->d_ino_softlimit : > dqp->q_ino.softlimit; > - if (hard == 0 || hard >= soft) { > - dqp->q_ino.hardlimit = hard; > - dqp->q_ino.softlimit = soft; > - if (id == 0) { > - defq->dfq_ino.hardlimit = hard; > - defq->dfq_ino.softlimit = soft; > - } > - } else { > - xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft); > - } > + res = &dqp->q_ino; > + dres = id == 0 ? &defq->dfq_ino : NULL; > > - /* > - * Update warnings counter(s) if requested > - */ > - if (newlim->d_fieldmask & QC_SPC_WARNS) > - dqp->q_blk.warnings = newlim->d_spc_warns; > + xfs_setqlim_limits(mp, res, dres, hard, soft, "ino"); > if (newlim->d_fieldmask & QC_INO_WARNS) > - dqp->q_ino.warnings = newlim->d_ino_warns; > - if (newlim->d_fieldmask & QC_RT_SPC_WARNS) > - dqp->q_rtb.warnings = newlim->d_rt_spc_warns; > - > - if (id == 0) { > - if (newlim->d_fieldmask & QC_SPC_WARNS) > - defq->dfq_blk.warnlimit = newlim->d_spc_warns; > - if (newlim->d_fieldmask & QC_INO_WARNS) > - defq->dfq_ino.warnlimit = newlim->d_ino_warns; > - if (newlim->d_fieldmask & QC_RT_SPC_WARNS) > - defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns; > - } > - > - /* > - * Timelimits for the super user set the relative time the other users > - * can be over quota for this file system. If it is zero a default is > - * used. Ditto for the default soft and hard limit values (already > - * done, above), and for warnings. > - * > - * For other IDs, userspace can bump out the grace period if over > - * the soft limit. > - */ > - if (newlim->d_fieldmask & QC_SPC_TIMER) > - dqp->q_blk.timer = newlim->d_spc_timer; > + xfs_setqlim_warns(res, dres, newlim->d_ino_warns); > if (newlim->d_fieldmask & QC_INO_TIMER) > - dqp->q_ino.timer = newlim->d_ino_timer; > - if (newlim->d_fieldmask & QC_RT_SPC_TIMER) > - dqp->q_rtb.timer = newlim->d_rt_spc_timer; > - > - if (id == 0) { > - if (newlim->d_fieldmask & QC_SPC_TIMER) > - defq->dfq_blk.timelimit = newlim->d_spc_timer; > - if (newlim->d_fieldmask & QC_INO_TIMER) > - defq->dfq_ino.timelimit = newlim->d_ino_timer; > - if (newlim->d_fieldmask & QC_RT_SPC_TIMER) > - defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer; > - } > + xfs_setqlim_timer(res, dres, newlim->d_ino_timer); > > if (id != 0) { > /* >
On 6/30/20 8:43 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Now that we've refactored the resource usage and limits into > per-resource structures, we can refactor some of the open-coded > reservation limit checking in xfs_trans_dqresv. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Ok, I followed it through, and I think it makes sense Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_trans_dquot.c | 153 +++++++++++++++++++++++----------------------- > 1 file changed, 78 insertions(+), 75 deletions(-) > > > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 2712814d696d..30a011dc9828 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -554,6 +554,58 @@ xfs_quota_warn( > mp->m_super->s_dev, type); > } > > +/* > + * Decide if we can make an additional reservation against a quota resource. > + * Returns an inode QUOTA_NL_ warning code and whether or not it's fatal. > + * > + * Note that we assume that the numeric difference between the inode and block > + * warning codes will always be 3 since it's userspace ABI now, and will never > + * decrease the quota reservation, so the *BELOW messages are irrelevant. > + */ > +static inline int > +xfs_dqresv_check( > + struct xfs_dquot_res *res, > + struct xfs_def_qres *dres, > + int64_t delta, > + bool *fatal) > +{ > + xfs_qcnt_t hardlimit = res->hardlimit; > + xfs_qcnt_t softlimit = res->softlimit; > + xfs_qcnt_t total_count = res->reserved + delta; > + > + BUILD_BUG_ON(QUOTA_NL_BHARDWARN != QUOTA_NL_IHARDWARN + 3); > + BUILD_BUG_ON(QUOTA_NL_BSOFTLONGWARN != QUOTA_NL_ISOFTLONGWARN + 3); > + BUILD_BUG_ON(QUOTA_NL_BSOFTWARN != QUOTA_NL_ISOFTWARN + 3); > + > + *fatal = false; > + if (delta <= 0) > + return QUOTA_NL_NOWARN; > + > + if (!hardlimit) > + hardlimit = dres->hardlimit; > + if (!softlimit) > + softlimit = dres->softlimit; > + > + if (hardlimit && total_count > hardlimit) { > + *fatal = true; > + return QUOTA_NL_IHARDWARN; > + } > + > + if (softlimit && total_count > softlimit) { > + time64_t now = ktime_get_real_seconds(); > + > + if ((res->timer != 0 && now > res->timer) || > + (res->warnings != 0 && res->warnings >= dres->warnlimit)) { > + *fatal = true; > + return QUOTA_NL_ISOFTLONGWARN; > + } > + > + return QUOTA_NL_ISOFTWARN; > + } > + > + return QUOTA_NL_NOWARN; > +} > + > /* > * This reserves disk blocks and inodes against a dquot. > * Flags indicate if the dquot is to be locked here and also > @@ -569,99 +621,51 @@ xfs_trans_dqresv( > long ninos, > uint flags) > { > - xfs_qcnt_t hardlimit; > - xfs_qcnt_t softlimit; > - time64_t timer; > - xfs_qwarncnt_t warns; > - xfs_qwarncnt_t warnlimit; > - xfs_qcnt_t total_count; > - xfs_qcnt_t *resbcountp; > struct xfs_quotainfo *q = mp->m_quotainfo; > struct xfs_def_quota *defq; > - > + struct xfs_dquot_res *blkres; > + struct xfs_def_qres *def_blkres; > > xfs_dqlock(dqp); > > defq = xfs_get_defquota(q, xfs_dquot_type(dqp)); > > if (flags & XFS_TRANS_DQ_RES_BLKS) { > - hardlimit = dqp->q_blk.hardlimit; > - if (!hardlimit) > - hardlimit = defq->dfq_blk.hardlimit; > - softlimit = dqp->q_blk.softlimit; > - if (!softlimit) > - softlimit = defq->dfq_blk.softlimit; > - timer = dqp->q_blk.timer; > - warns = dqp->q_blk.warnings; > - warnlimit = defq->dfq_blk.warnlimit; > - resbcountp = &dqp->q_blk.reserved; > + blkres = &dqp->q_blk; > + def_blkres = &defq->dfq_blk; > } else { > - ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); > - hardlimit = dqp->q_rtb.hardlimit; > - if (!hardlimit) > - hardlimit = defq->dfq_rtb.hardlimit; > - softlimit = dqp->q_rtb.softlimit; > - if (!softlimit) > - softlimit = defq->dfq_rtb.softlimit; > - timer = dqp->q_rtb.timer; > - warns = dqp->q_rtb.warnings; > - warnlimit = defq->dfq_rtb.warnlimit; > - resbcountp = &dqp->q_rtb.reserved; > + blkres = &dqp->q_rtb; > + def_blkres = &defq->dfq_rtb; > } > > if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_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) { > + int quota_nl; > + bool fatal; > + > + /* > + * dquot is locked already. See if we'd go over the hardlimit > + * or exceed the timelimit if we'd reserve resources. > + */ > + quota_nl = xfs_dqresv_check(blkres, def_blkres, nblks, &fatal); > + if (quota_nl != QUOTA_NL_NOWARN) { > /* > - * dquot is locked already. See if we'd go over the > - * hardlimit or exceed the timelimit if we allocate > - * nblks. > + * Quota block warning codes are 3 more than the inode > + * codes, which we check above. > */ > - total_count = *resbcountp + nblks; > - if (hardlimit && total_count > hardlimit) { > - xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN); > + xfs_quota_warn(mp, dqp, quota_nl + 3); > + if (fatal) > goto error_return; > - } > - if (softlimit && total_count > softlimit) { > - if ((timer != 0 && > - ktime_get_real_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 = dqp->q_ino.reserved + ninos; > - timer = dqp->q_ino.timer; > - warns = dqp->q_ino.warnings; > - warnlimit = defq->dfq_ino.warnlimit; > - hardlimit = dqp->q_ino.hardlimit; > - if (!hardlimit) > - hardlimit = defq->dfq_ino.hardlimit; > - softlimit = dqp->q_ino.softlimit; > - if (!softlimit) > - softlimit = defq->dfq_ino.softlimit; > > - if (hardlimit && total_count > hardlimit) { > - xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN); > + quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->dfq_ino, ninos, > + &fatal); > + if (quota_nl != QUOTA_NL_NOWARN) { > + xfs_quota_warn(mp, dqp, quota_nl); > + if (fatal) > goto error_return; > - } > - if (softlimit && total_count > softlimit) { > - if ((timer != 0 && > - ktime_get_real_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); > - } > } > } > > @@ -669,9 +673,8 @@ xfs_trans_dqresv( > * Change the reservation, but not the actual usage. > * Note that q_blk.reserved = q_blk.count + resv > */ > - (*resbcountp) += (xfs_qcnt_t)nblks; > - if (ninos != 0) > - dqp->q_ino.reserved += (xfs_qcnt_t)ninos; > + blkres->reserved += (xfs_qcnt_t)nblks; > + dqp->q_ino.reserved += (xfs_qcnt_t)ninos; > > /* > * note the reservation amt in the trans struct too, >
On Tuesday 30 June 2020 9:13:26 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Now that we can pass around quota resource and limit structures, clean > up the open-coded field setting in xfs_qm_scall_setqlim. > The changes are logically correct. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_qm_syscalls.c | 164 ++++++++++++++++++++++++++-------------------- > 1 file changed, 93 insertions(+), 71 deletions(-) > > > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 5423e02f9837..5044c333af5c 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -436,6 +436,58 @@ xfs_qm_scall_quotaon( > #define XFS_QC_MASK \ > (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK) > > +/* > + * Adjust limits of this quota, and the defaults if passed in. Returns true > + * if the new limits made sense and were applied, false otherwise. > + */ > +static inline bool > +xfs_setqlim_limits( > + struct xfs_mount *mp, > + struct xfs_dquot_res *res, > + struct xfs_def_qres *dres, > + xfs_qcnt_t hard, > + xfs_qcnt_t soft, > + const char *tag) > +{ > + /* The hard limit can't be less than the soft limit. */ > + if (hard != 0 && hard < soft) { > + xfs_debug(mp, "%shard %lld < %ssoft %lld", tag, hard, tag, > + soft); > + return false; > + } > + > + res->hardlimit = hard; > + res->softlimit = soft; > + if (dres) { > + dres->hardlimit = hard; > + dres->softlimit = soft; > + } > + > + return true; > +} > + > +static inline void > +xfs_setqlim_warns( > + struct xfs_dquot_res *res, > + struct xfs_def_qres *dres, > + int warns) > +{ > + res->warnings = warns; > + if (dres) > + dres->warnlimit = warns; > +} > + > +static inline void > +xfs_setqlim_timer( > + struct xfs_dquot_res *res, > + struct xfs_def_qres *dres, > + s64 timer) > +{ > + res->timer = timer; > + if (dres) > + dres->timelimit = timer; > +} > + > /* > * Adjust quota limits, and start/stop timers accordingly. > */ > @@ -450,6 +502,8 @@ xfs_qm_scall_setqlim( > struct xfs_dquot *dqp; > struct xfs_trans *tp; > struct xfs_def_quota *defq; > + struct xfs_dquot_res *res; > + struct xfs_def_qres *dres; > int error; > xfs_qcnt_t hard, soft; > > @@ -489,102 +543,70 @@ xfs_qm_scall_setqlim( > xfs_trans_dqjoin(tp, dqp); > > /* > + * Update quota limits, warnings, and timers, and the defaults > + * if we're touching id == 0. > + * > * Make sure that hardlimits are >= soft limits before changing. > + * > + * Update warnings counter(s) if requested. > + * > + * Timelimits for the super user set the relative time the other users > + * can be over quota for this file system. If it is zero a default is > + * used. Ditto for the default soft and hard limit values (already > + * done, above), and for warnings. > + * > + * For other IDs, userspace can bump out the grace period if over > + * the soft limit. > */ > + > + /* Blocks on the data device. */ > hard = (newlim->d_fieldmask & QC_SPC_HARD) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : > dqp->q_blk.hardlimit; > soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : > dqp->q_blk.softlimit; > - if (hard == 0 || hard >= soft) { > - dqp->q_blk.hardlimit = hard; > - dqp->q_blk.softlimit = soft; > + res = &dqp->q_blk; > + dres = id == 0 ? &defq->dfq_blk : NULL; > + > + if (xfs_setqlim_limits(mp, res, dres, hard, soft, "blk")) > xfs_dquot_set_prealloc_limits(dqp); > - if (id == 0) { > - defq->dfq_blk.hardlimit = hard; > - defq->dfq_blk.softlimit = soft; > - } > - } else { > - xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft); > - } > + if (newlim->d_fieldmask & QC_SPC_WARNS) > + xfs_setqlim_warns(res, dres, newlim->d_spc_warns); > + if (newlim->d_fieldmask & QC_SPC_TIMER) > + xfs_setqlim_timer(res, dres, newlim->d_spc_timer); > + > + /* Blocks on the realtime device. */ > hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : > dqp->q_rtb.hardlimit; > soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? > (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : > dqp->q_rtb.softlimit; > - if (hard == 0 || hard >= soft) { > - dqp->q_rtb.hardlimit = hard; > - dqp->q_rtb.softlimit = soft; > - if (id == 0) { > - defq->dfq_rtb.hardlimit = hard; > - defq->dfq_rtb.softlimit = soft; > - } > - } else { > - xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft); > - } > + res = &dqp->q_rtb; > + dres = id == 0 ? &defq->dfq_rtb : NULL; > > + xfs_setqlim_limits(mp, res, dres, hard, soft, "rtb"); > + if (newlim->d_fieldmask & QC_RT_SPC_WARNS) > + xfs_setqlim_warns(res, dres, newlim->d_rt_spc_warns); > + if (newlim->d_fieldmask & QC_RT_SPC_TIMER) > + xfs_setqlim_timer(res, dres, newlim->d_rt_spc_timer); > + > + /* Inodes */ > hard = (newlim->d_fieldmask & QC_INO_HARD) ? > (xfs_qcnt_t) newlim->d_ino_hardlimit : > dqp->q_ino.hardlimit; > soft = (newlim->d_fieldmask & QC_INO_SOFT) ? > (xfs_qcnt_t) newlim->d_ino_softlimit : > dqp->q_ino.softlimit; > - if (hard == 0 || hard >= soft) { > - dqp->q_ino.hardlimit = hard; > - dqp->q_ino.softlimit = soft; > - if (id == 0) { > - defq->dfq_ino.hardlimit = hard; > - defq->dfq_ino.softlimit = soft; > - } > - } else { > - xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft); > - } > + res = &dqp->q_ino; > + dres = id == 0 ? &defq->dfq_ino : NULL; > > - /* > - * Update warnings counter(s) if requested > - */ > - if (newlim->d_fieldmask & QC_SPC_WARNS) > - dqp->q_blk.warnings = newlim->d_spc_warns; > + xfs_setqlim_limits(mp, res, dres, hard, soft, "ino"); > if (newlim->d_fieldmask & QC_INO_WARNS) > - dqp->q_ino.warnings = newlim->d_ino_warns; > - if (newlim->d_fieldmask & QC_RT_SPC_WARNS) > - dqp->q_rtb.warnings = newlim->d_rt_spc_warns; > - > - if (id == 0) { > - if (newlim->d_fieldmask & QC_SPC_WARNS) > - defq->dfq_blk.warnlimit = newlim->d_spc_warns; > - if (newlim->d_fieldmask & QC_INO_WARNS) > - defq->dfq_ino.warnlimit = newlim->d_ino_warns; > - if (newlim->d_fieldmask & QC_RT_SPC_WARNS) > - defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns; > - } > - > - /* > - * Timelimits for the super user set the relative time the other users > - * can be over quota for this file system. If it is zero a default is > - * used. Ditto for the default soft and hard limit values (already > - * done, above), and for warnings. > - * > - * For other IDs, userspace can bump out the grace period if over > - * the soft limit. > - */ > - if (newlim->d_fieldmask & QC_SPC_TIMER) > - dqp->q_blk.timer = newlim->d_spc_timer; > + xfs_setqlim_warns(res, dres, newlim->d_ino_warns); > if (newlim->d_fieldmask & QC_INO_TIMER) > - dqp->q_ino.timer = newlim->d_ino_timer; > - if (newlim->d_fieldmask & QC_RT_SPC_TIMER) > - dqp->q_rtb.timer = newlim->d_rt_spc_timer; > - > - if (id == 0) { > - if (newlim->d_fieldmask & QC_SPC_TIMER) > - defq->dfq_blk.timelimit = newlim->d_spc_timer; > - if (newlim->d_fieldmask & QC_INO_TIMER) > - defq->dfq_ino.timelimit = newlim->d_ino_timer; > - if (newlim->d_fieldmask & QC_RT_SPC_TIMER) > - defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer; > - } > + xfs_setqlim_timer(res, dres, newlim->d_ino_timer); > > if (id != 0) { > /* > > -- chandan
On Tuesday 30 June 2020 9:13:32 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Now that we've refactored the resource usage and limits into > per-resource structures, we can refactor some of the open-coded > reservation limit checking in xfs_trans_dqresv. > The changes are consistent with the previous functionality. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_trans_dquot.c | 153 +++++++++++++++++++++++----------------------- > 1 file changed, 78 insertions(+), 75 deletions(-) > > > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 2712814d696d..30a011dc9828 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -554,6 +554,58 @@ xfs_quota_warn( > mp->m_super->s_dev, type); > } > > +/* > + * Decide if we can make an additional reservation against a quota resource. > + * Returns an inode QUOTA_NL_ warning code and whether or not it's fatal. > + * > + * Note that we assume that the numeric difference between the inode and block > + * warning codes will always be 3 since it's userspace ABI now, and will never > + * decrease the quota reservation, so the *BELOW messages are irrelevant. > + */ > +static inline int > +xfs_dqresv_check( > + struct xfs_dquot_res *res, > + struct xfs_def_qres *dres, > + int64_t delta, > + bool *fatal) > +{ > + xfs_qcnt_t hardlimit = res->hardlimit; > + xfs_qcnt_t softlimit = res->softlimit; > + xfs_qcnt_t total_count = res->reserved + delta; > + > + BUILD_BUG_ON(QUOTA_NL_BHARDWARN != QUOTA_NL_IHARDWARN + 3); > + BUILD_BUG_ON(QUOTA_NL_BSOFTLONGWARN != QUOTA_NL_ISOFTLONGWARN + 3); > + BUILD_BUG_ON(QUOTA_NL_BSOFTWARN != QUOTA_NL_ISOFTWARN + 3); > + > + *fatal = false; > + if (delta <= 0) > + return QUOTA_NL_NOWARN; > + > + if (!hardlimit) > + hardlimit = dres->hardlimit; > + if (!softlimit) > + softlimit = dres->softlimit; > + > + if (hardlimit && total_count > hardlimit) { > + *fatal = true; > + return QUOTA_NL_IHARDWARN; > + } > + > + if (softlimit && total_count > softlimit) { > + time64_t now = ktime_get_real_seconds(); > + > + if ((res->timer != 0 && now > res->timer) || > + (res->warnings != 0 && res->warnings >= dres->warnlimit)) { > + *fatal = true; > + return QUOTA_NL_ISOFTLONGWARN; > + } > + > + return QUOTA_NL_ISOFTWARN; > + } > + > + return QUOTA_NL_NOWARN; > +} > + > /* > * This reserves disk blocks and inodes against a dquot. > * Flags indicate if the dquot is to be locked here and also > @@ -569,99 +621,51 @@ xfs_trans_dqresv( > long ninos, > uint flags) > { > - xfs_qcnt_t hardlimit; > - xfs_qcnt_t softlimit; > - time64_t timer; > - xfs_qwarncnt_t warns; > - xfs_qwarncnt_t warnlimit; > - xfs_qcnt_t total_count; > - xfs_qcnt_t *resbcountp; > struct xfs_quotainfo *q = mp->m_quotainfo; > struct xfs_def_quota *defq; > - > + struct xfs_dquot_res *blkres; > + struct xfs_def_qres *def_blkres; > > xfs_dqlock(dqp); > > defq = xfs_get_defquota(q, xfs_dquot_type(dqp)); > > if (flags & XFS_TRANS_DQ_RES_BLKS) { > - hardlimit = dqp->q_blk.hardlimit; > - if (!hardlimit) > - hardlimit = defq->dfq_blk.hardlimit; > - softlimit = dqp->q_blk.softlimit; > - if (!softlimit) > - softlimit = defq->dfq_blk.softlimit; > - timer = dqp->q_blk.timer; > - warns = dqp->q_blk.warnings; > - warnlimit = defq->dfq_blk.warnlimit; > - resbcountp = &dqp->q_blk.reserved; > + blkres = &dqp->q_blk; > + def_blkres = &defq->dfq_blk; > } else { > - ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); > - hardlimit = dqp->q_rtb.hardlimit; > - if (!hardlimit) > - hardlimit = defq->dfq_rtb.hardlimit; > - softlimit = dqp->q_rtb.softlimit; > - if (!softlimit) > - softlimit = defq->dfq_rtb.softlimit; > - timer = dqp->q_rtb.timer; > - warns = dqp->q_rtb.warnings; > - warnlimit = defq->dfq_rtb.warnlimit; > - resbcountp = &dqp->q_rtb.reserved; > + blkres = &dqp->q_rtb; > + def_blkres = &defq->dfq_rtb; > } > > if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_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) { > + int quota_nl; > + bool fatal; > + > + /* > + * dquot is locked already. See if we'd go over the hardlimit > + * or exceed the timelimit if we'd reserve resources. > + */ > + quota_nl = xfs_dqresv_check(blkres, def_blkres, nblks, &fatal); > + if (quota_nl != QUOTA_NL_NOWARN) { > /* > - * dquot is locked already. See if we'd go over the > - * hardlimit or exceed the timelimit if we allocate > - * nblks. > + * Quota block warning codes are 3 more than the inode > + * codes, which we check above. > */ > - total_count = *resbcountp + nblks; > - if (hardlimit && total_count > hardlimit) { > - xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN); > + xfs_quota_warn(mp, dqp, quota_nl + 3); > + if (fatal) > goto error_return; > - } > - if (softlimit && total_count > softlimit) { > - if ((timer != 0 && > - ktime_get_real_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 = dqp->q_ino.reserved + ninos; > - timer = dqp->q_ino.timer; > - warns = dqp->q_ino.warnings; > - warnlimit = defq->dfq_ino.warnlimit; > - hardlimit = dqp->q_ino.hardlimit; > - if (!hardlimit) > - hardlimit = defq->dfq_ino.hardlimit; > - softlimit = dqp->q_ino.softlimit; > - if (!softlimit) > - softlimit = defq->dfq_ino.softlimit; > > - if (hardlimit && total_count > hardlimit) { > - xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN); > + quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->dfq_ino, ninos, > + &fatal); > + if (quota_nl != QUOTA_NL_NOWARN) { > + xfs_quota_warn(mp, dqp, quota_nl); > + if (fatal) > goto error_return; > - } > - if (softlimit && total_count > softlimit) { > - if ((timer != 0 && > - ktime_get_real_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); > - } > } > } > > @@ -669,9 +673,8 @@ xfs_trans_dqresv( > * Change the reservation, but not the actual usage. > * Note that q_blk.reserved = q_blk.count + resv > */ > - (*resbcountp) += (xfs_qcnt_t)nblks; > - if (ninos != 0) > - dqp->q_ino.reserved += (xfs_qcnt_t)ninos; > + blkres->reserved += (xfs_qcnt_t)nblks; > + dqp->q_ino.reserved += (xfs_qcnt_t)ninos; > > /* > * note the reservation amt in the trans struct too, > > -- chandan
On Fri, Jul 03, 2020 at 10:58:50AM +1000, Dave Chinner wrote: > On Wed, Jul 01, 2020 at 04:50:31PM -0700, Darrick J. Wong wrote: > > On Thu, Jul 02, 2020 at 09:44:35AM +1000, Dave Chinner wrote: > > > On Wed, Jul 01, 2020 at 04:19:10PM -0700, Darrick J. Wong wrote: > > > > On Thu, Jul 02, 2020 at 08:50:53AM +1000, Dave Chinner wrote: > > > > > On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote: > > > > > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > > > > > > > > > Use the incore dq_flags to figure out the dquot type. This is the first > > > > > > step towards removing xfs_disk_dquot from the incore dquot. > > > > > > > > > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > > > > > > --- > > > > > > fs/xfs/libxfs/xfs_quota_defs.h | 2 ++ > > > > > > fs/xfs/scrub/quota.c | 4 ---- > > > > > > fs/xfs/xfs_dquot.c | 33 +++++++++++++++++++++++++++++++-- > > > > > > fs/xfs/xfs_dquot.h | 2 ++ > > > > > > fs/xfs/xfs_dquot_item.c | 6 ++++-- > > > > > > fs/xfs/xfs_qm.c | 4 ++-- > > > > > > fs/xfs/xfs_qm.h | 2 +- > > > > > > fs/xfs/xfs_qm_syscalls.c | 9 +++------ > > > > > > 8 files changed, 45 insertions(+), 17 deletions(-) > > > > > > > > > > > > > > > > > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h > > > > > > index 56d9dd787e7b..459023b0a304 100644 > > > > > > --- a/fs/xfs/libxfs/xfs_quota_defs.h > > > > > > +++ b/fs/xfs/libxfs/xfs_quota_defs.h > > > > > > @@ -29,6 +29,8 @@ typedef uint16_t xfs_qwarncnt_t; > > > > > > > > > > > > #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) > > > > > > > > > > > > +#define XFS_DQ_ONDISK (XFS_DQ_ALLTYPES) > > > > > > > > > > That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK? > > > > > > > > Well, based on Christoph's suggestions I broke the incore dquot flags > > > > (XFS_DQ_*) apart from the ondisk dquot flags (XFS_DQFLAG_*). Not sure > > > > if that's really better, but at least the namespaces are separate now. > > > > > > Sure, but the point I was trying to make is that "XFS_DQ_ONDISK" > > > doesn't actually indicate what part of the on-disk dquot it refers > > > to. We use the phrase "on-disk dquot" to refer to the entire on-disk > > > dquot, not a subset of flags in a flags field in the on-disk > > > dquot. Hence the name of this variable needs to be more specific as > > > to what it applies to in the on-disk dquot... > > > > Sorry, I was typing too fast. xfs_format.h now has: > > > > #define XFS_DQFLAG_USER 0x01 /* user dquot record */ > > #define XFS_DQFLAG_PROJ 0x02 /* project dquot record */ > > #define XFS_DQFLAG_GROUP 0x04 /* group dquot record */ > > > > #define XFS_DQFLAG_TYPE_MASK (XFS_DQFLAG_USER | \ > > XFS_DQFLAG_PROJ | \ > > XFS_DQFLAG_GROUP) > > > > #define XFS_DQFLAG_ALL (XFS_DQFLAG_TYPE_MASK) > > > > /* > > * This is the main portion of the on-disk representation of quota > > * information for a user. This is the q_core of the struct xfs_dquot > > * that is kept in kernel memory. We pad this with some more expansion > > * room to construct the on disk structure. > > */ > > struct xfs_disk_dquot { > > __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */ > > __u8 d_version; /* dquot version */ > > __u8 d_flags; /* XFS_DQFLAG_* */ > > > > I'm not particularly thrilled about the DQFLAG/DQ thing though. DDFLAG? > > (Also note that the future bigtime series will add a new ondisk flag > > XFS_DQFLAG_BIGTIME, which ofc will get added to XFS_DQFLAG_ALL.) > > /me shrugs > > I don't have any good ideas, but I think that DQFLAG is a bad choice > for an on-disk flag namespace because it's way too generic. It's > more a type/feature indicator so perhaps we should rename d_flags to > d_type or d_features and use: > > #define XFS_DDQTYPE_USER > #define XFS_DDQTYPE_PROJ > #define XFS_DDQTYPE_GROUP > #define XFS_DDQTYPE_BIGTIME > > #define XFS_DDQTYPE_QUOTA_MASK (XFS_DDQTYPE_USER | ... > > #define XFS_DDQTYPE_ALL (XFS_DDQTYPE_QUOTA_MASK | XFS_DDQTYPE_BIGTIME) > > Or something like that... I prefer d_features/DDQFEAT over d_type/DDQTYPE because I don't want people to mix up "ondisk dquot type (user/group/proj/bigtime)" with "quota type (user/group/proj)". --D > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com
On 6/30/20 8:43 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Hoist the code that adjusts the incore quota reservation count > adjustments into a separate function, both to reduce the level of > indentation and also to reduce the amount of open-coded logic. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Ok, it's a bit of a hoist and a simplification, but I think it's a good clean up. Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_trans_dquot.c | 103 +++++++++++++++++++++------------------------- > 1 file changed, 46 insertions(+), 57 deletions(-) > > > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 30a011dc9828..701923ea6c04 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -293,6 +293,37 @@ xfs_trans_dqlockedjoin( > } > } > > +/* Apply dqtrx changes to the quota reservation counters. */ > +static inline void > +xfs_apply_quota_reservation_deltas( > + struct xfs_dquot_res *res, > + uint64_t reserved, > + int64_t res_used, > + int64_t count_delta) > +{ > + if (reserved != 0) { > + /* > + * Subtle math here: If reserved > res_used (the normal case), > + * we're simply subtracting the unused transaction quota > + * reservation from the dquot reservation. > + * > + * If, however, res_used > reserved, then we have allocated > + * more quota blocks than were reserved for the transaction. > + * We must add that excess to the dquot reservation since it > + * tracks (usage + resv) and by definition we didn't reserve > + * that excess. > + */ > + res->reserved -= abs(reserved - res_used); > + } else if (count_delta != 0) { > + /* > + * These blks were never reserved, either inside a transaction > + * or outside one (in a delayed allocation). Also, this isn't > + * always a negative number since we sometimes deliberately > + * skip quota reservations. > + */ > + res->reserved += count_delta; > + } > +} > > /* > * Called by xfs_trans_commit() and similar in spirit to > @@ -327,6 +358,8 @@ xfs_trans_apply_dquot_deltas( > xfs_trans_dqlockedjoin(tp, qa); > > for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) { > + uint64_t blk_res_used; > + > qtrx = &qa[i]; > /* > * The array of dquots is filled > @@ -396,71 +429,27 @@ xfs_trans_apply_dquot_deltas( > * In case of delayed allocations, there's no > * reservation that a transaction structure knows of. > */ > - if (qtrx->qt_blk_res != 0) { > - uint64_t blk_res_used = 0; > + blk_res_used = max_t(int64_t, 0, qtrx->qt_bcount_delta); > + xfs_apply_quota_reservation_deltas(&dqp->q_blk, > + qtrx->qt_blk_res, blk_res_used, > + qtrx->qt_bcount_delta); > > - if (qtrx->qt_bcount_delta > 0) > - blk_res_used = qtrx->qt_bcount_delta; > - > - if (qtrx->qt_blk_res != blk_res_used) { > - if (qtrx->qt_blk_res > blk_res_used) > - dqp->q_blk.reserved -= (xfs_qcnt_t) > - (qtrx->qt_blk_res - > - blk_res_used); > - else > - dqp->q_blk.reserved -= (xfs_qcnt_t) > - (blk_res_used - > - qtrx->qt_blk_res); > - } > - } else { > - /* > - * These blks were never reserved, either inside > - * a transaction or outside one (in a delayed > - * allocation). Also, this isn't always a > - * negative number since we sometimes > - * deliberately skip quota reservations. > - */ > - if (qtrx->qt_bcount_delta) { > - dqp->q_blk.reserved += > - (xfs_qcnt_t)qtrx->qt_bcount_delta; > - } > - } > /* > * Adjust the RT reservation. > */ > - if (qtrx->qt_rtblk_res != 0) { > - if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) { > - if (qtrx->qt_rtblk_res > > - qtrx->qt_rtblk_res_used) > - dqp->q_rtb.reserved -= (xfs_qcnt_t) > - (qtrx->qt_rtblk_res - > - qtrx->qt_rtblk_res_used); > - else > - dqp->q_rtb.reserved -= (xfs_qcnt_t) > - (qtrx->qt_rtblk_res_used - > - qtrx->qt_rtblk_res); > - } > - } else { > - if (qtrx->qt_rtbcount_delta) > - dqp->q_rtb.reserved += > - (xfs_qcnt_t)qtrx->qt_rtbcount_delta; > - } > + xfs_apply_quota_reservation_deltas(&dqp->q_rtb, > + qtrx->qt_rtblk_res, > + qtrx->qt_rtblk_res_used, > + qtrx->qt_rtbcount_delta); > > /* > * Adjust the inode reservation. > */ > - if (qtrx->qt_ino_res != 0) { > - ASSERT(qtrx->qt_ino_res >= > - qtrx->qt_ino_res_used); > - if (qtrx->qt_ino_res > qtrx->qt_ino_res_used) > - dqp->q_ino.reserved -= (xfs_qcnt_t) > - (qtrx->qt_ino_res - > - qtrx->qt_ino_res_used); > - } else { > - if (qtrx->qt_icount_delta) > - dqp->q_ino.reserved += > - (xfs_qcnt_t)qtrx->qt_icount_delta; > - } > + ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used); > + xfs_apply_quota_reservation_deltas(&dqp->q_ino, > + qtrx->qt_ino_res, > + qtrx->qt_ino_res_used, > + qtrx->qt_icount_delta); > > ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count); > ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count); >
On 6/30/20 8:43 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Add all the xfs_dquot fields to the tracepoint for that type; add a new > tracepoint type for the qtrx structure (dquot transaction deltas); and > use our new tracepoints. This makes it easier for the author to trace > changes to dquot counters for debugging. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Alrighty, seems helpful Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/xfs_trace.h | 140 +++++++++++++++++++++++++++++++++++++++++++++- > fs/xfs/xfs_trans_dquot.c | 21 +++++++ > 2 files changed, 159 insertions(+), 2 deletions(-) > > > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 851f97dfe9e3..35b9dfd3984f 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -36,6 +36,7 @@ struct xfs_owner_info; > struct xfs_trans_res; > struct xfs_inobt_rec_incore; > union xfs_btree_ptr; > +struct xfs_dqtrx; > > #define XFS_ATTR_FILTER_FLAGS \ > { XFS_ATTR_ROOT, "ROOT" }, \ > @@ -867,37 +868,59 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, > __field(unsigned, flags) > __field(unsigned, nrefs) > __field(unsigned long long, res_bcount) > + __field(unsigned long long, res_rtbcount) > + __field(unsigned long long, res_icount) > + > __field(unsigned long long, bcount) > + __field(unsigned long long, rtbcount) > __field(unsigned long long, icount) > + > __field(unsigned long long, blk_hardlimit) > __field(unsigned long long, blk_softlimit) > + __field(unsigned long long, rtb_hardlimit) > + __field(unsigned long long, rtb_softlimit) > __field(unsigned long long, ino_hardlimit) > __field(unsigned long long, ino_softlimit) > - ), \ > + ), > TP_fast_assign( > __entry->dev = dqp->q_mount->m_super->s_dev; > __entry->id = dqp->q_id; > __entry->flags = dqp->dq_flags; > __entry->nrefs = dqp->q_nrefs; > + > __entry->res_bcount = dqp->q_blk.reserved; > + __entry->res_rtbcount = dqp->q_rtb.reserved; > + __entry->res_icount = dqp->q_ino.reserved; > + > __entry->bcount = dqp->q_blk.count; > + __entry->rtbcount = dqp->q_rtb.count; > __entry->icount = dqp->q_ino.count; > + > __entry->blk_hardlimit = dqp->q_blk.hardlimit; > __entry->blk_softlimit = dqp->q_blk.softlimit; > + __entry->rtb_hardlimit = dqp->q_rtb.hardlimit; > + __entry->rtb_softlimit = dqp->q_rtb.softlimit; > __entry->ino_hardlimit = dqp->q_ino.hardlimit; > __entry->ino_softlimit = dqp->q_ino.softlimit; > ), > - TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx " > + TP_printk("dev %d:%d id 0x%x flags %s nrefs %u " > + "res_bc 0x%llx res_rtbc 0x%llx res_ic 0x%llx " > "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx " > + "rtbcnt 0x%llx rtbhardlimit 0x%llx rtbsoftlimit 0x%llx " > "icnt 0x%llx ihardlimit 0x%llx isoftlimit 0x%llx]", > MAJOR(__entry->dev), MINOR(__entry->dev), > __entry->id, > __print_flags(__entry->flags, "|", XFS_DQ_FLAGS), > __entry->nrefs, > __entry->res_bcount, > + __entry->res_rtbcount, > + __entry->res_icount, > __entry->bcount, > __entry->blk_hardlimit, > __entry->blk_softlimit, > + __entry->rtbcount, > + __entry->rtb_hardlimit, > + __entry->rtb_softlimit, > __entry->icount, > __entry->ino_hardlimit, > __entry->ino_softlimit) > @@ -928,6 +951,119 @@ DEFINE_DQUOT_EVENT(xfs_dqrele); > DEFINE_DQUOT_EVENT(xfs_dqflush); > DEFINE_DQUOT_EVENT(xfs_dqflush_force); > DEFINE_DQUOT_EVENT(xfs_dqflush_done); > +DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_before); > +DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_after); > + > +#define XFS_QMOPT_FLAGS \ > + { XFS_QMOPT_UQUOTA, "UQUOTA" }, \ > + { XFS_QMOPT_PQUOTA, "PQUOTA" }, \ > + { XFS_QMOPT_FORCE_RES, "FORCE_RES" }, \ > + { XFS_QMOPT_SBVERSION, "SBVERSION" }, \ > + { XFS_QMOPT_GQUOTA, "GQUOTA" }, \ > + { XFS_QMOPT_INHERIT, "INHERIT" }, \ > + { XFS_QMOPT_RES_REGBLKS, "RES_REGBLKS" }, \ > + { XFS_QMOPT_RES_RTBLKS, "RES_RTBLKS" }, \ > + { XFS_QMOPT_BCOUNT, "BCOUNT" }, \ > + { XFS_QMOPT_ICOUNT, "ICOUNT" }, \ > + { XFS_QMOPT_RTBCOUNT, "RTBCOUNT" }, \ > + { XFS_QMOPT_DELBCOUNT, "DELBCOUNT" }, \ > + { XFS_QMOPT_DELRTBCOUNT, "DELRTBCOUNT" }, \ > + { XFS_QMOPT_RES_INOS, "RES_INOS" } > + > +TRACE_EVENT(xfs_trans_mod_dquot, > + TP_PROTO(struct xfs_trans *tp, struct xfs_dquot *dqp, > + unsigned int field, int64_t delta), > + TP_ARGS(tp, dqp, field, delta), > + TP_STRUCT__entry( > + __field(dev_t, dev) > + __field(unsigned int, dqflags) > + __field(unsigned int, dqid) > + __field(unsigned int, field) > + __field(int64_t, delta) > + ), > + TP_fast_assign( > + __entry->dev = tp->t_mountp->m_super->s_dev; > + __entry->dqflags = dqp->dq_flags; > + __entry->dqid = dqp->q_id; > + __entry->field = field; > + __entry->delta = delta; > + ), > + TP_printk("dev %d:%d dquot %s id 0x%x %s delta %lld", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS), > + __entry->dqid, > + __print_flags(__entry->field, "|", XFS_QMOPT_FLAGS), > + __entry->delta) > +); > + > +DECLARE_EVENT_CLASS(xfs_dqtrx_class, > + TP_PROTO(struct xfs_dqtrx *qtrx), > + TP_ARGS(qtrx), > + TP_STRUCT__entry( > + __field(dev_t, dev) > + __field(unsigned int, dqflags) > + __field(u32, dqid) > + > + __field(uint64_t, blk_res) > + __field(int64_t, bcount_delta) > + __field(int64_t, delbcnt_delta) > + > + __field(uint64_t, rtblk_res) > + __field(uint64_t, rtblk_res_used) > + __field(int64_t, rtbcount_delta) > + __field(int64_t, delrtb_delta) > + > + __field(uint64_t, ino_res) > + __field(uint64_t, ino_res_used) > + __field(int64_t, icount_delta) > + ), > + TP_fast_assign( > + __entry->dev = qtrx->qt_dquot->q_mount->m_super->s_dev; > + __entry->dqflags = qtrx->qt_dquot->dq_flags; > + __entry->dqid = qtrx->qt_dquot->q_id; > + > + __entry->blk_res = qtrx->qt_blk_res; > + __entry->bcount_delta = qtrx->qt_bcount_delta; > + __entry->delbcnt_delta = qtrx->qt_delbcnt_delta; > + > + __entry->rtblk_res = qtrx->qt_rtblk_res; > + __entry->rtblk_res_used = qtrx->qt_rtblk_res_used; > + __entry->rtbcount_delta = qtrx->qt_rtbcount_delta; > + __entry->delrtb_delta = qtrx->qt_delrtb_delta; > + > + __entry->ino_res = qtrx->qt_ino_res; > + __entry->ino_res_used = qtrx->qt_ino_res_used; > + __entry->icount_delta = qtrx->qt_icount_delta; > + ), > + TP_printk("dev %d:%d dquot %s id 0x%x " > + "blk_res %llu bcount_delta %lld delbcnt_delta %lld " > + "rtblk_res %llu rtblk_res_used %llu rtbcount_delta %lld delrtb_delta %lld " > + "ino_res %llu ino_res_used %llu icount_delta %lld", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS), > + __entry->dqid, > + > + __entry->blk_res, > + __entry->bcount_delta, > + __entry->delbcnt_delta, > + > + __entry->rtblk_res, > + __entry->rtblk_res_used, > + __entry->rtbcount_delta, > + __entry->delrtb_delta, > + > + __entry->ino_res, > + __entry->ino_res_used, > + __entry->icount_delta) > +) > + > +#define DEFINE_DQTRX_EVENT(name) \ > +DEFINE_EVENT(xfs_dqtrx_class, name, \ > + TP_PROTO(struct xfs_dqtrx *qtrx), \ > + TP_ARGS(qtrx)) > +DEFINE_DQTRX_EVENT(xfs_trans_apply_dquot_deltas); > +DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_before); > +DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_after); > > DECLARE_EVENT_CLASS(xfs_loggrant_class, > TP_PROTO(struct xlog *log, struct xlog_ticket *tic), > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 701923ea6c04..5689d9f1b748 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -15,6 +15,7 @@ > #include "xfs_trans_priv.h" > #include "xfs_quota.h" > #include "xfs_qm.h" > +#include "xfs_trace.h" > > STATIC void xfs_trans_alloc_dqinfo(xfs_trans_t *); > > @@ -203,6 +204,11 @@ xfs_trans_mod_dquot( > if (qtrx->qt_dquot == NULL) > qtrx->qt_dquot = dqp; > > + if (delta) { > + trace_xfs_trans_mod_dquot_before(qtrx); > + trace_xfs_trans_mod_dquot(tp, dqp, field, delta); > + } > + > switch (field) { > > /* > @@ -266,6 +272,10 @@ xfs_trans_mod_dquot( > default: > ASSERT(0); > } > + > + if (delta) > + trace_xfs_trans_mod_dquot_after(qtrx); > + > tp->t_flags |= XFS_TRANS_DQ_DIRTY; > } > > @@ -391,6 +401,13 @@ xfs_trans_apply_dquot_deltas( > qtrx->qt_delbcnt_delta; > totalrtbdelta = qtrx->qt_rtbcount_delta + > qtrx->qt_delrtb_delta; > + > + if (totalbdelta != 0 || totalrtbdelta != 0 || > + qtrx->qt_icount_delta != 0) { > + trace_xfs_trans_apply_dquot_deltas_before(dqp); > + trace_xfs_trans_apply_dquot_deltas(qtrx); > + } > + > #ifdef DEBUG > if (totalbdelta < 0) > ASSERT(dqp->q_blk.count >= -totalbdelta); > @@ -410,6 +427,10 @@ xfs_trans_apply_dquot_deltas( > if (totalrtbdelta) > dqp->q_rtb.count += totalrtbdelta; > > + if (totalbdelta != 0 || totalrtbdelta != 0 || > + qtrx->qt_icount_delta != 0) > + trace_xfs_trans_apply_dquot_deltas_after(dqp); > + > /* > * Get any default limits in use. > * Start/reset the timer(s) if needed. >
On Tuesday 30 June 2020 9:13:38 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Hoist the code that adjusts the incore quota reservation count > adjustments into a separate function, both to reduce the level of > indentation and also to reduce the amount of open-coded logic. > The changes are logically consistent with the previous behaviour. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_trans_dquot.c | 103 +++++++++++++++++++++------------------------- > 1 file changed, 46 insertions(+), 57 deletions(-) > > > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 30a011dc9828..701923ea6c04 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -293,6 +293,37 @@ xfs_trans_dqlockedjoin( > } > } > > +/* Apply dqtrx changes to the quota reservation counters. */ > +static inline void > +xfs_apply_quota_reservation_deltas( > + struct xfs_dquot_res *res, > + uint64_t reserved, > + int64_t res_used, > + int64_t count_delta) > +{ > + if (reserved != 0) { > + /* > + * Subtle math here: If reserved > res_used (the normal case), > + * we're simply subtracting the unused transaction quota > + * reservation from the dquot reservation. > + * > + * If, however, res_used > reserved, then we have allocated > + * more quota blocks than were reserved for the transaction. > + * We must add that excess to the dquot reservation since it > + * tracks (usage + resv) and by definition we didn't reserve > + * that excess. > + */ > + res->reserved -= abs(reserved - res_used); > + } else if (count_delta != 0) { > + /* > + * These blks were never reserved, either inside a transaction > + * or outside one (in a delayed allocation). Also, this isn't > + * always a negative number since we sometimes deliberately > + * skip quota reservations. > + */ > + res->reserved += count_delta; > + } > +} > > /* > * Called by xfs_trans_commit() and similar in spirit to > @@ -327,6 +358,8 @@ xfs_trans_apply_dquot_deltas( > xfs_trans_dqlockedjoin(tp, qa); > > for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) { > + uint64_t blk_res_used; > + > qtrx = &qa[i]; > /* > * The array of dquots is filled > @@ -396,71 +429,27 @@ xfs_trans_apply_dquot_deltas( > * In case of delayed allocations, there's no > * reservation that a transaction structure knows of. > */ > - if (qtrx->qt_blk_res != 0) { > - uint64_t blk_res_used = 0; > + blk_res_used = max_t(int64_t, 0, qtrx->qt_bcount_delta); > + xfs_apply_quota_reservation_deltas(&dqp->q_blk, > + qtrx->qt_blk_res, blk_res_used, > + qtrx->qt_bcount_delta); > > - if (qtrx->qt_bcount_delta > 0) > - blk_res_used = qtrx->qt_bcount_delta; > - > - if (qtrx->qt_blk_res != blk_res_used) { > - if (qtrx->qt_blk_res > blk_res_used) > - dqp->q_blk.reserved -= (xfs_qcnt_t) > - (qtrx->qt_blk_res - > - blk_res_used); > - else > - dqp->q_blk.reserved -= (xfs_qcnt_t) > - (blk_res_used - > - qtrx->qt_blk_res); > - } > - } else { > - /* > - * These blks were never reserved, either inside > - * a transaction or outside one (in a delayed > - * allocation). Also, this isn't always a > - * negative number since we sometimes > - * deliberately skip quota reservations. > - */ > - if (qtrx->qt_bcount_delta) { > - dqp->q_blk.reserved += > - (xfs_qcnt_t)qtrx->qt_bcount_delta; > - } > - } > /* > * Adjust the RT reservation. > */ > - if (qtrx->qt_rtblk_res != 0) { > - if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) { > - if (qtrx->qt_rtblk_res > > - qtrx->qt_rtblk_res_used) > - dqp->q_rtb.reserved -= (xfs_qcnt_t) > - (qtrx->qt_rtblk_res - > - qtrx->qt_rtblk_res_used); > - else > - dqp->q_rtb.reserved -= (xfs_qcnt_t) > - (qtrx->qt_rtblk_res_used - > - qtrx->qt_rtblk_res); > - } > - } else { > - if (qtrx->qt_rtbcount_delta) > - dqp->q_rtb.reserved += > - (xfs_qcnt_t)qtrx->qt_rtbcount_delta; > - } > + xfs_apply_quota_reservation_deltas(&dqp->q_rtb, > + qtrx->qt_rtblk_res, > + qtrx->qt_rtblk_res_used, > + qtrx->qt_rtbcount_delta); > > /* > * Adjust the inode reservation. > */ > - if (qtrx->qt_ino_res != 0) { > - ASSERT(qtrx->qt_ino_res >= > - qtrx->qt_ino_res_used); > - if (qtrx->qt_ino_res > qtrx->qt_ino_res_used) > - dqp->q_ino.reserved -= (xfs_qcnt_t) > - (qtrx->qt_ino_res - > - qtrx->qt_ino_res_used); > - } else { > - if (qtrx->qt_icount_delta) > - dqp->q_ino.reserved += > - (xfs_qcnt_t)qtrx->qt_icount_delta; > - } > + ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used); > + xfs_apply_quota_reservation_deltas(&dqp->q_ino, > + qtrx->qt_ino_res, > + qtrx->qt_ino_res_used, > + qtrx->qt_icount_delta); > > ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count); > ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count); > > -- chandan
On Tuesday 30 June 2020 9:13:45 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Add all the xfs_dquot fields to the tracepoint for that type; add a new > tracepoint type for the qtrx structure (dquot transaction deltas); and > use our new tracepoints. This makes it easier for the author to trace > changes to dquot counters for debugging. > The changes look good to me. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/xfs/xfs_trace.h | 140 +++++++++++++++++++++++++++++++++++++++++++++- > fs/xfs/xfs_trans_dquot.c | 21 +++++++ > 2 files changed, 159 insertions(+), 2 deletions(-) > > > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 851f97dfe9e3..35b9dfd3984f 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -36,6 +36,7 @@ struct xfs_owner_info; > struct xfs_trans_res; > struct xfs_inobt_rec_incore; > union xfs_btree_ptr; > +struct xfs_dqtrx; > > #define XFS_ATTR_FILTER_FLAGS \ > { XFS_ATTR_ROOT, "ROOT" }, \ > @@ -867,37 +868,59 @@ DECLARE_EVENT_CLASS(xfs_dquot_class, > __field(unsigned, flags) > __field(unsigned, nrefs) > __field(unsigned long long, res_bcount) > + __field(unsigned long long, res_rtbcount) > + __field(unsigned long long, res_icount) > + > __field(unsigned long long, bcount) > + __field(unsigned long long, rtbcount) > __field(unsigned long long, icount) > + > __field(unsigned long long, blk_hardlimit) > __field(unsigned long long, blk_softlimit) > + __field(unsigned long long, rtb_hardlimit) > + __field(unsigned long long, rtb_softlimit) > __field(unsigned long long, ino_hardlimit) > __field(unsigned long long, ino_softlimit) > - ), \ > + ), > TP_fast_assign( > __entry->dev = dqp->q_mount->m_super->s_dev; > __entry->id = dqp->q_id; > __entry->flags = dqp->dq_flags; > __entry->nrefs = dqp->q_nrefs; > + > __entry->res_bcount = dqp->q_blk.reserved; > + __entry->res_rtbcount = dqp->q_rtb.reserved; > + __entry->res_icount = dqp->q_ino.reserved; > + > __entry->bcount = dqp->q_blk.count; > + __entry->rtbcount = dqp->q_rtb.count; > __entry->icount = dqp->q_ino.count; > + > __entry->blk_hardlimit = dqp->q_blk.hardlimit; > __entry->blk_softlimit = dqp->q_blk.softlimit; > + __entry->rtb_hardlimit = dqp->q_rtb.hardlimit; > + __entry->rtb_softlimit = dqp->q_rtb.softlimit; > __entry->ino_hardlimit = dqp->q_ino.hardlimit; > __entry->ino_softlimit = dqp->q_ino.softlimit; > ), > - TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx " > + TP_printk("dev %d:%d id 0x%x flags %s nrefs %u " > + "res_bc 0x%llx res_rtbc 0x%llx res_ic 0x%llx " > "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx " > + "rtbcnt 0x%llx rtbhardlimit 0x%llx rtbsoftlimit 0x%llx " > "icnt 0x%llx ihardlimit 0x%llx isoftlimit 0x%llx]", > MAJOR(__entry->dev), MINOR(__entry->dev), > __entry->id, > __print_flags(__entry->flags, "|", XFS_DQ_FLAGS), > __entry->nrefs, > __entry->res_bcount, > + __entry->res_rtbcount, > + __entry->res_icount, > __entry->bcount, > __entry->blk_hardlimit, > __entry->blk_softlimit, > + __entry->rtbcount, > + __entry->rtb_hardlimit, > + __entry->rtb_softlimit, > __entry->icount, > __entry->ino_hardlimit, > __entry->ino_softlimit) > @@ -928,6 +951,119 @@ DEFINE_DQUOT_EVENT(xfs_dqrele); > DEFINE_DQUOT_EVENT(xfs_dqflush); > DEFINE_DQUOT_EVENT(xfs_dqflush_force); > DEFINE_DQUOT_EVENT(xfs_dqflush_done); > +DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_before); > +DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_after); > + > +#define XFS_QMOPT_FLAGS \ > + { XFS_QMOPT_UQUOTA, "UQUOTA" }, \ > + { XFS_QMOPT_PQUOTA, "PQUOTA" }, \ > + { XFS_QMOPT_FORCE_RES, "FORCE_RES" }, \ > + { XFS_QMOPT_SBVERSION, "SBVERSION" }, \ > + { XFS_QMOPT_GQUOTA, "GQUOTA" }, \ > + { XFS_QMOPT_INHERIT, "INHERIT" }, \ > + { XFS_QMOPT_RES_REGBLKS, "RES_REGBLKS" }, \ > + { XFS_QMOPT_RES_RTBLKS, "RES_RTBLKS" }, \ > + { XFS_QMOPT_BCOUNT, "BCOUNT" }, \ > + { XFS_QMOPT_ICOUNT, "ICOUNT" }, \ > + { XFS_QMOPT_RTBCOUNT, "RTBCOUNT" }, \ > + { XFS_QMOPT_DELBCOUNT, "DELBCOUNT" }, \ > + { XFS_QMOPT_DELRTBCOUNT, "DELRTBCOUNT" }, \ > + { XFS_QMOPT_RES_INOS, "RES_INOS" } > + > +TRACE_EVENT(xfs_trans_mod_dquot, > + TP_PROTO(struct xfs_trans *tp, struct xfs_dquot *dqp, > + unsigned int field, int64_t delta), > + TP_ARGS(tp, dqp, field, delta), > + TP_STRUCT__entry( > + __field(dev_t, dev) > + __field(unsigned int, dqflags) > + __field(unsigned int, dqid) > + __field(unsigned int, field) > + __field(int64_t, delta) > + ), > + TP_fast_assign( > + __entry->dev = tp->t_mountp->m_super->s_dev; > + __entry->dqflags = dqp->dq_flags; > + __entry->dqid = dqp->q_id; > + __entry->field = field; > + __entry->delta = delta; > + ), > + TP_printk("dev %d:%d dquot %s id 0x%x %s delta %lld", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS), > + __entry->dqid, > + __print_flags(__entry->field, "|", XFS_QMOPT_FLAGS), > + __entry->delta) > +); > + > +DECLARE_EVENT_CLASS(xfs_dqtrx_class, > + TP_PROTO(struct xfs_dqtrx *qtrx), > + TP_ARGS(qtrx), > + TP_STRUCT__entry( > + __field(dev_t, dev) > + __field(unsigned int, dqflags) > + __field(u32, dqid) > + > + __field(uint64_t, blk_res) > + __field(int64_t, bcount_delta) > + __field(int64_t, delbcnt_delta) > + > + __field(uint64_t, rtblk_res) > + __field(uint64_t, rtblk_res_used) > + __field(int64_t, rtbcount_delta) > + __field(int64_t, delrtb_delta) > + > + __field(uint64_t, ino_res) > + __field(uint64_t, ino_res_used) > + __field(int64_t, icount_delta) > + ), > + TP_fast_assign( > + __entry->dev = qtrx->qt_dquot->q_mount->m_super->s_dev; > + __entry->dqflags = qtrx->qt_dquot->dq_flags; > + __entry->dqid = qtrx->qt_dquot->q_id; > + > + __entry->blk_res = qtrx->qt_blk_res; > + __entry->bcount_delta = qtrx->qt_bcount_delta; > + __entry->delbcnt_delta = qtrx->qt_delbcnt_delta; > + > + __entry->rtblk_res = qtrx->qt_rtblk_res; > + __entry->rtblk_res_used = qtrx->qt_rtblk_res_used; > + __entry->rtbcount_delta = qtrx->qt_rtbcount_delta; > + __entry->delrtb_delta = qtrx->qt_delrtb_delta; > + > + __entry->ino_res = qtrx->qt_ino_res; > + __entry->ino_res_used = qtrx->qt_ino_res_used; > + __entry->icount_delta = qtrx->qt_icount_delta; > + ), > + TP_printk("dev %d:%d dquot %s id 0x%x " > + "blk_res %llu bcount_delta %lld delbcnt_delta %lld " > + "rtblk_res %llu rtblk_res_used %llu rtbcount_delta %lld delrtb_delta %lld " > + "ino_res %llu ino_res_used %llu icount_delta %lld", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS), > + __entry->dqid, > + > + __entry->blk_res, > + __entry->bcount_delta, > + __entry->delbcnt_delta, > + > + __entry->rtblk_res, > + __entry->rtblk_res_used, > + __entry->rtbcount_delta, > + __entry->delrtb_delta, > + > + __entry->ino_res, > + __entry->ino_res_used, > + __entry->icount_delta) > +) > + > +#define DEFINE_DQTRX_EVENT(name) \ > +DEFINE_EVENT(xfs_dqtrx_class, name, \ > + TP_PROTO(struct xfs_dqtrx *qtrx), \ > + TP_ARGS(qtrx)) > +DEFINE_DQTRX_EVENT(xfs_trans_apply_dquot_deltas); > +DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_before); > +DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_after); > > DECLARE_EVENT_CLASS(xfs_loggrant_class, > TP_PROTO(struct xlog *log, struct xlog_ticket *tic), > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index 701923ea6c04..5689d9f1b748 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -15,6 +15,7 @@ > #include "xfs_trans_priv.h" > #include "xfs_quota.h" > #include "xfs_qm.h" > +#include "xfs_trace.h" > > STATIC void xfs_trans_alloc_dqinfo(xfs_trans_t *); > > @@ -203,6 +204,11 @@ xfs_trans_mod_dquot( > if (qtrx->qt_dquot == NULL) > qtrx->qt_dquot = dqp; > > + if (delta) { > + trace_xfs_trans_mod_dquot_before(qtrx); > + trace_xfs_trans_mod_dquot(tp, dqp, field, delta); > + } > + > switch (field) { > > /* > @@ -266,6 +272,10 @@ xfs_trans_mod_dquot( > default: > ASSERT(0); > } > + > + if (delta) > + trace_xfs_trans_mod_dquot_after(qtrx); > + > tp->t_flags |= XFS_TRANS_DQ_DIRTY; > } > > @@ -391,6 +401,13 @@ xfs_trans_apply_dquot_deltas( > qtrx->qt_delbcnt_delta; > totalrtbdelta = qtrx->qt_rtbcount_delta + > qtrx->qt_delrtb_delta; > + > + if (totalbdelta != 0 || totalrtbdelta != 0 || > + qtrx->qt_icount_delta != 0) { > + trace_xfs_trans_apply_dquot_deltas_before(dqp); > + trace_xfs_trans_apply_dquot_deltas(qtrx); > + } > + > #ifdef DEBUG > if (totalbdelta < 0) > ASSERT(dqp->q_blk.count >= -totalbdelta); > @@ -410,6 +427,10 @@ xfs_trans_apply_dquot_deltas( > if (totalrtbdelta) > dqp->q_rtb.count += totalrtbdelta; > > + if (totalbdelta != 0 || totalrtbdelta != 0 || > + qtrx->qt_icount_delta != 0) > + trace_xfs_trans_apply_dquot_deltas_after(dqp); > + > /* > * Get any default limits in use. > * Start/reset the timer(s) if needed. > > -- chandan