From f959b5d037e71a4d69b5bf71faffa065d9269b4a Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:36:09 -0700 Subject: xfs: fix inode quota reservation checks 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 Reviewed-by: Allison Collins Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_dquot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/xfs/xfs_trans_dquot.c') 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; -- cgit From 985a78fdde15e1730383f99867ca38b5648444bf Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:13 -0700 Subject: xfs: rename dquot incore state flags Rename the existing incore dquot "dq_flags" field to "q_flags" to match everything else in the structure, then move the two actual dquot state flags to the XFS_DQFLAG_ namespace from XFS_DQ_. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Reviewed-by: Chandan Babu R --- fs/xfs/xfs_trans_dquot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index ed0ce8b301b4..8963cfac2a6a 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -391,7 +391,7 @@ xfs_trans_apply_dquot_deltas( xfs_qm_adjust_dqtimers(tp->t_mountp, dqp); } - dqp->dq_flags |= XFS_DQ_DIRTY; + dqp->q_flags |= XFS_DQFLAG_DIRTY; /* * add this to the list of items to get logged */ -- cgit From c51df7334167e445f2cafc5511d6e2407a32e8f1 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:30 -0700 Subject: xfs: stop using q_core.d_id in the quota code 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 Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig Reviewed-by: Allison Collins --- fs/xfs/xfs_trans_dquot.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 8963cfac2a6a..8dd6aa6e8fa3 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)))) { -- cgit From 784e80f5640db9a925af1143a25e9bb98624350d Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:30 -0700 Subject: xfs: use a per-resource struct for incore dquot data 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 Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig Reviewed-by: Allison Collins --- fs/xfs/xfs_trans_dquot.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 8dd6aa6e8fa3..ed3928e9392f 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 && @@ -645,7 +645,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,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; -- cgit From d3537cf93e5e2f8b4e95cfe8bc8fa03b58c88e32 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:31 -0700 Subject: xfs: stop using q_core limits in the quota code Add limits fields in the incore dquot, and use that instead of the ones in qcore. This eliminates a bunch of endian conversions and will eventually allow us to remove qcore entirely. Signed-off-by: Darrick J. Wong Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig Reviewed-by: Allison Collins --- fs/xfs/xfs_trans_dquot.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index ed3928e9392f..0d6a69a81a58 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; -- cgit From be37d40c1ba0b5484ea2f8c109a9eda13e4c690a Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:31 -0700 Subject: xfs: stop using q_core counters in the quota code 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 Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig Reviewed-by: Allison Collins --- fs/xfs/xfs_trans_dquot.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 0d6a69a81a58..1c2a45989aaf 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); } } } @@ -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; -- cgit From c8c45fb2f614e1d30526c5aa304352923ad76416 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:31 -0700 Subject: xfs: stop using q_core warning counters in the quota code 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 Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig Reviewed-by: Allison Collins --- fs/xfs/xfs_trans_dquot.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 1c2a45989aaf..58cbc8f216f1 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) -- cgit From 19dce7eaef7f8fdecab965afacc7a7bf3eb4e0a1 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:32 -0700 Subject: xfs: stop using q_core timers in the quota code 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 Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig Reviewed-by: Allison Collins --- fs/xfs/xfs_trans_dquot.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 58cbc8f216f1..817c3d48b911 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; -- cgit From 438769e31e4410a20ea0df0ed1769516ae80740d Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:32 -0700 Subject: xfs: refactor default quota limits by resource 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 Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_dquot.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 817c3d48b911..9adea8f6ba87 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->blk.hard; softlimit = dqp->q_blk.softlimit; if (!softlimit) - softlimit = defq->bsoftlimit; + softlimit = defq->blk.soft; timer = dqp->q_blk.timer; warns = dqp->q_blk.warnings; - warnlimit = defq->bwarnlimit; + warnlimit = defq->blk.warn; 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->rtb.hard; softlimit = dqp->q_rtb.softlimit; if (!softlimit) - softlimit = defq->rtbsoftlimit; + softlimit = defq->rtb.soft; timer = dqp->q_rtb.timer; warns = dqp->q_rtb.warnings; - warnlimit = defq->rtbwarnlimit; + warnlimit = defq->rtb.warn; 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->ino.warn; hardlimit = dqp->q_ino.hardlimit; if (!hardlimit) - hardlimit = defq->ihardlimit; + hardlimit = defq->ino.hard; softlimit = dqp->q_ino.softlimit; if (!softlimit) - softlimit = defq->isoftlimit; + softlimit = defq->ino.soft; if (hardlimit && total_count > hardlimit) { xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN); -- cgit From c8c753e19a76507a2b686d9c521d5266351c75d0 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:33 -0700 Subject: xfs: remove unnecessary arguments from quota adjust functions 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 Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_dquot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 9adea8f6ba87..6f0bfd522116 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->q_flags |= XFS_DQFLAG_DIRTY; -- cgit From 292b47b4fcfad2b8b2bc749d68c8baa63fc8bf36 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:34 -0700 Subject: xfs: refactor xfs_trans_dqresv 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 Reviewed-by: Chandan Babu R Reviewed-by: Allison Collins Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_dquot.c | 155 ++++++++++++++++++++++++----------------------- 1 file changed, 79 insertions(+), 76 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 6f0bfd522116..9dc8dd9f852c 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_quota_limits *qlim, + 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 = qlim->hard; + if (!softlimit) + softlimit = qlim->soft; + + 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 >= qlim->warn)) { + *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_quota_limits *qlim; 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->blk.hard; - softlimit = dqp->q_blk.softlimit; - if (!softlimit) - softlimit = defq->blk.soft; - timer = dqp->q_blk.timer; - warns = dqp->q_blk.warnings; - warnlimit = defq->blk.warn; - resbcountp = &dqp->q_blk.reserved; + blkres = &dqp->q_blk; + qlim = &defq->blk; } else { - ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); - hardlimit = dqp->q_rtb.hardlimit; - if (!hardlimit) - hardlimit = defq->rtb.hard; - softlimit = dqp->q_rtb.softlimit; - if (!softlimit) - softlimit = defq->rtb.soft; - timer = dqp->q_rtb.timer; - warns = dqp->q_rtb.warnings; - warnlimit = defq->rtb.warn; - resbcountp = &dqp->q_rtb.reserved; + blkres = &dqp->q_rtb; + qlim = &defq->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, qlim, 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->ino.warn; - hardlimit = dqp->q_ino.hardlimit; - if (!hardlimit) - hardlimit = defq->ino.hard; - softlimit = dqp->q_ino.softlimit; - if (!softlimit) - softlimit = defq->ino.soft; - - if (hardlimit && total_count > hardlimit) { - xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN); + + quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->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, -- cgit From d92c881538c40a18d0a86193898fc0b6e2598aa0 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:34 -0700 Subject: xfs: refactor xfs_trans_apply_dquot_deltas 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 Reviewed-by: Allison Collins Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_dquot.c | 105 +++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 58 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 9dc8dd9f852c..510b9c3164d6 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; - - 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; - } - } + 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); + /* * 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); -- cgit From 4b8628d57b725b32616965e66975fcdebe008fe7 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:35 -0700 Subject: xfs: actually bump warning counts when we send warnings Currently, xfs quotas have the ability to send netlink warnings when a user exceeds the limits. They also have all the support code necessary to convert softlimit warnings into failures if the number of warnings exceeds a limit set by the administrator. Unfortunately, we never actually increase the warning counter, so this never actually happens. Make it so we actually do something useful with the warning counts. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Reviewed-by: Chandan Babu R --- fs/xfs/xfs_trans_dquot.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 510b9c3164d6..6be6287da1ac 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -589,6 +589,7 @@ xfs_dqresv_check( return QUOTA_NL_ISOFTLONGWARN; } + res->warnings++; return QUOTA_NL_ISOFTWARN; } -- cgit From 2cb91bab4fa4effe56da1c7fe2fc5723c4935db1 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Jul 2020 10:37:35 -0700 Subject: xfs: add more dquot tracepoints 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 Reviewed-by: Allison Collins Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_dquot.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 6be6287da1ac..a8f480e5401f 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. -- cgit From 8cd4901da56caadc16b4e8d6b434291a8ce31d7c Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 15 Jul 2020 17:42:36 -0700 Subject: xfs: rename XFS_DQ_{USER,GROUP,PROJ} to XFS_DQTYPE_* We're going to split up the incore dquot state flags from the ondisk dquot flags (eventually renaming this "type") so start by renaming the three flags and the bitmask that are going to participate in this. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_dquot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index a8f480e5401f..ea61e279f831 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -553,9 +553,9 @@ xfs_quota_warn( { enum quota_type qtype; - if (dqp->dq_flags & XFS_DQ_PROJ) + if (dqp->dq_flags & XFS_DQTYPE_PROJ) qtype = PRJQUOTA; - else if (dqp->dq_flags & XFS_DQ_USER) + else if (dqp->dq_flags & XFS_DQTYPE_USER) qtype = USRQUOTA; else qtype = GRPQUOTA; -- cgit From dbcbc7b90e8a43aa00412bfa601a2d110a29086a Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 15 Jul 2020 17:48:31 -0700 Subject: xfs: refactor testing if a particular dquot is being enforced Create a small helper to test if enforcement is enabled for a given incore dquot and replace the open-code logic testing. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_dquot.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index ea61e279f831..d7d710d25bbd 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -650,9 +650,7 @@ xfs_trans_dqresv( } 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)))) { + xfs_dquot_is_enforced(dqp)) { int quota_nl; bool fatal; -- cgit From 00a342e4965ee91fff06e01949fa27db53c0bb1c Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 15 Jul 2020 17:47:13 -0700 Subject: xfs: remove the XFS_QM_IS[UGP]DQ macros Remove these macros and use xfs_dquot_type() for everything. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_dquot.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index d7d710d25bbd..19d3e283aafa 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -156,14 +156,19 @@ xfs_trans_get_dqtrx( int i; struct xfs_dqtrx *qa; - if (XFS_QM_ISUDQ(dqp)) + switch (xfs_dquot_type(dqp)) { + case XFS_DQTYPE_USER: qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_USR]; - else if (XFS_QM_ISGDQ(dqp)) + break; + case XFS_DQTYPE_GROUP: qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_GRP]; - else if (XFS_QM_ISPDQ(dqp)) + break; + case XFS_DQTYPE_PROJ: qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_PRJ]; - else + break; + default: return NULL; + } for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) { if (qa[i].qt_dquot == NULL || @@ -713,7 +718,7 @@ xfs_trans_dqresv( error_return: xfs_dqunlock(dqp); - if (XFS_QM_ISPDQ(dqp)) + if (xfs_dquot_type(dqp) == XFS_DQTYPE_PROJ) return -ENOSPC; return -EDQUOT; } -- cgit From e6eb603c7e4f39cbd41042c7ceb7141dffc08096 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 15 Jul 2020 17:50:57 -0700 Subject: xfs: refactor quota type testing Certain functions can only act upon one quota type, so refactor those functions to use switch statements, in keeping with all the other high level xfs quota api calls. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_dquot.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 19d3e283aafa..518cf0347891 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -556,14 +556,21 @@ xfs_quota_warn( struct xfs_dquot *dqp, int type) { - enum quota_type qtype; + enum quota_type qtype; - if (dqp->dq_flags & XFS_DQTYPE_PROJ) + switch (xfs_dquot_type(dqp)) { + case XFS_DQTYPE_PROJ: qtype = PRJQUOTA; - else if (dqp->dq_flags & XFS_DQTYPE_USER) + break; + case XFS_DQTYPE_USER: qtype = USRQUOTA; - else + break; + case XFS_DQTYPE_GROUP: qtype = GRPQUOTA; + break; + default: + return; + } quota_send_warning(make_kqid(&init_user_ns, qtype, dqp->q_id), mp->m_super->s_dev, type); -- cgit From 32a2b11f467642ea700bc0b01f4693e52ec0fabd Mon Sep 17 00:00:00 2001 From: Carlos Maiolino Date: Wed, 22 Jul 2020 09:23:10 -0700 Subject: xfs: Remove kmem_zone_zalloc() usage Use kmem_cache_zalloc() directly. With the exception of xlog_ticket_alloc() which will be dealt on the next patch for readability. Reviewed-by: Christoph Hellwig Signed-off-by: Carlos Maiolino Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_trans_dquot.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'fs/xfs/xfs_trans_dquot.c') diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 518cf0347891..c6ba7ef18e06 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -874,7 +874,8 @@ STATIC void xfs_trans_alloc_dqinfo( xfs_trans_t *tp) { - tp->t_dqinfo = kmem_zone_zalloc(xfs_qm_dqtrxzone, 0); + tp->t_dqinfo = kmem_cache_zalloc(xfs_qm_dqtrxzone, + GFP_KERNEL | __GFP_NOFAIL); } void -- cgit