LCOV - code coverage report
Current view: top level - fs/xfs - xfs_trans_dquot.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-djwx @ Mon Jul 31 20:08:22 PDT 2023 Lines: 310 339 91.4 %
Date: 2023-07-31 20:08:22 Functions: 17 17 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2000-2002 Silicon Graphics, Inc.
       4             :  * All Rights Reserved.
       5             :  */
       6             : #include "xfs.h"
       7             : #include "xfs_fs.h"
       8             : #include "xfs_shared.h"
       9             : #include "xfs_format.h"
      10             : #include "xfs_log_format.h"
      11             : #include "xfs_trans_resv.h"
      12             : #include "xfs_mount.h"
      13             : #include "xfs_inode.h"
      14             : #include "xfs_trans.h"
      15             : #include "xfs_trans_priv.h"
      16             : #include "xfs_quota.h"
      17             : #include "xfs_qm.h"
      18             : #include "xfs_trace.h"
      19             : #include "xfs_error.h"
      20             : 
      21             : STATIC void     xfs_trans_alloc_dqinfo(xfs_trans_t *);
      22             : 
      23             : /*
      24             :  * Add the locked dquot to the transaction.
      25             :  * The dquot must be locked, and it cannot be associated with any
      26             :  * transaction.
      27             :  */
      28             : void
      29  2847337802 : xfs_trans_dqjoin(
      30             :         struct xfs_trans        *tp,
      31             :         struct xfs_dquot        *dqp)
      32             : {
      33  2847337802 :         ASSERT(XFS_DQ_IS_LOCKED(dqp));
      34  2847332876 :         ASSERT(dqp->q_logitem.qli_dquot == dqp);
      35             : 
      36             :         /*
      37             :          * Get a log_item_desc to point at the new item.
      38             :          */
      39  2847332876 :         xfs_trans_add_item(tp, &dqp->q_logitem.qli_item);
      40  2847301998 : }
      41             : 
      42             : /*
      43             :  * This is called to mark the dquot as needing
      44             :  * to be logged when the transaction is committed.  The dquot must
      45             :  * already be associated with the given transaction.
      46             :  * Note that it marks the entire transaction as dirty. In the ordinary
      47             :  * case, this gets called via xfs_trans_commit, after the transaction
      48             :  * is already dirty. However, there's nothing stop this from getting
      49             :  * called directly, as done by xfs_qm_scall_setqlim. Hence, the TRANS_DIRTY
      50             :  * flag.
      51             :  */
      52             : void
      53  2847273697 : xfs_trans_log_dquot(
      54             :         struct xfs_trans        *tp,
      55             :         struct xfs_dquot        *dqp)
      56             : {
      57  2847273697 :         ASSERT(XFS_DQ_IS_LOCKED(dqp));
      58             : 
      59             :         /* Upgrade the dquot to bigtime format if possible. */
      60  2847281290 :         if (dqp->q_id != 0 &&
      61   200060053 :             xfs_has_bigtime(tp->t_mountp) &&
      62   199986068 :             !(dqp->q_type & XFS_DQTYPE_BIGTIME))
      63         308 :                 dqp->q_type |= XFS_DQTYPE_BIGTIME;
      64             : 
      65  2847281290 :         tp->t_flags |= XFS_TRANS_DIRTY;
      66  2847281290 :         set_bit(XFS_LI_DIRTY, &dqp->q_logitem.qli_item.li_flags);
      67  2847357452 : }
      68             : 
      69             : /*
      70             :  * Carry forward whatever is left of the quota blk reservation to
      71             :  * the spanky new transaction
      72             :  */
      73             : void
      74   891465185 : xfs_trans_dup_dqinfo(
      75             :         struct xfs_trans        *otp,
      76             :         struct xfs_trans        *ntp)
      77             : {
      78   891465185 :         struct xfs_dqtrx        *oq, *nq;
      79   891465185 :         int                     i, j;
      80   891465185 :         struct xfs_dqtrx        *oqa, *nqa;
      81   891465185 :         uint64_t                blk_res_used;
      82             : 
      83   891465185 :         if (!otp->t_dqinfo)
      84             :                 return;
      85             : 
      86   596539995 :         xfs_trans_alloc_dqinfo(ntp);
      87             : 
      88  2982034101 :         for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
      89  1788989204 :                 oqa = otp->t_dqinfo->dqs[j];
      90  1789189760 :                 nqa = ntp->t_dqinfo->dqs[j];
      91  3577738091 :                 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
      92  3578072781 :                         blk_res_used = 0;
      93             : 
      94  3578072781 :                         if (oqa[i].qt_dquot == NULL)
      95             :                                 break;
      96  1788824094 :                         oq = &oqa[i];
      97  1788824094 :                         nq = &nqa[i];
      98             : 
      99  1788824094 :                         if (oq->qt_blk_res && oq->qt_bcount_delta > 0)
     100   276175611 :                                 blk_res_used = oq->qt_bcount_delta;
     101             : 
     102  1788824094 :                         nq->qt_dquot = oq->qt_dquot;
     103  1788824094 :                         nq->qt_bcount_delta = nq->qt_icount_delta = 0;
     104  1788824094 :                         nq->qt_rtbcount_delta = 0;
     105             : 
     106             :                         /*
     107             :                          * Transfer whatever is left of the reservations.
     108             :                          */
     109  1788824094 :                         nq->qt_blk_res = oq->qt_blk_res - blk_res_used;
     110  1788824094 :                         oq->qt_blk_res = blk_res_used;
     111             : 
     112  1788824094 :                         nq->qt_rtblk_res = oq->qt_rtblk_res -
     113  1788824094 :                                 oq->qt_rtblk_res_used;
     114  1788824094 :                         oq->qt_rtblk_res = oq->qt_rtblk_res_used;
     115             : 
     116  1788824094 :                         nq->qt_ino_res = oq->qt_ino_res - oq->qt_ino_res_used;
     117  1788824094 :                         oq->qt_ino_res = oq->qt_ino_res_used;
     118             : 
     119             :                 }
     120             :         }
     121             : }
     122             : 
     123             : /*
     124             :  * Wrap around mod_dquot to account for both user and group quotas.
     125             :  */
     126             : void
     127   416682206 : xfs_trans_mod_dquot_byino(
     128             :         xfs_trans_t     *tp,
     129             :         xfs_inode_t     *ip,
     130             :         uint            field,
     131             :         int64_t         delta)
     132             : {
     133   416682206 :         xfs_mount_t     *mp = tp->t_mountp;
     134             : 
     135   671362989 :         if (!XFS_IS_QUOTA_ON(mp) ||
     136   254680783 :             xfs_is_quota_inode(&mp->m_sb, ip->i_ino))
     137             :                 return;
     138             : 
     139   252366951 :         if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
     140   252358800 :                 (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
     141   252310015 :         if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot)
     142   252026539 :                 (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
     143   252344052 :         if (XFS_IS_PQUOTA_ON(mp) && ip->i_pdquot)
     144   251927533 :                 (void) xfs_trans_mod_dquot(tp, ip->i_pdquot, field, delta);
     145             : }
     146             : 
     147             : STATIC struct xfs_dqtrx *
     148  2233228657 : xfs_trans_get_dqtrx(
     149             :         struct xfs_trans        *tp,
     150             :         struct xfs_dquot        *dqp)
     151             : {
     152  2233228657 :         int                     i;
     153  2233228657 :         struct xfs_dqtrx        *qa;
     154             : 
     155  2233228657 :         switch (xfs_dquot_type(dqp)) {
     156   756506242 :         case XFS_DQTYPE_USER:
     157   756506242 :                 qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_USR];
     158   756506242 :                 break;
     159   754331275 :         case XFS_DQTYPE_GROUP:
     160   754331275 :                 qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_GRP];
     161   754331275 :                 break;
     162   722391140 :         case XFS_DQTYPE_PROJ:
     163   722391140 :                 qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_PRJ];
     164   722391140 :                 break;
     165             :         default:
     166             :                 return NULL;
     167             :         }
     168             : 
     169  2250077619 :         for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
     170  2248386698 :                 if (qa[i].qt_dquot == NULL ||
     171             :                     qa[i].qt_dquot == dqp)
     172  2231537736 :                         return &qa[i];
     173             :         }
     174             : 
     175             :         return NULL;
     176             : }
     177             : 
     178             : /*
     179             :  * Make the changes in the transaction structure.
     180             :  * The moral equivalent to xfs_trans_mod_sb().
     181             :  * We don't touch any fields in the dquot, so we don't care
     182             :  * if it's locked or not (most of the time it won't be).
     183             :  */
     184             : void
     185  5446172344 : xfs_trans_mod_dquot(
     186             :         struct xfs_trans        *tp,
     187             :         struct xfs_dquot        *dqp,
     188             :         uint                    field,
     189             :         int64_t                 delta)
     190             : {
     191  5446172344 :         struct xfs_dqtrx        *qtrx;
     192             : 
     193  5446172344 :         ASSERT(tp);
     194  5446172344 :         ASSERT(XFS_IS_QUOTA_ON(tp->t_mountp));
     195  5446172344 :         qtrx = NULL;
     196             : 
     197  5446172344 :         if (!delta)
     198             :                 return;
     199             : 
     200  2231132786 :         if (tp->t_dqinfo == NULL)
     201   468092616 :                 xfs_trans_alloc_dqinfo(tp);
     202             :         /*
     203             :          * Find either the first free slot or the slot that belongs
     204             :          * to this dquot.
     205             :          */
     206  2231174585 :         qtrx = xfs_trans_get_dqtrx(tp, dqp);
     207  2231174585 :         ASSERT(qtrx);
     208  2231174585 :         if (qtrx->qt_dquot == NULL)
     209  1406953608 :                 qtrx->qt_dquot = dqp;
     210             : 
     211  2231174585 :         trace_xfs_trans_mod_dquot_before(qtrx);
     212  2231325059 :         trace_xfs_trans_mod_dquot(tp, dqp, field, delta);
     213             : 
     214  2232378453 :         switch (field) {
     215             :         /* regular disk blk reservation */
     216  1201069748 :         case XFS_TRANS_DQ_RES_BLKS:
     217  1201069748 :                 qtrx->qt_blk_res += delta;
     218  1201069748 :                 break;
     219             : 
     220             :         /* inode reservation */
     221   140630611 :         case XFS_TRANS_DQ_RES_INOS:
     222   140630611 :                 qtrx->qt_ino_res += delta;
     223   140630611 :                 break;
     224             : 
     225             :         /* disk blocks used. */
     226   575551546 :         case XFS_TRANS_DQ_BCOUNT:
     227   575551546 :                 qtrx->qt_bcount_delta += delta;
     228   575551546 :                 break;
     229             : 
     230    76140302 :         case XFS_TRANS_DQ_DELBCOUNT:
     231    76140302 :                 qtrx->qt_delbcnt_delta += delta;
     232    76140302 :                 break;
     233             : 
     234             :         /* Inode Count */
     235   238986246 :         case XFS_TRANS_DQ_ICOUNT:
     236   238986246 :                 if (qtrx->qt_ino_res && delta > 0) {
     237   140014689 :                         qtrx->qt_ino_res_used += delta;
     238   140014689 :                         ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
     239             :                 }
     240   238986246 :                 qtrx->qt_icount_delta += delta;
     241   238986246 :                 break;
     242             : 
     243             :         /* rtblk reservation */
     244           0 :         case XFS_TRANS_DQ_RES_RTBLKS:
     245           0 :                 qtrx->qt_rtblk_res += delta;
     246           0 :                 break;
     247             : 
     248             :         /* rtblk count */
     249           0 :         case XFS_TRANS_DQ_RTBCOUNT:
     250           0 :                 if (qtrx->qt_rtblk_res && delta > 0) {
     251           0 :                         qtrx->qt_rtblk_res_used += delta;
     252           0 :                         ASSERT(qtrx->qt_rtblk_res >= qtrx->qt_rtblk_res_used);
     253             :                 }
     254           0 :                 qtrx->qt_rtbcount_delta += delta;
     255           0 :                 break;
     256             : 
     257           0 :         case XFS_TRANS_DQ_DELRTBCOUNT:
     258           0 :                 qtrx->qt_delrtb_delta += delta;
     259           0 :                 break;
     260             : 
     261           0 :         default:
     262           0 :                 ASSERT(0);
     263             :         }
     264             : 
     265  2232378453 :         trace_xfs_trans_mod_dquot_after(qtrx);
     266             : }
     267             : 
     268             : 
     269             : /*
     270             :  * Given an array of dqtrx structures, lock all the dquots associated and join
     271             :  * them to the transaction, provided they have been modified.  We know that the
     272             :  * highest number of dquots of one type - usr, grp and prj - involved in a
     273             :  * transaction is 3 so we don't need to make this very generic.
     274             :  */
     275             : STATIC void
     276  2831241902 : xfs_trans_dqlockedjoin(
     277             :         struct xfs_trans        *tp,
     278             :         struct xfs_dqtrx        *q)
     279             : {
     280  2831241902 :         ASSERT(q[0].qt_dquot != NULL);
     281  2831241902 :         if (q[1].qt_dquot == NULL) {
     282  2816529664 :                 xfs_dqlock(q[0].qt_dquot);
     283  2817772656 :                 xfs_trans_dqjoin(tp, q[0].qt_dquot);
     284             :         } else {
     285    14712238 :                 ASSERT(XFS_QM_TRANS_MAXDQS == 2);
     286    14712238 :                 xfs_dqlock2(q[0].qt_dquot, q[1].qt_dquot);
     287    14754034 :                 xfs_trans_dqjoin(tp, q[0].qt_dquot);
     288    14753946 :                 xfs_trans_dqjoin(tp, q[1].qt_dquot);
     289             :         }
     290  2832490375 : }
     291             : 
     292             : /* Apply dqtrx changes to the quota reservation counters. */
     293             : static inline void
     294             : xfs_apply_quota_reservation_deltas(
     295             :         struct xfs_dquot_res    *res,
     296             :         uint64_t                reserved,
     297             :         int64_t                 res_used,
     298             :         int64_t                 count_delta)
     299             : {
     300  8541888792 :         if (reserved != 0) {
     301             :                 /*
     302             :                  * Subtle math here: If reserved > res_used (the normal case),
     303             :                  * we're simply subtracting the unused transaction quota
     304             :                  * reservation from the dquot reservation.
     305             :                  *
     306             :                  * If, however, res_used > reserved, then we have allocated
     307             :                  * more quota blocks than were reserved for the transaction.
     308             :                  * We must add that excess to the dquot reservation since it
     309             :                  * tracks (usage + resv) and by definition we didn't reserve
     310             :                  * that excess.
     311             :                  */
     312  1248396117 :                 res->reserved -= abs(reserved - res_used);
     313  7293492675 :         } else if (count_delta != 0) {
     314             :                 /*
     315             :                  * These blks were never reserved, either inside a transaction
     316             :                  * or outside one (in a delayed allocation). Also, this isn't
     317             :                  * always a negative number since we sometimes deliberately
     318             :                  * skip quota reservations.
     319             :                  */
     320   315192027 :                 res->reserved += count_delta;
     321             :         }
     322             : }
     323             : 
     324             : /*
     325             :  * Called by xfs_trans_commit() and similar in spirit to
     326             :  * xfs_trans_apply_sb_deltas().
     327             :  * Go thru all the dquots belonging to this transaction and modify the
     328             :  * INCORE dquot to reflect the actual usages.
     329             :  * Unreserve just the reservations done by this transaction.
     330             :  * dquot is still left locked at exit.
     331             :  */
     332             : void
     333  1738115180 : xfs_trans_apply_dquot_deltas(
     334             :         struct xfs_trans        *tp)
     335             : {
     336  1738115180 :         int                     i, j;
     337  1738115180 :         struct xfs_dquot        *dqp;
     338  1738115180 :         struct xfs_dqtrx        *qtrx, *qa;
     339  1738115180 :         int64_t                 totalbdelta;
     340  1738115180 :         int64_t                 totalrtbdelta;
     341             : 
     342  1738115180 :         if (!tp->t_dqinfo)
     343             :                 return;
     344             : 
     345             :         ASSERT(tp->t_dqinfo);
     346  3791273032 :         for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
     347  2843247243 :                 qa = tp->t_dqinfo->dqs[j];
     348  2842881273 :                 if (qa[0].qt_dquot == NULL)
     349    11522286 :                         continue;
     350             : 
     351             :                 /*
     352             :                  * Lock all of the dquots and join them to the transaction.
     353             :                  */
     354  2831358987 :                 xfs_trans_dqlockedjoin(tp, qa);
     355             : 
     356  8511144661 :                 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
     357  5665000546 :                         uint64_t        blk_res_used;
     358             : 
     359  5665000546 :                         qtrx = &qa[i];
     360             :                         /*
     361             :                          * The array of dquots is filled
     362             :                          * sequentially, not sparsely.
     363             :                          */
     364  5665000546 :                         if ((dqp = qtrx->qt_dquot) == NULL)
     365             :                                 break;
     366             : 
     367  2847241907 :                         ASSERT(XFS_DQ_IS_LOCKED(dqp));
     368             : 
     369             :                         /*
     370             :                          * adjust the actual number of blocks used
     371             :                          */
     372             : 
     373             :                         /*
     374             :                          * The issue here is - sometimes we don't make a blkquota
     375             :                          * reservation intentionally to be fair to users
     376             :                          * (when the amount is small). On the other hand,
     377             :                          * delayed allocs do make reservations, but that's
     378             :                          * outside of a transaction, so we have no
     379             :                          * idea how much was really reserved.
     380             :                          * So, here we've accumulated delayed allocation blks and
     381             :                          * non-delay blks. The assumption is that the
     382             :                          * delayed ones are always reserved (outside of a
     383             :                          * transaction), and the others may or may not have
     384             :                          * quota reservations.
     385             :                          */
     386  2847260303 :                         totalbdelta = qtrx->qt_bcount_delta +
     387  2847260303 :                                 qtrx->qt_delbcnt_delta;
     388  2847260303 :                         totalrtbdelta = qtrx->qt_rtbcount_delta +
     389  2847260303 :                                 qtrx->qt_delrtb_delta;
     390             : 
     391  2847260303 :                         if (totalbdelta != 0 || totalrtbdelta != 0 ||
     392  2312985867 :                             qtrx->qt_icount_delta != 0) {
     393   743196101 :                                 trace_xfs_trans_apply_dquot_deltas_before(dqp);
     394   743192676 :                                 trace_xfs_trans_apply_dquot_deltas(qtrx);
     395             :                         }
     396             : 
     397             : #ifdef DEBUG
     398  2847253856 :                         if (totalbdelta < 0)
     399   197315838 :                                 ASSERT(dqp->q_blk.count >= -totalbdelta);
     400             : 
     401  2847253856 :                         if (totalrtbdelta < 0)
     402           0 :                                 ASSERT(dqp->q_rtb.count >= -totalrtbdelta);
     403             : 
     404  2847253856 :                         if (qtrx->qt_icount_delta < 0)
     405    99369277 :                                 ASSERT(dqp->q_ino.count >= -qtrx->qt_icount_delta);
     406             : #endif
     407  2847253856 :                         if (totalbdelta)
     408   534273036 :                                 dqp->q_blk.count += totalbdelta;
     409             : 
     410  2847253856 :                         if (qtrx->qt_icount_delta)
     411   239693018 :                                 dqp->q_ino.count += qtrx->qt_icount_delta;
     412             : 
     413  2847253856 :                         if (totalrtbdelta)
     414           0 :                                 dqp->q_rtb.count += totalrtbdelta;
     415             : 
     416  2847253856 :                         if (totalbdelta != 0 || totalrtbdelta != 0 ||
     417  2312981548 :                             qtrx->qt_icount_delta != 0)
     418   743193358 :                                 trace_xfs_trans_apply_dquot_deltas_after(dqp);
     419             : 
     420             :                         /*
     421             :                          * Get any default limits in use.
     422             :                          * Start/reset the timer(s) if needed.
     423             :                          */
     424  2847251248 :                         if (dqp->q_id) {
     425   200010604 :                                 xfs_qm_adjust_dqlimits(dqp);
     426   200010105 :                                 xfs_qm_adjust_dqtimers(dqp);
     427             :                         }
     428             : 
     429  2847243330 :                         dqp->q_flags |= XFS_DQFLAG_DIRTY;
     430             :                         /*
     431             :                          * add this to the list of items to get logged
     432             :                          */
     433  2847243330 :                         xfs_trans_log_dquot(tp, dqp);
     434             :                         /*
     435             :                          * Take off what's left of the original reservation.
     436             :                          * In case of delayed allocations, there's no
     437             :                          * reservation that a transaction structure knows of.
     438             :                          */
     439  2847296264 :                         blk_res_used = max_t(int64_t, 0, qtrx->qt_bcount_delta);
     440  2847296264 :                         xfs_apply_quota_reservation_deltas(&dqp->q_blk,
     441             :                                         qtrx->qt_blk_res, blk_res_used,
     442             :                                         qtrx->qt_bcount_delta);
     443             : 
     444             :                         /*
     445             :                          * Adjust the RT reservation.
     446             :                          */
     447  2847296264 :                         xfs_apply_quota_reservation_deltas(&dqp->q_rtb,
     448             :                                         qtrx->qt_rtblk_res,
     449  2847296264 :                                         qtrx->qt_rtblk_res_used,
     450             :                                         qtrx->qt_rtbcount_delta);
     451             : 
     452             :                         /*
     453             :                          * Adjust the inode reservation.
     454             :                          */
     455  2847296264 :                         ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
     456  2847296264 :                         xfs_apply_quota_reservation_deltas(&dqp->q_ino,
     457             :                                         qtrx->qt_ino_res,
     458  2847296264 :                                         qtrx->qt_ino_res_used,
     459             :                                         qtrx->qt_icount_delta);
     460             : 
     461  2847296264 :                         ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
     462  2847296264 :                         ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
     463  2847296264 :                         ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
     464             :                 }
     465             :         }
     466             : }
     467             : 
     468             : /*
     469             :  * Release the reservations, and adjust the dquots accordingly.
     470             :  * This is called only when the transaction is being aborted. If by
     471             :  * any chance we have done dquot modifications incore (ie. deltas) already,
     472             :  * we simply throw those away, since that's the expected behavior
     473             :  * when a transaction is curtailed without a commit.
     474             :  */
     475             : void
     476  2747726314 : xfs_trans_unreserve_and_mod_dquots(
     477             :         struct xfs_trans        *tp)
     478             : {
     479  2747726314 :         int                     i, j;
     480  2747726314 :         struct xfs_dquot        *dqp;
     481  2747726314 :         struct xfs_dqtrx        *qtrx, *qa;
     482  2747726314 :         bool                    locked;
     483             : 
     484  2747726314 :         if (!tp->t_dqinfo)
     485             :                 return;
     486             : 
     487   467299343 :         for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
     488   350521238 :                 qa = tp->t_dqinfo->dqs[j];
     489             : 
     490   700095909 :                 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
     491   700090120 :                         qtrx = &qa[i];
     492             :                         /*
     493             :                          * We assume that the array of dquots is filled
     494             :                          * sequentially, not sparsely.
     495             :                          */
     496   700090120 :                         if ((dqp = qtrx->qt_dquot) == NULL)
     497             :                                 break;
     498             :                         /*
     499             :                          * Unreserve the original reservation. We don't care
     500             :                          * about the number of blocks used field, or deltas.
     501             :                          * Also we don't bother to zero the fields.
     502             :                          */
     503   349870284 :                         locked = false;
     504   349870284 :                         if (qtrx->qt_blk_res) {
     505   349864049 :                                 xfs_dqlock(dqp);
     506   349869936 :                                 locked = true;
     507   349869936 :                                 dqp->q_blk.reserved -=
     508   349869936 :                                         (xfs_qcnt_t)qtrx->qt_blk_res;
     509             :                         }
     510   349876171 :                         if (qtrx->qt_ino_res) {
     511      443872 :                                 if (!locked) {
     512           0 :                                         xfs_dqlock(dqp);
     513           0 :                                         locked = true;
     514             :                                 }
     515      443872 :                                 dqp->q_ino.reserved -=
     516      443872 :                                         (xfs_qcnt_t)qtrx->qt_ino_res;
     517             :                         }
     518             : 
     519   349876171 :                         if (qtrx->qt_rtblk_res) {
     520           0 :                                 if (!locked) {
     521           0 :                                         xfs_dqlock(dqp);
     522           0 :                                         locked = true;
     523             :                                 }
     524           0 :                                 dqp->q_rtb.reserved -=
     525           0 :                                         (xfs_qcnt_t)qtrx->qt_rtblk_res;
     526             :                         }
     527   349876171 :                         if (locked)
     528   349864800 :                                 xfs_dqunlock(dqp);
     529             : 
     530             :                 }
     531             :         }
     532             : }
     533             : 
     534             : STATIC void
     535      102537 : xfs_quota_warn(
     536             :         struct xfs_mount        *mp,
     537             :         struct xfs_dquot        *dqp,
     538             :         int                     type)
     539             : {
     540      102537 :         enum quota_type         qtype;
     541             : 
     542      102537 :         switch (xfs_dquot_type(dqp)) {
     543             :         case XFS_DQTYPE_PROJ:
     544             :                 qtype = PRJQUOTA;
     545             :                 break;
     546       76330 :         case XFS_DQTYPE_USER:
     547       76330 :                 qtype = USRQUOTA;
     548       76330 :                 break;
     549       13006 :         case XFS_DQTYPE_GROUP:
     550       13006 :                 qtype = GRPQUOTA;
     551       13006 :                 break;
     552             :         default:
     553             :                 return;
     554             :         }
     555             : 
     556      102537 :         quota_send_warning(make_kqid(&init_user_ns, qtype, dqp->q_id),
     557      102537 :                            mp->m_super->s_dev, type);
     558             : }
     559             : 
     560             : /*
     561             :  * Decide if we can make an additional reservation against a quota resource.
     562             :  * Returns an inode QUOTA_NL_ warning code and whether or not it's fatal.
     563             :  *
     564             :  * Note that we assume that the numeric difference between the inode and block
     565             :  * warning codes will always be 3 since it's userspace ABI now, and will never
     566             :  * decrease the quota reservation, so the *BELOW messages are irrelevant.
     567             :  */
     568             : static inline int
     569   463257962 : xfs_dqresv_check(
     570             :         struct xfs_dquot_res    *res,
     571             :         struct xfs_quota_limits *qlim,
     572             :         int64_t                 delta,
     573             :         bool                    *fatal)
     574             : {
     575   463257962 :         xfs_qcnt_t              hardlimit = res->hardlimit;
     576   463257962 :         xfs_qcnt_t              softlimit = res->softlimit;
     577   463257962 :         xfs_qcnt_t              total_count = res->reserved + delta;
     578             : 
     579   463257962 :         BUILD_BUG_ON(QUOTA_NL_BHARDWARN     != QUOTA_NL_IHARDWARN + 3);
     580   463257962 :         BUILD_BUG_ON(QUOTA_NL_BSOFTLONGWARN != QUOTA_NL_ISOFTLONGWARN + 3);
     581   463257962 :         BUILD_BUG_ON(QUOTA_NL_BSOFTWARN     != QUOTA_NL_ISOFTWARN + 3);
     582             : 
     583   463257962 :         *fatal = false;
     584   463257962 :         if (delta <= 0)
     585             :                 return QUOTA_NL_NOWARN;
     586             : 
     587   102758454 :         if (!hardlimit)
     588   102479473 :                 hardlimit = qlim->hard;
     589   102758454 :         if (!softlimit)
     590   102480978 :                 softlimit = qlim->soft;
     591             : 
     592   102758454 :         if (hardlimit && total_count > hardlimit) {
     593       65780 :                 *fatal = true;
     594       65780 :                 return QUOTA_NL_IHARDWARN;
     595             :         }
     596             : 
     597   102692674 :         if (softlimit && total_count > softlimit) {
     598       36757 :                 time64_t        now = ktime_get_real_seconds();
     599             : 
     600       36757 :                 if (res->timer != 0 && now > res->timer) {
     601         132 :                         *fatal = true;
     602         132 :                         return QUOTA_NL_ISOFTLONGWARN;
     603             :                 }
     604             : 
     605             :                 return QUOTA_NL_ISOFTWARN;
     606             :         }
     607             : 
     608             :         return QUOTA_NL_NOWARN;
     609             : }
     610             : 
     611             : /*
     612             :  * This reserves disk blocks and inodes against a dquot.
     613             :  * Flags indicate if the dquot is to be locked here and also
     614             :  * if the blk reservation is for RT or regular blocks.
     615             :  * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
     616             :  */
     617             : STATIC int
     618  2565533579 : xfs_trans_dqresv(
     619             :         struct xfs_trans        *tp,
     620             :         struct xfs_mount        *mp,
     621             :         struct xfs_dquot        *dqp,
     622             :         int64_t                 nblks,
     623             :         long                    ninos,
     624             :         uint                    flags)
     625             : {
     626  2565533579 :         struct xfs_quotainfo    *q = mp->m_quotainfo;
     627  2565533579 :         struct xfs_def_quota    *defq;
     628  2565533579 :         struct xfs_dquot_res    *blkres;
     629  2565533579 :         struct xfs_quota_limits *qlim;
     630             : 
     631  2565533579 :         xfs_dqlock(dqp);
     632             : 
     633  2565824932 :         defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
     634             : 
     635  2566021361 :         if (flags & XFS_TRANS_DQ_RES_BLKS) {
     636  1353398354 :                 blkres = &dqp->q_blk;
     637  1353398354 :                 qlim = &defq->blk;
     638             :         } else {
     639  1212623007 :                 blkres = &dqp->q_rtb;
     640  1212623007 :                 qlim = &defq->rtb;
     641             :         }
     642             : 
     643  2797826007 :         if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
     644   231809935 :             xfs_dquot_is_enforced(dqp)) {
     645   231664515 :                 int             quota_nl;
     646   231664515 :                 bool            fatal;
     647             : 
     648             :                 /*
     649             :                  * dquot is locked already. See if we'd go over the hardlimit
     650             :                  * or exceed the timelimit if we'd reserve resources.
     651             :                  */
     652   231664515 :                 quota_nl = xfs_dqresv_check(blkres, qlim, nblks, &fatal);
     653   231660266 :                 if (quota_nl != QUOTA_NL_NOWARN) {
     654             :                         /*
     655             :                          * Quota block warning codes are 3 more than the inode
     656             :                          * codes, which we check above.
     657             :                          */
     658      101085 :                         xfs_quota_warn(mp, dqp, quota_nl + 3);
     659      101085 :                         if (fatal)
     660       64808 :                                 goto error_return;
     661             :                 }
     662             : 
     663   231595458 :                 quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->ino, ninos,
     664             :                                 &fatal);
     665   231600798 :                 if (quota_nl != QUOTA_NL_NOWARN) {
     666        1452 :                         xfs_quota_warn(mp, dqp, quota_nl);
     667        1452 :                         if (fatal)
     668        1104 :                                 goto error_return;
     669             :                 }
     670             :         }
     671             : 
     672             :         /*
     673             :          * Change the reservation, but not the actual usage.
     674             :          * Note that q_blk.reserved = q_blk.count + resv
     675             :          */
     676  2565951251 :         blkres->reserved += (xfs_qcnt_t)nblks;
     677  2565951251 :         dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
     678             : 
     679             :         /*
     680             :          * note the reservation amt in the trans struct too,
     681             :          * so that the transaction knows how much was reserved by
     682             :          * it against this particular dquot.
     683             :          * We don't do this when we are reserving for a delayed allocation,
     684             :          * because we don't have the luxury of a transaction envelope then.
     685             :          */
     686  2565951251 :         if (tp) {
     687  2247307540 :                 ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
     688  2247307540 :                 xfs_trans_mod_dquot(tp, dqp, flags & XFS_QMOPT_RESBLK_MASK,
     689             :                                     nblks);
     690  2246349220 :                 xfs_trans_mod_dquot(tp, dqp, XFS_TRANS_DQ_RES_INOS, ninos);
     691             :         }
     692             : 
     693  2564858821 :         if (XFS_IS_CORRUPT(mp, dqp->q_blk.reserved < dqp->q_blk.count) ||
     694  2564858821 :             XFS_IS_CORRUPT(mp, dqp->q_rtb.reserved < dqp->q_rtb.count) ||
     695  2564858821 :             XFS_IS_CORRUPT(mp, dqp->q_ino.reserved < dqp->q_ino.count))
     696           0 :                 goto error_corrupt;
     697             : 
     698  2564858821 :         xfs_dqunlock(dqp);
     699  2564858821 :         return 0;
     700             : 
     701             : error_return:
     702       65912 :         xfs_dqunlock(dqp);
     703       65912 :         if (xfs_dquot_type(dqp) == XFS_DQTYPE_PROJ)
     704        1046 :                 return -ENOSPC;
     705             :         return -EDQUOT;
     706             : error_corrupt:
     707           0 :         xfs_dqunlock(dqp);
     708           0 :         xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
     709           0 :         return -EFSCORRUPTED;
     710             : }
     711             : 
     712             : 
     713             : /*
     714             :  * Given dquot(s), make disk block and/or inode reservations against them.
     715             :  * The fact that this does the reservation against user, group and
     716             :  * project quotas is important, because this follows a all-or-nothing
     717             :  * approach.
     718             :  *
     719             :  * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
     720             :  *         XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT.  Used by pquota.
     721             :  *         XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
     722             :  *         XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
     723             :  * dquots are unlocked on return, if they were not locked by caller.
     724             :  */
     725             : int
     726   859431006 : xfs_trans_reserve_quota_bydquots(
     727             :         struct xfs_trans        *tp,
     728             :         struct xfs_mount        *mp,
     729             :         struct xfs_dquot        *udqp,
     730             :         struct xfs_dquot        *gdqp,
     731             :         struct xfs_dquot        *pdqp,
     732             :         int64_t                 nblks,
     733             :         long                    ninos,
     734             :         uint                    flags)
     735             : {
     736   859431006 :         int             error;
     737             : 
     738   859431006 :         if (!XFS_IS_QUOTA_ON(mp))
     739             :                 return 0;
     740             : 
     741   859431006 :         ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
     742             : 
     743   859431006 :         if (udqp) {
     744   859007045 :                 error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags);
     745   859898066 :                 if (error)
     746             :                         return error;
     747             :         }
     748             : 
     749   860257938 :         if (gdqp) {
     750   857559928 :                 error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
     751   857559042 :                 if (error)
     752         777 :                         goto unwind_usr;
     753             :         }
     754             : 
     755   860256275 :         if (pdqp) {
     756   849979934 :                 error = xfs_trans_dqresv(tp, mp, pdqp, nblks, ninos, flags);
     757   849986185 :                 if (error)
     758        1046 :                         goto unwind_grp;
     759             :         }
     760             : 
     761             :         /*
     762             :          * Didn't change anything critical, so, no need to log
     763             :          */
     764             :         return 0;
     765             : 
     766             : unwind_grp:
     767        1046 :         flags |= XFS_QMOPT_FORCE_RES;
     768        1046 :         if (gdqp)
     769         312 :                 xfs_trans_dqresv(tp, mp, gdqp, -nblks, -ninos, flags);
     770         734 : unwind_usr:
     771        1823 :         flags |= XFS_QMOPT_FORCE_RES;
     772        1823 :         if (udqp)
     773         492 :                 xfs_trans_dqresv(tp, mp, udqp, -nblks, -ninos, flags);
     774             :         return error;
     775             : }
     776             : 
     777             : 
     778             : /*
     779             :  * Lock the dquot and change the reservation if we can.
     780             :  * This doesn't change the actual usage, just the reservation.
     781             :  * The inode sent in is locked.
     782             :  */
     783             : int
     784   648559286 : xfs_trans_reserve_quota_nblks(
     785             :         struct xfs_trans        *tp,
     786             :         struct xfs_inode        *ip,
     787             :         int64_t                 dblocks,
     788             :         int64_t                 rblocks,
     789             :         bool                    force)
     790             : {
     791   648559286 :         struct xfs_mount        *mp = ip->i_mount;
     792   648559286 :         unsigned int            qflags = 0;
     793   648559286 :         int                     error;
     794             : 
     795   648559286 :         if (!XFS_IS_QUOTA_ON(mp))
     796             :                 return 0;
     797             : 
     798   810139208 :         ASSERT(!xfs_is_quota_inode(&mp->m_sb, ip->i_ino));
     799   405069604 :         ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
     800             : 
     801   404948990 :         if (force)
     802    26656253 :                 qflags |= XFS_QMOPT_FORCE_RES;
     803             : 
     804             :         /* Reserve data device quota against the inode's dquots. */
     805   404948990 :         error = xfs_trans_reserve_quota_bydquots(tp, mp, ip->i_udquot,
     806             :                         ip->i_gdquot, ip->i_pdquot, dblocks, 0,
     807             :                         XFS_QMOPT_RES_REGBLKS | qflags);
     808   405279020 :         if (error)
     809             :                 return error;
     810             : 
     811             :         /* Do the same but for realtime blocks. */
     812   405233668 :         error = xfs_trans_reserve_quota_bydquots(tp, mp, ip->i_udquot,
     813             :                         ip->i_gdquot, ip->i_pdquot, rblocks, 0,
     814             :                         XFS_QMOPT_RES_RTBLKS | qflags);
     815   405233762 :         if (error) {
     816           0 :                 xfs_trans_reserve_quota_bydquots(tp, mp, ip->i_udquot,
     817             :                                 ip->i_gdquot, ip->i_pdquot, -dblocks, 0,
     818             :                                 XFS_QMOPT_RES_REGBLKS);
     819           0 :                 return error;
     820             :         }
     821             : 
     822             :         return 0;
     823             : }
     824             : 
     825             : /* Change the quota reservations for an inode creation activity. */
     826             : int
     827    84502221 : xfs_trans_reserve_quota_icreate(
     828             :         struct xfs_trans        *tp,
     829             :         struct xfs_dquot        *udqp,
     830             :         struct xfs_dquot        *gdqp,
     831             :         struct xfs_dquot        *pdqp,
     832             :         int64_t                 dblocks)
     833             : {
     834    84502221 :         struct xfs_mount        *mp = tp->t_mountp;
     835             : 
     836    84502221 :         if (!XFS_IS_QUOTA_ON(mp))
     837             :                 return 0;
     838             : 
     839    41814667 :         return xfs_trans_reserve_quota_bydquots(tp, mp, udqp, gdqp, pdqp,
     840             :                         dblocks, 1, XFS_QMOPT_RES_REGBLKS);
     841             : }
     842             : 
     843             : STATIC void
     844  1064548764 : xfs_trans_alloc_dqinfo(
     845             :         xfs_trans_t     *tp)
     846             : {
     847  1064548764 :         tp->t_dqinfo = kmem_cache_zalloc(xfs_dqtrx_cache,
     848             :                                          GFP_KERNEL | __GFP_NOFAIL);
     849  1064699434 : }
     850             : 
     851             : void
     852  4481604314 : xfs_trans_free_dqinfo(
     853             :         xfs_trans_t     *tp)
     854             : {
     855  4481604314 :         if (!tp->t_dqinfo)
     856             :                 return;
     857  1064740015 :         kmem_cache_free(xfs_dqtrx_cache, tp->t_dqinfo);
     858  1064742075 :         tp->t_dqinfo = NULL;
     859             : }

Generated by: LCOV version 1.14