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-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 361 392 92.1 %
Date: 2023-07-31 20:08:12 Functions: 24 24 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             : #include "xfs_health.h"
      21             : 
      22             : STATIC void     xfs_trans_alloc_dqinfo(xfs_trans_t *);
      23             : 
      24             : /*
      25             :  * Add the locked dquot to the transaction.
      26             :  * The dquot must be locked, and it cannot be associated with any
      27             :  * transaction.
      28             :  */
      29             : void
      30  4000708502 : xfs_trans_dqjoin(
      31             :         struct xfs_trans        *tp,
      32             :         struct xfs_dquot        *dqp)
      33             : {
      34  4000708502 :         ASSERT(XFS_DQ_IS_LOCKED(dqp));
      35  4000703751 :         ASSERT(dqp->q_logitem.qli_dquot == dqp);
      36             : 
      37             :         /*
      38             :          * Get a log_item_desc to point at the new item.
      39             :          */
      40  4000703751 :         xfs_trans_add_item(tp, &dqp->q_logitem.qli_item);
      41  4000655171 : }
      42             : 
      43             : /*
      44             :  * This is called to mark the dquot as needing
      45             :  * to be logged when the transaction is committed.  The dquot must
      46             :  * already be associated with the given transaction.
      47             :  * Note that it marks the entire transaction as dirty. In the ordinary
      48             :  * case, this gets called via xfs_trans_commit, after the transaction
      49             :  * is already dirty. However, there's nothing stop this from getting
      50             :  * called directly, as done by xfs_qm_scall_setqlim. Hence, the TRANS_DIRTY
      51             :  * flag.
      52             :  */
      53             : void
      54  3988506470 : xfs_trans_log_dquot(
      55             :         struct xfs_trans        *tp,
      56             :         struct xfs_dquot        *dqp)
      57             : {
      58  3988506470 :         ASSERT(XFS_DQ_IS_LOCKED(dqp));
      59             : 
      60             :         /* Upgrade the dquot to bigtime format if possible. */
      61  3988520417 :         if (dqp->q_id != 0 &&
      62   256492130 :             xfs_has_bigtime(tp->t_mountp) &&
      63   256303110 :             !(dqp->q_type & XFS_DQTYPE_BIGTIME))
      64         497 :                 dqp->q_type |= XFS_DQTYPE_BIGTIME;
      65             : 
      66  3988520417 :         tp->t_flags |= XFS_TRANS_DIRTY;
      67  3988520417 :         set_bit(XFS_LI_DIRTY, &dqp->q_logitem.qli_item.li_flags);
      68  3988639406 : }
      69             : 
      70             : /*
      71             :  * Carry forward whatever is left of the quota blk reservation to
      72             :  * the spanky new transaction
      73             :  */
      74             : void
      75  1330737966 : xfs_trans_dup_dqinfo(
      76             :         struct xfs_trans        *otp,
      77             :         struct xfs_trans        *ntp)
      78             : {
      79  1330737966 :         struct xfs_dqtrx        *oq, *nq;
      80  1330737966 :         int                     i, j;
      81  1330737966 :         struct xfs_dqtrx        *oqa, *nqa;
      82  1330737966 :         uint64_t                blk_res_used;
      83             : 
      84  1330737966 :         if (!otp->t_dqinfo)
      85             :                 return;
      86             : 
      87   846055814 :         xfs_trans_alloc_dqinfo(ntp);
      88             : 
      89  4228426609 :         for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
      90  2536432247 :                 oqa = otp->t_dqinfo->dqs[j];
      91  2536819833 :                 nqa = ntp->t_dqinfo->dqs[j];
      92  5074831703 :                 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
      93  5075688506 :                         blk_res_used = 0;
      94             : 
      95  5075688506 :                         if (oqa[i].qt_dquot == NULL)
      96             :                                 break;
      97  2538624478 :                         oq = &oqa[i];
      98  2538624478 :                         nq = &nqa[i];
      99             : 
     100  2538624478 :                         if (oq->qt_blk_res && oq->qt_bcount_delta > 0)
     101   312250094 :                                 blk_res_used = oq->qt_bcount_delta;
     102             : 
     103  2538624478 :                         nq->qt_dquot = oq->qt_dquot;
     104  2538624478 :                         nq->qt_bcount_delta = nq->qt_icount_delta = 0;
     105  2538624478 :                         nq->qt_rtbcount_delta = 0;
     106             : 
     107             :                         /*
     108             :                          * Transfer whatever is left of the reservations.
     109             :                          */
     110  2538624478 :                         nq->qt_blk_res = oq->qt_blk_res - blk_res_used;
     111  2538624478 :                         oq->qt_blk_res = blk_res_used;
     112             : 
     113  2538624478 :                         nq->qt_rtblk_res = oq->qt_rtblk_res -
     114  2538624478 :                                 oq->qt_rtblk_res_used;
     115  2538624478 :                         oq->qt_rtblk_res = oq->qt_rtblk_res_used;
     116             : 
     117  2538624478 :                         nq->qt_ino_res = oq->qt_ino_res - oq->qt_ino_res_used;
     118  2538624478 :                         oq->qt_ino_res = oq->qt_ino_res_used;
     119             : 
     120             :                 }
     121             :         }
     122             : }
     123             : 
     124             : #ifdef CONFIG_XFS_LIVE_HOOKS
     125             : /*
     126             :  * Use a static key here to reduce the overhead of quota live updates.  If the
     127             :  * compiler supports jump labels, the static branch will be replaced by a nop
     128             :  * sled when there are no hook users.  Online fsck is currently the only
     129             :  * caller, so this is a reasonable tradeoff.
     130             :  *
     131             :  * Note: Patching the kernel code requires taking the cpu hotplug lock.  Other
     132             :  * parts of the kernel allocate memory with that lock held, which means that
     133             :  * XFS callers cannot hold any locks that might be used by memory reclaim or
     134             :  * writeback when calling the static_branch_{inc,dec} functions.
     135             :  */
     136             : DEFINE_STATIC_XFS_HOOK_SWITCH(xfs_dqtrx_hooks_switch);
     137             : 
     138             : void
     139       18677 : xfs_dqtrx_hook_disable(void)
     140             : {
     141       18677 :         xfs_hooks_switch_off(&xfs_dqtrx_hooks_switch);
     142       18677 : }
     143             : 
     144             : void
     145       18677 : xfs_dqtrx_hook_enable(void)
     146             : {
     147       18677 :         xfs_hooks_switch_on(&xfs_dqtrx_hooks_switch);
     148       18677 : }
     149             : 
     150             : /* Schedule a transactional dquot update on behalf of an inode. */
     151             : void
     152  1200153699 : xfs_trans_mod_ino_dquot(
     153             :         struct xfs_trans                *tp,
     154             :         struct xfs_inode                *ip,
     155             :         struct xfs_dquot                *dqp,
     156             :         unsigned int                    field,
     157             :         int64_t                         delta)
     158             : {
     159  1200153699 :         xfs_trans_mod_dquot(tp, dqp, field, delta);
     160             : 
     161  1210558592 :         if (xfs_hooks_switched_on(&xfs_dqtrx_hooks_switch)) {
     162    10605158 :                 struct xfs_mod_ino_dqtrx_params p = {
     163    10605158 :                         .tx_id          = (uintptr_t)tp,
     164    10605158 :                         .ino            = ip->i_ino,
     165             :                         .q_type         = xfs_dquot_type(dqp),
     166    10605158 :                         .q_id           = dqp->q_id,
     167             :                         .delta          = delta
     168             :                 };
     169    10605158 :                 struct xfs_quotainfo    *qi = tp->t_mountp->m_quotainfo;
     170             : 
     171    10605158 :                 xfs_hooks_call(&qi->qi_mod_ino_dqtrx_hooks, field, &p);
     172             :         }
     173  1199950667 : }
     174             : 
     175             : /* Call the specified functions during a dquot counter update. */
     176             : int
     177       18662 : xfs_dqtrx_hook_add(
     178             :         struct xfs_quotainfo    *qi,
     179             :         struct xfs_dqtrx_hook   *hook)
     180             : {
     181       18662 :         int                     error;
     182             : 
     183             :         /*
     184             :          * Transactional dquot updates first call the mod hook when changes
     185             :          * are attached to the transaction and then call the apply hook when
     186             :          * those changes are committed (or canceled).
     187             :          *
     188             :          * The apply hook must be installed before the mod hook so that we
     189             :          * never fail to catch the end of a quota update sequence.
     190             :          */
     191       18662 :         error = xfs_hooks_add(&qi->qi_apply_dqtrx_hooks, &hook->apply_hook);
     192       18662 :         if (error)
     193           0 :                 goto out;
     194             : 
     195       18662 :         error = xfs_hooks_add(&qi->qi_mod_ino_dqtrx_hooks, &hook->mod_hook);
     196       18662 :         if (error)
     197           0 :                 goto out_apply;
     198             : 
     199             :         return 0;
     200             : 
     201             : out_apply:
     202           0 :         xfs_hooks_del(&qi->qi_apply_dqtrx_hooks, &hook->apply_hook);
     203             : out:
     204             :         return error;
     205             : }
     206             : 
     207             : /* Stop calling the specified function during a dquot counter update. */
     208             : void
     209       18662 : xfs_dqtrx_hook_del(
     210             :         struct xfs_quotainfo    *qi,
     211             :         struct xfs_dqtrx_hook   *hook)
     212             : {
     213             :         /*
     214             :          * The mod hook must be removed before apply hook to avoid giving the
     215             :          * hook consumer with an incomplete update.  No hooks should be running
     216             :          * after these functions return.
     217             :          */
     218       18662 :         xfs_hooks_del(&qi->qi_mod_ino_dqtrx_hooks, &hook->mod_hook);
     219       18662 :         xfs_hooks_del(&qi->qi_apply_dqtrx_hooks, &hook->apply_hook);
     220       18662 : }
     221             : #endif /* CONFIG_XFS_LIVE_HOOKS */
     222             : 
     223             : /*
     224             :  * Wrap around mod_dquot to account for both user and group quotas.
     225             :  */
     226             : void
     227   572187249 : xfs_trans_mod_dquot_byino(
     228             :         xfs_trans_t     *tp,
     229             :         xfs_inode_t     *ip,
     230             :         uint            field,
     231             :         int64_t         delta)
     232             : {
     233   572187249 :         xfs_mount_t     *mp = tp->t_mountp;
     234             : 
     235   954874840 :         if (!XFS_IS_QUOTA_ON(mp) ||
     236   382687591 :             xfs_is_quota_inode(&mp->m_sb, ip->i_ino))
     237             :                 return;
     238             : 
     239   379726613 :         if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
     240   379700114 :                 xfs_trans_mod_ino_dquot(tp, ip, ip->i_udquot, field, delta);
     241   379333810 :         if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot)
     242   378707867 :                 xfs_trans_mod_ino_dquot(tp, ip, ip->i_gdquot, field, delta);
     243   379517259 :         if (XFS_IS_PQUOTA_ON(mp) && ip->i_pdquot)
     244   378739159 :                 xfs_trans_mod_ino_dquot(tp, ip, ip->i_pdquot, field, delta);
     245             : }
     246             : 
     247             : STATIC struct xfs_dqtrx *
     248  3247931602 : xfs_trans_get_dqtrx(
     249             :         struct xfs_trans        *tp,
     250             :         struct xfs_dquot        *dqp)
     251             : {
     252  3247931602 :         int                     i;
     253  3247931602 :         struct xfs_dqtrx        *qa;
     254             : 
     255  3247931602 :         switch (xfs_dquot_type(dqp)) {
     256  1095602637 :         case XFS_DQTYPE_USER:
     257  1095602637 :                 qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_USR];
     258  1095602637 :                 break;
     259  1093203138 :         case XFS_DQTYPE_GROUP:
     260  1093203138 :                 qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_GRP];
     261  1093203138 :                 break;
     262  1059125827 :         case XFS_DQTYPE_PROJ:
     263  1059125827 :                 qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_PRJ];
     264  1059125827 :                 break;
     265             :         default:
     266             :                 return NULL;
     267             :         }
     268             : 
     269  3267640651 :         for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
     270  3266264494 :                 if (qa[i].qt_dquot == NULL ||
     271             :                     qa[i].qt_dquot == dqp)
     272  3246555445 :                         return &qa[i];
     273             :         }
     274             : 
     275             :         return NULL;
     276             : }
     277             : 
     278             : /*
     279             :  * Make the changes in the transaction structure.
     280             :  * The moral equivalent to xfs_trans_mod_sb().
     281             :  * We don't touch any fields in the dquot, so we don't care
     282             :  * if it's locked or not (most of the time it won't be).
     283             :  */
     284             : void
     285  8368738699 : xfs_trans_mod_dquot(
     286             :         struct xfs_trans        *tp,
     287             :         struct xfs_dquot        *dqp,
     288             :         uint                    field,
     289             :         int64_t                 delta)
     290             : {
     291  8368738699 :         struct xfs_dqtrx        *qtrx;
     292             : 
     293  8368738699 :         ASSERT(tp);
     294  8368738699 :         ASSERT(XFS_IS_QUOTA_ON(tp->t_mountp));
     295  8368738699 :         qtrx = NULL;
     296             : 
     297  8368738699 :         if (!delta)
     298             :                 return;
     299             : 
     300  3245316163 :         if (tp->t_dqinfo == NULL)
     301   707527118 :                 xfs_trans_alloc_dqinfo(tp);
     302             :         /*
     303             :          * Find either the first free slot or the slot that belongs
     304             :          * to this dquot.
     305             :          */
     306  3245377688 :         qtrx = xfs_trans_get_dqtrx(tp, dqp);
     307  3245377688 :         ASSERT(qtrx);
     308  3245377688 :         if (qtrx->qt_dquot == NULL)
     309  2126727874 :                 qtrx->qt_dquot = dqp;
     310             : 
     311  3245377688 :         trace_xfs_trans_mod_dquot_before(qtrx);
     312  3246397517 :         trace_xfs_trans_mod_dquot(tp, dqp, field, delta);
     313             : 
     314  3247355515 :         switch (field) {
     315             :         /* regular disk blk reservation */
     316  1905207680 :         case XFS_TRANS_DQ_RES_BLKS:
     317  1905207680 :                 qtrx->qt_blk_res += delta;
     318  1905207680 :                 break;
     319             : 
     320             :         /* inode reservation */
     321   218529262 :         case XFS_TRANS_DQ_RES_INOS:
     322   218529262 :                 qtrx->qt_ino_res += delta;
     323   218529262 :                 break;
     324             : 
     325             :         /* disk blocks used. */
     326   685956901 :         case XFS_TRANS_DQ_BCOUNT:
     327   685956901 :                 qtrx->qt_bcount_delta += delta;
     328   685956901 :                 break;
     329             : 
     330    92133624 :         case XFS_TRANS_DQ_DELBCOUNT:
     331    92133624 :                 qtrx->qt_delbcnt_delta += delta;
     332    92133624 :                 break;
     333             : 
     334             :         /* Inode Count */
     335   345528048 :         case XFS_TRANS_DQ_ICOUNT:
     336   345528048 :                 if (qtrx->qt_ino_res && delta > 0) {
     337   206168186 :                         qtrx->qt_ino_res_used += delta;
     338   206168186 :                         ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
     339             :                 }
     340   345528048 :                 qtrx->qt_icount_delta += delta;
     341   345528048 :                 break;
     342             : 
     343             :         /* rtblk reservation */
     344           0 :         case XFS_TRANS_DQ_RES_RTBLKS:
     345           0 :                 qtrx->qt_rtblk_res += delta;
     346           0 :                 break;
     347             : 
     348             :         /* rtblk count */
     349           0 :         case XFS_TRANS_DQ_RTBCOUNT:
     350           0 :                 if (qtrx->qt_rtblk_res && delta > 0) {
     351           0 :                         qtrx->qt_rtblk_res_used += delta;
     352           0 :                         ASSERT(qtrx->qt_rtblk_res >= qtrx->qt_rtblk_res_used);
     353             :                 }
     354           0 :                 qtrx->qt_rtbcount_delta += delta;
     355           0 :                 break;
     356             : 
     357           0 :         case XFS_TRANS_DQ_DELRTBCOUNT:
     358           0 :                 qtrx->qt_delrtb_delta += delta;
     359           0 :                 break;
     360             : 
     361           0 :         default:
     362           0 :                 ASSERT(0);
     363             :         }
     364             : 
     365  3247355515 :         trace_xfs_trans_mod_dquot_after(qtrx);
     366             : }
     367             : 
     368             : 
     369             : /*
     370             :  * Given an array of dqtrx structures, lock all the dquots associated and join
     371             :  * them to the transaction, provided they have been modified.
     372             :  */
     373             : STATIC void
     374  3968789719 : xfs_trans_dqlockedjoin(
     375             :         struct xfs_trans        *tp,
     376             :         struct xfs_dqtrx        *q)
     377             : {
     378  3968789719 :         unsigned int            i;
     379  3968789719 :         ASSERT(q[0].qt_dquot != NULL);
     380  3968789719 :         if (q[1].qt_dquot == NULL) {
     381  3950794393 :                 xfs_dqlock(q[0].qt_dquot);
     382  3952462628 :                 xfs_trans_dqjoin(tp, q[0].qt_dquot);
     383    17995326 :         } else if (q[2].qt_dquot == NULL) {
     384    17992393 :                 xfs_dqlock2(q[0].qt_dquot, q[1].qt_dquot);
     385    18051680 :                 xfs_trans_dqjoin(tp, q[0].qt_dquot);
     386    18051575 :                 xfs_trans_dqjoin(tp, q[1].qt_dquot);
     387             :         } else {
     388        2933 :                 xfs_dqlockn(q);
     389       14665 :                 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
     390       11732 :                         if (q[i].qt_dquot == NULL)
     391             :                                 break;
     392        8799 :                         xfs_trans_dqjoin(tp, q[i].qt_dquot);
     393             :                 }
     394             :         }
     395  3970451692 : }
     396             : 
     397             : /* Apply dqtrx changes to the quota reservation counters. */
     398             : static inline void
     399             : xfs_apply_quota_reservation_deltas(
     400             :         struct xfs_dquot_res    *res,
     401             :         uint64_t                reserved,
     402             :         int64_t                 res_used,
     403             :         int64_t                 count_delta)
     404             : {
     405 11965673088 :         if (reserved != 0) {
     406             :                 /*
     407             :                  * Subtle math here: If reserved > res_used (the normal case),
     408             :                  * we're simply subtracting the unused transaction quota
     409             :                  * reservation from the dquot reservation.
     410             :                  *
     411             :                  * If, however, res_used > reserved, then we have allocated
     412             :                  * more quota blocks than were reserved for the transaction.
     413             :                  * We must add that excess to the dquot reservation since it
     414             :                  * tracks (usage + resv) and by definition we didn't reserve
     415             :                  * that excess.
     416             :                  */
     417  1666079570 :                 res->reserved -= abs(reserved - res_used);
     418 10299593518 :         } else if (count_delta != 0) {
     419             :                 /*
     420             :                  * These blks were never reserved, either inside a transaction
     421             :                  * or outside one (in a delayed allocation). Also, this isn't
     422             :                  * always a negative number since we sometimes deliberately
     423             :                  * skip quota reservations.
     424             :                  */
     425   403889740 :                 res->reserved += count_delta;
     426             :         }
     427             : }
     428             : 
     429             : #ifdef CONFIG_XFS_LIVE_HOOKS
     430             : /* Call downstream hooks now that it's time to apply dquot deltas. */
     431             : static inline void
     432  3988496525 : xfs_trans_apply_dquot_deltas_hook(
     433             :         struct xfs_trans                *tp,
     434             :         struct xfs_dquot                *dqp)
     435             : {
     436  4024039592 :         if (xfs_hooks_switched_on(&xfs_dqtrx_hooks_switch)) {
     437    35542470 :                 struct xfs_apply_dqtrx_params   p = {
     438    35542470 :                         .tx_id          = (uintptr_t)tp,
     439             :                         .q_type         = xfs_dquot_type(dqp),
     440    35542470 :                         .q_id           = dqp->q_id,
     441             :                 };
     442    35542470 :                 struct xfs_quotainfo    *qi = tp->t_mountp->m_quotainfo;
     443             : 
     444    35542470 :                 xfs_hooks_call(&qi->qi_apply_dqtrx_hooks,
     445             :                                 XFS_APPLY_DQTRX_COMMIT, &p);
     446             :         }
     447  3988504715 : }
     448             : #else
     449             : # define xfs_trans_apply_dquot_deltas_hook(tp, dqp)     ((void)0)
     450             : #endif /* CONFIG_XFS_LIVE_HOOKS */
     451             : 
     452             : /*
     453             :  * Called by xfs_trans_commit() and similar in spirit to
     454             :  * xfs_trans_apply_sb_deltas().
     455             :  * Go thru all the dquots belonging to this transaction and modify the
     456             :  * INCORE dquot to reflect the actual usages.
     457             :  * Unreserve just the reservations done by this transaction.
     458             :  * dquot is still left locked at exit.
     459             :  */
     460             : void
     461  2449458755 : xfs_trans_apply_dquot_deltas(
     462             :         struct xfs_trans        *tp)
     463             : {
     464  2449458755 :         int                     i, j;
     465  2449458755 :         struct xfs_dquot        *dqp;
     466  2449458755 :         struct xfs_dqtrx        *qtrx, *qa;
     467  2449458755 :         int64_t                 totalbdelta;
     468  2449458755 :         int64_t                 totalrtbdelta;
     469             : 
     470  2449458755 :         if (!tp->t_dqinfo)
     471             :                 return;
     472             : 
     473             :         ASSERT(tp->t_dqinfo);
     474  5309667509 :         for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
     475  3981996788 :                 qa = tp->t_dqinfo->dqs[j];
     476  3981467786 :                 if (qa[0].qt_dquot == NULL)
     477    12458526 :                         continue;
     478             : 
     479             :                 /*
     480             :                  * Lock all of the dquots and join them to the transaction.
     481             :                  */
     482  3969009260 :                 xfs_trans_dqlockedjoin(tp, qa);
     483             : 
     484 11928011709 :                 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
     485  7959002449 :                         uint64_t        blk_res_used;
     486             : 
     487  7959002449 :                         qtrx = &qa[i];
     488             :                         /*
     489             :                          * The array of dquots is filled
     490             :                          * sequentially, not sparsely.
     491             :                          */
     492  7959002449 :                         if ((dqp = qtrx->qt_dquot) == NULL)
     493             :                                 break;
     494             : 
     495  3988524991 :                         ASSERT(XFS_DQ_IS_LOCKED(dqp));
     496             : 
     497  3988504566 :                         xfs_trans_apply_dquot_deltas_hook(tp, dqp);
     498             : 
     499             :                         /*
     500             :                          * adjust the actual number of blocks used
     501             :                          */
     502             : 
     503             :                         /*
     504             :                          * The issue here is - sometimes we don't make a blkquota
     505             :                          * reservation intentionally to be fair to users
     506             :                          * (when the amount is small). On the other hand,
     507             :                          * delayed allocs do make reservations, but that's
     508             :                          * outside of a transaction, so we have no
     509             :                          * idea how much was really reserved.
     510             :                          * So, here we've accumulated delayed allocation blks and
     511             :                          * non-delay blks. The assumption is that the
     512             :                          * delayed ones are always reserved (outside of a
     513             :                          * transaction), and the others may or may not have
     514             :                          * quota reservations.
     515             :                          */
     516  3988525899 :                         totalbdelta = qtrx->qt_bcount_delta +
     517  3988525899 :                                 qtrx->qt_delbcnt_delta;
     518  3988525899 :                         totalrtbdelta = qtrx->qt_rtbcount_delta +
     519  3988525899 :                                 qtrx->qt_delrtb_delta;
     520             : 
     521  3988525899 :                         if (totalbdelta != 0 || totalrtbdelta != 0 ||
     522  3355967121 :                             qtrx->qt_icount_delta != 0) {
     523   930833114 :                                 trace_xfs_trans_apply_dquot_deltas_before(dqp);
     524   930828663 :                                 trace_xfs_trans_apply_dquot_deltas(qtrx);
     525             :                         }
     526             : 
     527             : #ifdef DEBUG
     528  3988511578 :                         if (totalbdelta < 0)
     529   242588838 :                                 ASSERT(dqp->q_blk.count >= -totalbdelta);
     530             : 
     531  3988511578 :                         if (totalrtbdelta < 0)
     532           0 :                                 ASSERT(dqp->q_rtb.count >= -totalrtbdelta);
     533             : 
     534  3988511578 :                         if (qtrx->qt_icount_delta < 0)
     535   139739156 :                                 ASSERT(dqp->q_ino.count >= -qtrx->qt_icount_delta);
     536             : #endif
     537  3988511578 :                         if (totalbdelta)
     538   632556847 :                                 dqp->q_blk.count += totalbdelta;
     539             : 
     540  3988511578 :                         if (qtrx->qt_icount_delta)
     541   347098492 :                                 dqp->q_ino.count += qtrx->qt_icount_delta;
     542             : 
     543  3988511578 :                         if (totalrtbdelta)
     544           0 :                                 dqp->q_rtb.count += totalrtbdelta;
     545             : 
     546  3988511578 :                         if (totalbdelta != 0 || totalrtbdelta != 0 ||
     547  3355955910 :                             qtrx->qt_icount_delta != 0)
     548   930828638 :                                 trace_xfs_trans_apply_dquot_deltas_after(dqp);
     549             : 
     550             :                         /*
     551             :                          * Get any default limits in use.
     552             :                          * Start/reset the timer(s) if needed.
     553             :                          */
     554  3988508049 :                         if (dqp->q_id) {
     555   256446970 :                                 xfs_qm_adjust_dqlimits(dqp);
     556   256443041 :                                 xfs_qm_adjust_dqtimers(dqp);
     557             :                         }
     558             : 
     559  3988495547 :                         dqp->q_flags |= XFS_DQFLAG_DIRTY;
     560             :                         /*
     561             :                          * add this to the list of items to get logged
     562             :                          */
     563  3988495547 :                         xfs_trans_log_dquot(tp, dqp);
     564             :                         /*
     565             :                          * Take off what's left of the original reservation.
     566             :                          * In case of delayed allocations, there's no
     567             :                          * reservation that a transaction structure knows of.
     568             :                          */
     569  3988557696 :                         blk_res_used = max_t(int64_t, 0, qtrx->qt_bcount_delta);
     570  3988557696 :                         xfs_apply_quota_reservation_deltas(&dqp->q_blk,
     571             :                                         qtrx->qt_blk_res, blk_res_used,
     572             :                                         qtrx->qt_bcount_delta);
     573             : 
     574             :                         /*
     575             :                          * Adjust the RT reservation.
     576             :                          */
     577  3988557696 :                         xfs_apply_quota_reservation_deltas(&dqp->q_rtb,
     578             :                                         qtrx->qt_rtblk_res,
     579  3988557696 :                                         qtrx->qt_rtblk_res_used,
     580             :                                         qtrx->qt_rtbcount_delta);
     581             : 
     582             :                         /*
     583             :                          * Adjust the inode reservation.
     584             :                          */
     585  3988557696 :                         ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
     586  3988557696 :                         xfs_apply_quota_reservation_deltas(&dqp->q_ino,
     587             :                                         qtrx->qt_ino_res,
     588  3988557696 :                                         qtrx->qt_ino_res_used,
     589             :                                         qtrx->qt_icount_delta);
     590             : 
     591  3988557696 :                         ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
     592  3988557696 :                         ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
     593  3988557696 :                         ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
     594             :                 }
     595             :         }
     596             : }
     597             : 
     598             : #ifdef CONFIG_XFS_LIVE_HOOKS
     599             : /* Call downstream hooks now that it's time to cancel dquot deltas. */
     600             : static inline void
     601   679211597 : xfs_trans_unreserve_and_mod_dquots_hook(
     602             :         struct xfs_trans                *tp,
     603             :         struct xfs_dquot                *dqp)
     604             : {
     605   696545593 :         if (xfs_hooks_switched_on(&xfs_dqtrx_hooks_switch)) {
     606    17333581 :                 struct xfs_apply_dqtrx_params   p = {
     607    17333581 :                         .tx_id          = (uintptr_t)tp,
     608             :                         .q_type         = xfs_dquot_type(dqp),
     609    17333581 :                         .q_id           = dqp->q_id,
     610             :                 };
     611    17333581 :                 struct xfs_quotainfo    *qi = tp->t_mountp->m_quotainfo;
     612             : 
     613    17333581 :                 xfs_hooks_call(&qi->qi_apply_dqtrx_hooks,
     614             :                                 XFS_APPLY_DQTRX_UNRESERVE, &p);
     615             :         }
     616   679214247 : }
     617             : #else
     618             : # define xfs_trans_unreserve_and_mod_dquots_hook(tp, dqp)       ((void)0)
     619             : #endif /* CONFIG_XFS_LIVE_HOOKS */
     620             : 
     621             : /*
     622             :  * Release the reservations, and adjust the dquots accordingly.
     623             :  * This is called only when the transaction is being aborted. If by
     624             :  * any chance we have done dquot modifications incore (ie. deltas) already,
     625             :  * we simply throw those away, since that's the expected behavior
     626             :  * when a transaction is curtailed without a commit.
     627             :  */
     628             : void
     629  2054874807 : xfs_trans_unreserve_and_mod_dquots(
     630             :         struct xfs_trans        *tp)
     631             : {
     632  2054874807 :         int                     i, j;
     633  2054874807 :         struct xfs_dquot        *dqp;
     634  2054874807 :         struct xfs_dqtrx        *qtrx, *qa;
     635  2054874807 :         bool                    locked;
     636             : 
     637  2054874807 :         if (!tp->t_dqinfo)
     638             :                 return;
     639             : 
     640   905160618 :         for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
     641   678861995 :                 qa = tp->t_dqinfo->dqs[j];
     642             : 
     643  1357907032 :                 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
     644  1357910387 :                         qtrx = &qa[i];
     645             :                         /*
     646             :                          * We assume that the array of dquots is filled
     647             :                          * sequentially, not sparsely.
     648             :                          */
     649  1357910387 :                         if ((dqp = qtrx->qt_dquot) == NULL)
     650             :                                 break;
     651             : 
     652   679233735 :                         xfs_trans_unreserve_and_mod_dquots_hook(tp, dqp);
     653             : 
     654             :                         /*
     655             :                          * Unreserve the original reservation. We don't care
     656             :                          * about the number of blocks used field, or deltas.
     657             :                          * Also we don't bother to zero the fields.
     658             :                          */
     659   679121214 :                         locked = false;
     660   679121214 :                         if (qtrx->qt_blk_res) {
     661   678255426 :                                 xfs_dqlock(dqp);
     662   678356784 :                                 locked = true;
     663   678356784 :                                 dqp->q_blk.reserved -=
     664   678356784 :                                         (xfs_qcnt_t)qtrx->qt_blk_res;
     665             :                         }
     666   679222572 :                         if (qtrx->qt_ino_res) {
     667    11161845 :                                 if (!locked) {
     668           3 :                                         xfs_dqlock(dqp);
     669           3 :                                         locked = true;
     670             :                                 }
     671    11161845 :                                 dqp->q_ino.reserved -=
     672    11161845 :                                         (xfs_qcnt_t)qtrx->qt_ino_res;
     673             :                         }
     674             : 
     675   679222572 :                         if (qtrx->qt_rtblk_res) {
     676           0 :                                 if (!locked) {
     677           0 :                                         xfs_dqlock(dqp);
     678           0 :                                         locked = true;
     679             :                                 }
     680           0 :                                 dqp->q_rtb.reserved -=
     681           0 :                                         (xfs_qcnt_t)qtrx->qt_rtblk_res;
     682             :                         }
     683   679222572 :                         if (locked)
     684   678336021 :                                 xfs_dqunlock(dqp);
     685             : 
     686             :                 }
     687             :         }
     688             : }
     689             : 
     690             : STATIC void
     691       80453 : xfs_quota_warn(
     692             :         struct xfs_mount        *mp,
     693             :         struct xfs_dquot        *dqp,
     694             :         int                     type)
     695             : {
     696       80453 :         enum quota_type         qtype;
     697             : 
     698       80453 :         switch (xfs_dquot_type(dqp)) {
     699             :         case XFS_DQTYPE_PROJ:
     700             :                 qtype = PRJQUOTA;
     701             :                 break;
     702       54343 :         case XFS_DQTYPE_USER:
     703       54343 :                 qtype = USRQUOTA;
     704       54343 :                 break;
     705       12909 :         case XFS_DQTYPE_GROUP:
     706       12909 :                 qtype = GRPQUOTA;
     707       12909 :                 break;
     708             :         default:
     709             :                 return;
     710             :         }
     711             : 
     712       80453 :         quota_send_warning(make_kqid(&init_user_ns, qtype, dqp->q_id),
     713       80453 :                            mp->m_super->s_dev, type);
     714             : }
     715             : 
     716             : /*
     717             :  * Decide if we can make an additional reservation against a quota resource.
     718             :  * Returns an inode QUOTA_NL_ warning code and whether or not it's fatal.
     719             :  *
     720             :  * Note that we assume that the numeric difference between the inode and block
     721             :  * warning codes will always be 3 since it's userspace ABI now, and will never
     722             :  * decrease the quota reservation, so the *BELOW messages are irrelevant.
     723             :  */
     724             : static inline int
     725   582921499 : xfs_dqresv_check(
     726             :         struct xfs_dquot_res    *res,
     727             :         struct xfs_quota_limits *qlim,
     728             :         int64_t                 delta,
     729             :         bool                    *fatal)
     730             : {
     731   582921499 :         xfs_qcnt_t              hardlimit = res->hardlimit;
     732   582921499 :         xfs_qcnt_t              softlimit = res->softlimit;
     733   582921499 :         xfs_qcnt_t              total_count = res->reserved + delta;
     734             : 
     735   582921499 :         BUILD_BUG_ON(QUOTA_NL_BHARDWARN     != QUOTA_NL_IHARDWARN + 3);
     736   582921499 :         BUILD_BUG_ON(QUOTA_NL_BSOFTLONGWARN != QUOTA_NL_ISOFTLONGWARN + 3);
     737   582921499 :         BUILD_BUG_ON(QUOTA_NL_BSOFTWARN     != QUOTA_NL_ISOFTWARN + 3);
     738             : 
     739   582921499 :         *fatal = false;
     740   582921499 :         if (delta <= 0)
     741             :                 return QUOTA_NL_NOWARN;
     742             : 
     743   131774695 :         if (!hardlimit)
     744   131494062 :                 hardlimit = qlim->hard;
     745   131774695 :         if (!softlimit)
     746   131495137 :                 softlimit = qlim->soft;
     747             : 
     748   131774695 :         if (hardlimit && total_count > hardlimit) {
     749       43732 :                 *fatal = true;
     750       43732 :                 return QUOTA_NL_IHARDWARN;
     751             :         }
     752             : 
     753   131730963 :         if (softlimit && total_count > softlimit) {
     754       36721 :                 time64_t        now = ktime_get_real_seconds();
     755             : 
     756       36721 :                 if (res->timer != 0 && now > res->timer) {
     757         132 :                         *fatal = true;
     758         132 :                         return QUOTA_NL_ISOFTLONGWARN;
     759             :                 }
     760             : 
     761             :                 return QUOTA_NL_ISOFTWARN;
     762             :         }
     763             : 
     764             :         return QUOTA_NL_NOWARN;
     765             : }
     766             : 
     767             : /*
     768             :  * This reserves disk blocks and inodes against a dquot.
     769             :  * Flags indicate if the dquot is to be locked here and also
     770             :  * if the blk reservation is for RT or regular blocks.
     771             :  * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
     772             :  */
     773             : STATIC int
     774  3946309650 : xfs_trans_dqresv(
     775             :         struct xfs_trans        *tp,
     776             :         struct xfs_mount        *mp,
     777             :         struct xfs_dquot        *dqp,
     778             :         int64_t                 nblks,
     779             :         long                    ninos,
     780             :         uint                    flags)
     781             : {
     782  3946309650 :         struct xfs_quotainfo    *q = mp->m_quotainfo;
     783  3946309650 :         struct xfs_def_quota    *defq;
     784  3946309650 :         struct xfs_dquot_res    *blkres;
     785  3946309650 :         struct xfs_quota_limits *qlim;
     786             : 
     787  3946309650 :         xfs_dqlock(dqp);
     788             : 
     789  3946250826 :         defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
     790             : 
     791  3946466730 :         if (flags & XFS_TRANS_DQ_RES_BLKS) {
     792  2082655157 :                 blkres = &dqp->q_blk;
     793  2082655157 :                 qlim = &defq->blk;
     794             :         } else {
     795  1863811573 :                 blkres = &dqp->q_rtb;
     796  1863811573 :                 qlim = &defq->rtb;
     797             :         }
     798             : 
     799  4238094715 :         if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
     800   291633155 :             xfs_dquot_is_enforced(dqp)) {
     801   291483944 :                 int             quota_nl;
     802   291483944 :                 bool            fatal;
     803             : 
     804             :                 /*
     805             :                  * dquot is locked already. See if we'd go over the hardlimit
     806             :                  * or exceed the timelimit if we'd reserve resources.
     807             :                  */
     808   291483944 :                 quota_nl = xfs_dqresv_check(blkres, qlim, nblks, &fatal);
     809   291481597 :                 if (quota_nl != QUOTA_NL_NOWARN) {
     810             :                         /*
     811             :                          * Quota block warning codes are 3 more than the inode
     812             :                          * codes, which we check above.
     813             :                          */
     814       78388 :                         xfs_quota_warn(mp, dqp, quota_nl + 3);
     815       78388 :                         if (fatal)
     816       42147 :                                 goto error_return;
     817             :                 }
     818             : 
     819   291439450 :                 quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->ino, ninos,
     820             :                                 &fatal);
     821   291443842 :                 if (quota_nl != QUOTA_NL_NOWARN) {
     822        2065 :                         xfs_quota_warn(mp, dqp, quota_nl);
     823        2065 :                         if (fatal)
     824        1717 :                                 goto error_return;
     825             :                 }
     826             :         }
     827             : 
     828             :         /*
     829             :          * Change the reservation, but not the actual usage.
     830             :          * Note that q_blk.reserved = q_blk.count + resv
     831             :          */
     832  3946419741 :         blkres->reserved += (xfs_qcnt_t)nblks;
     833  3946419741 :         dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
     834             : 
     835             :         /*
     836             :          * note the reservation amt in the trans struct too,
     837             :          * so that the transaction knows how much was reserved by
     838             :          * it against this particular dquot.
     839             :          * We don't do this when we are reserving for a delayed allocation,
     840             :          * because we don't have the luxury of a transaction envelope then.
     841             :          */
     842  3946419741 :         if (tp) {
     843  3578087477 :                 ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
     844  3578087477 :                 xfs_trans_mod_dquot(tp, dqp, flags & XFS_QMOPT_RESBLK_MASK,
     845             :                                     nblks);
     846  3577064989 :                 xfs_trans_mod_dquot(tp, dqp, XFS_TRANS_DQ_RES_INOS, ninos);
     847             :         }
     848             : 
     849  3945325382 :         if (XFS_IS_CORRUPT(mp, dqp->q_blk.reserved < dqp->q_blk.count) ||
     850  3945325382 :             XFS_IS_CORRUPT(mp, dqp->q_rtb.reserved < dqp->q_rtb.count) ||
     851  3945325382 :             XFS_IS_CORRUPT(mp, dqp->q_ino.reserved < dqp->q_ino.count))
     852           0 :                 goto error_corrupt;
     853             : 
     854  3945325382 :         xfs_dqunlock(dqp);
     855  3945325382 :         return 0;
     856             : 
     857             : error_return:
     858       43864 :         xfs_dqunlock(dqp);
     859       43864 :         if (xfs_dquot_type(dqp) == XFS_DQTYPE_PROJ)
     860        1046 :                 return -ENOSPC;
     861             :         return -EDQUOT;
     862             : error_corrupt:
     863           0 :         xfs_dqunlock(dqp);
     864           0 :         xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
     865           0 :         xfs_fs_mark_sick(mp, XFS_SICK_FS_QUOTACHECK);
     866           0 :         return -EFSCORRUPTED;
     867             : }
     868             : 
     869             : 
     870             : /*
     871             :  * Given dquot(s), make disk block and/or inode reservations against them.
     872             :  * The fact that this does the reservation against user, group and
     873             :  * project quotas is important, because this follows a all-or-nothing
     874             :  * approach.
     875             :  *
     876             :  * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
     877             :  *         XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT.  Used by pquota.
     878             :  *         XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
     879             :  *         XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
     880             :  * dquots are unlocked on return, if they were not locked by caller.
     881             :  */
     882             : int
     883  1319919835 : xfs_trans_reserve_quota_bydquots(
     884             :         struct xfs_trans        *tp,
     885             :         struct xfs_mount        *mp,
     886             :         struct xfs_dquot        *udqp,
     887             :         struct xfs_dquot        *gdqp,
     888             :         struct xfs_dquot        *pdqp,
     889             :         int64_t                 nblks,
     890             :         long                    ninos,
     891             :         uint                    flags)
     892             : {
     893  1319919835 :         int             error;
     894             : 
     895  1319919835 :         if (!XFS_IS_QUOTA_ON(mp))
     896             :                 return 0;
     897             : 
     898  1319919835 :         ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
     899             : 
     900  1319919835 :         if (udqp) {
     901  1319390998 :                 error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags);
     902  1320528082 :                 if (error)
     903             :                         return error;
     904             :         }
     905             : 
     906  1321014837 :         if (gdqp) {
     907  1318199538 :                 error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
     908  1318197166 :                 if (error)
     909         736 :                         goto unwind_usr;
     910             :         }
     911             : 
     912  1321011729 :         if (pdqp) {
     913  1310074317 :                 error = xfs_trans_dqresv(tp, mp, pdqp, nblks, ninos, flags);
     914  1310081139 :                 if (error)
     915        1046 :                         goto unwind_grp;
     916             :         }
     917             : 
     918             :         /*
     919             :          * Didn't change anything critical, so, no need to log
     920             :          */
     921             :         return 0;
     922             : 
     923             : unwind_grp:
     924        1046 :         flags |= XFS_QMOPT_FORCE_RES;
     925        1046 :         if (gdqp)
     926         312 :                 xfs_trans_dqresv(tp, mp, gdqp, -nblks, -ninos, flags);
     927         734 : unwind_usr:
     928        1782 :         flags |= XFS_QMOPT_FORCE_RES;
     929        1782 :         if (udqp)
     930         492 :                 xfs_trans_dqresv(tp, mp, udqp, -nblks, -ninos, flags);
     931             :         return error;
     932             : }
     933             : 
     934             : 
     935             : /*
     936             :  * Lock the dquot and change the reservation if we can.
     937             :  * This doesn't change the actual usage, just the reservation.
     938             :  * The inode sent in is locked.
     939             :  */
     940             : int
     941   941301627 : xfs_trans_reserve_quota_nblks(
     942             :         struct xfs_trans        *tp,
     943             :         struct xfs_inode        *ip,
     944             :         int64_t                 dblocks,
     945             :         int64_t                 rblocks,
     946             :         bool                    force)
     947             : {
     948   941301627 :         struct xfs_mount        *mp = ip->i_mount;
     949   941301627 :         unsigned int            qflags = 0;
     950   941301627 :         int                     error;
     951             : 
     952   941301627 :         if (!XFS_IS_QUOTA_ON(mp))
     953             :                 return 0;
     954             : 
     955  1244348070 :         ASSERT(!xfs_is_quota_inode(&mp->m_sb, ip->i_ino));
     956   622174035 :         ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
     957             : 
     958   621962238 :         if (force)
     959   124007434 :                 qflags |= XFS_QMOPT_FORCE_RES;
     960             : 
     961             :         /* Reserve data device quota against the inode's dquots. */
     962   621962238 :         error = xfs_trans_reserve_quota_bydquots(tp, mp, ip->i_udquot,
     963             :                         ip->i_gdquot, ip->i_pdquot, dblocks, 0,
     964             :                         XFS_QMOPT_RES_REGBLKS | qflags);
     965   622533108 :         if (error)
     966             :                 return error;
     967             : 
     968             :         /* Do the same but for realtime blocks. */
     969   622502059 :         error = xfs_trans_reserve_quota_bydquots(tp, mp, ip->i_udquot,
     970             :                         ip->i_gdquot, ip->i_pdquot, rblocks, 0,
     971             :                         XFS_QMOPT_RES_RTBLKS | qflags);
     972   622492377 :         if (error) {
     973           0 :                 xfs_trans_reserve_quota_bydquots(tp, mp, ip->i_udquot,
     974             :                                 ip->i_gdquot, ip->i_pdquot, -dblocks, 0,
     975             :                                 XFS_QMOPT_RES_REGBLKS);
     976           0 :                 return error;
     977             :         }
     978             : 
     979             :         return 0;
     980             : }
     981             : 
     982             : /* Change the quota reservations for an inode creation activity. */
     983             : int
     984   134055489 : xfs_trans_reserve_quota_icreate(
     985             :         struct xfs_trans        *tp,
     986             :         struct xfs_dquot        *udqp,
     987             :         struct xfs_dquot        *gdqp,
     988             :         struct xfs_dquot        *pdqp,
     989             :         int64_t                 dblocks)
     990             : {
     991   134055489 :         struct xfs_mount        *mp = tp->t_mountp;
     992             : 
     993   134055489 :         if (!XFS_IS_QUOTA_ON(mp))
     994             :                 return 0;
     995             : 
     996    67223745 :         return xfs_trans_reserve_quota_bydquots(tp, mp, udqp, gdqp, pdqp,
     997             :                         dblocks, 1, XFS_QMOPT_RES_REGBLKS);
     998             : }
     999             : 
    1000             : STATIC void
    1001  1553386479 : xfs_trans_alloc_dqinfo(
    1002             :         xfs_trans_t     *tp)
    1003             : {
    1004  1553386479 :         tp->t_dqinfo = kmem_cache_zalloc(xfs_dqtrx_cache,
    1005             :                                          GFP_KERNEL | __GFP_NOFAIL);
    1006  1553720314 : }
    1007             : 
    1008             : void
    1009  4503364107 : xfs_trans_free_dqinfo(
    1010             :         xfs_trans_t     *tp)
    1011             : {
    1012  4503364107 :         if (!tp->t_dqinfo)
    1013             :                 return;
    1014  1553784098 :         kmem_cache_free(xfs_dqtrx_cache, tp->t_dqinfo);
    1015  1553733877 :         tp->t_dqinfo = NULL;
    1016             : }

Generated by: LCOV version 1.14