LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_refcount_btree.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 200 219 91.3 %
Date: 2023-07-31 20:08:34 Functions: 28 30 93.3 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0+
       2             : /*
       3             :  * Copyright (C) 2016 Oracle.  All Rights Reserved.
       4             :  * Author: Darrick J. Wong <darrick.wong@oracle.com>
       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_btree.h"
      14             : #include "xfs_btree_staging.h"
      15             : #include "xfs_refcount_btree.h"
      16             : #include "xfs_refcount.h"
      17             : #include "xfs_alloc.h"
      18             : #include "xfs_error.h"
      19             : #include "xfs_trace.h"
      20             : #include "xfs_trans.h"
      21             : #include "xfs_bit.h"
      22             : #include "xfs_rmap.h"
      23             : #include "xfs_ag.h"
      24             : 
      25             : static struct kmem_cache        *xfs_refcountbt_cur_cache;
      26             : 
      27             : static struct xfs_btree_cur *
      28    19370923 : xfs_refcountbt_dup_cursor(
      29             :         struct xfs_btree_cur    *cur)
      30             : {
      31    19370923 :         return xfs_refcountbt_init_cursor(cur->bc_mp, cur->bc_tp,
      32             :                         cur->bc_ag.agbp, cur->bc_ag.pag);
      33             : }
      34             : 
      35             : STATIC void
      36        3355 : xfs_refcountbt_set_root(
      37             :         struct xfs_btree_cur            *cur,
      38             :         const union xfs_btree_ptr       *ptr,
      39             :         int                             inc)
      40             : {
      41        3355 :         struct xfs_buf          *agbp = cur->bc_ag.agbp;
      42        3355 :         struct xfs_agf          *agf = agbp->b_addr;
      43        3355 :         struct xfs_perag        *pag = agbp->b_pag;
      44             : 
      45        3355 :         ASSERT(ptr->s != 0);
      46             : 
      47        3355 :         agf->agf_refcount_root = ptr->s;
      48        3355 :         be32_add_cpu(&agf->agf_refcount_level, inc);
      49        3355 :         pag->pagf_refcount_level += inc;
      50             : 
      51        3355 :         xfs_alloc_log_agf(cur->bc_tp, agbp,
      52             :                         XFS_AGF_REFCOUNT_ROOT | XFS_AGF_REFCOUNT_LEVEL);
      53        3355 : }
      54             : 
      55             : STATIC int
      56      121781 : xfs_refcountbt_alloc_block(
      57             :         struct xfs_btree_cur            *cur,
      58             :         const union xfs_btree_ptr       *start,
      59             :         union xfs_btree_ptr             *new,
      60             :         int                             *stat)
      61             : {
      62      121781 :         struct xfs_buf          *agbp = cur->bc_ag.agbp;
      63      121781 :         struct xfs_agf          *agf = agbp->b_addr;
      64      121781 :         struct xfs_alloc_arg    args;           /* block allocation args */
      65      121781 :         int                     error;          /* error return value */
      66             : 
      67      121781 :         memset(&args, 0, sizeof(args));
      68      121781 :         args.tp = cur->bc_tp;
      69      121781 :         args.mp = cur->bc_mp;
      70      121781 :         args.pag = cur->bc_ag.pag;
      71      121781 :         args.oinfo = XFS_RMAP_OINFO_REFC;
      72      121781 :         args.minlen = args.maxlen = args.prod = 1;
      73      121781 :         args.resv = XFS_AG_RESV_METADATA;
      74             : 
      75      243562 :         error = xfs_alloc_vextent_near_bno(&args,
      76      121781 :                         XFS_AGB_TO_FSB(args.mp, args.pag->pag_agno,
      77             :                                         xfs_refc_block(args.mp)));
      78      121781 :         if (error)
      79           0 :                 goto out_error;
      80      121781 :         if (args.fsbno == NULLFSBLOCK) {
      81           0 :                 *stat = 0;
      82           0 :                 return 0;
      83             :         }
      84      121781 :         ASSERT(args.agno == cur->bc_ag.pag->pag_agno);
      85      121781 :         ASSERT(args.len == 1);
      86             : 
      87      121781 :         new->s = cpu_to_be32(args.agbno);
      88      121781 :         be32_add_cpu(&agf->agf_refcount_blocks, 1);
      89      121781 :         xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_REFCOUNT_BLOCKS);
      90             : 
      91      121781 :         *stat = 1;
      92      121781 :         return 0;
      93             : 
      94             : out_error:
      95           0 :         return error;
      96             : }
      97             : 
      98             : STATIC int
      99       99642 : xfs_refcountbt_free_block(
     100             :         struct xfs_btree_cur    *cur,
     101             :         struct xfs_buf          *bp)
     102             : {
     103       99642 :         struct xfs_mount        *mp = cur->bc_mp;
     104       99642 :         struct xfs_buf          *agbp = cur->bc_ag.agbp;
     105       99642 :         struct xfs_agf          *agf = agbp->b_addr;
     106       99642 :         xfs_fsblock_t           fsbno = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
     107             : 
     108       99642 :         be32_add_cpu(&agf->agf_refcount_blocks, -1);
     109       99642 :         xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_REFCOUNT_BLOCKS);
     110       99642 :         return xfs_free_extent_later(cur->bc_tp, fsbno, 1,
     111             :                         &XFS_RMAP_OINFO_REFC, XFS_AG_RESV_METADATA, 0);
     112             : }
     113             : 
     114             : STATIC int
     115    77921996 : xfs_refcountbt_get_minrecs(
     116             :         struct xfs_btree_cur    *cur,
     117             :         int                     level)
     118             : {
     119    77921996 :         return cur->bc_mp->m_refc_mnr[level != 0];
     120             : }
     121             : 
     122             : STATIC int
     123 14318707897 : xfs_refcountbt_get_maxrecs(
     124             :         struct xfs_btree_cur    *cur,
     125             :         int                     level)
     126             : {
     127 14318707897 :         return cur->bc_mp->m_refc_mxr[level != 0];
     128             : }
     129             : 
     130             : STATIC void
     131 38913679721 : xfs_refcountbt_init_key_from_rec(
     132             :         union xfs_btree_key             *key,
     133             :         const union xfs_btree_rec       *rec)
     134             : {
     135 38913679721 :         key->refc.rc_startblock = rec->refc.rc_startblock;
     136 38913679721 : }
     137             : 
     138             : STATIC void
     139  1537435129 : xfs_refcountbt_init_high_key_from_rec(
     140             :         union xfs_btree_key             *key,
     141             :         const union xfs_btree_rec       *rec)
     142             : {
     143  1537435129 :         __u32                           x;
     144             : 
     145  1537435129 :         x = be32_to_cpu(rec->refc.rc_startblock);
     146  1537435129 :         x += be32_to_cpu(rec->refc.rc_blockcount) - 1;
     147  1537435129 :         key->refc.rc_startblock = cpu_to_be32(x);
     148  1537435129 : }
     149             : 
     150             : STATIC void
     151 11094154405 : xfs_refcountbt_init_rec_from_cur(
     152             :         struct xfs_btree_cur    *cur,
     153             :         union xfs_btree_rec     *rec)
     154             : {
     155 11094154405 :         const struct xfs_refcount_irec *irec = &cur->bc_rec.rc;
     156 11094154405 :         uint32_t                start;
     157             : 
     158 11094154405 :         start = xfs_refcount_encode_startblock(irec->rc_startblock,
     159 11094154405 :                         irec->rc_domain);
     160 11094154405 :         rec->refc.rc_startblock = cpu_to_be32(start);
     161 11094154405 :         rec->refc.rc_blockcount = cpu_to_be32(cur->bc_rec.rc.rc_blockcount);
     162 11094154405 :         rec->refc.rc_refcount = cpu_to_be32(cur->bc_rec.rc.rc_refcount);
     163 11094154405 : }
     164             : 
     165             : STATIC void
     166  5759379454 : xfs_refcountbt_init_ptr_from_cur(
     167             :         struct xfs_btree_cur    *cur,
     168             :         union xfs_btree_ptr     *ptr)
     169             : {
     170  5759379454 :         struct xfs_agf          *agf = cur->bc_ag.agbp->b_addr;
     171             : 
     172  5759379454 :         ASSERT(cur->bc_ag.pag->pag_agno == be32_to_cpu(agf->agf_seqno));
     173             : 
     174  5759379454 :         ptr->s = agf->agf_refcount_root;
     175  5759379454 : }
     176             : 
     177             : STATIC int64_t
     178 36286780873 : xfs_refcountbt_key_diff(
     179             :         struct xfs_btree_cur            *cur,
     180             :         const union xfs_btree_key       *key)
     181             : {
     182 36286780873 :         const struct xfs_refcount_key   *kp = &key->refc;
     183 36286780873 :         const struct xfs_refcount_irec  *irec = &cur->bc_rec.rc;
     184 36286780873 :         uint32_t                        start;
     185             : 
     186 36286780873 :         start = xfs_refcount_encode_startblock(irec->rc_startblock,
     187 36286780873 :                         irec->rc_domain);
     188 36286780873 :         return (int64_t)be32_to_cpu(kp->rc_startblock) - start;
     189             : }
     190             : 
     191             : STATIC int64_t
     192  5712379484 : xfs_refcountbt_diff_two_keys(
     193             :         struct xfs_btree_cur            *cur,
     194             :         const union xfs_btree_key       *k1,
     195             :         const union xfs_btree_key       *k2,
     196             :         const union xfs_btree_key       *mask)
     197             : {
     198  5712379484 :         ASSERT(!mask || mask->refc.rc_startblock);
     199             : 
     200  5712379484 :         return (int64_t)be32_to_cpu(k1->refc.rc_startblock) -
     201  5712379484 :                         be32_to_cpu(k2->refc.rc_startblock);
     202             : }
     203             : 
     204             : STATIC xfs_failaddr_t
     205     2321834 : xfs_refcountbt_verify(
     206             :         struct xfs_buf          *bp)
     207             : {
     208     2321834 :         struct xfs_mount        *mp = bp->b_mount;
     209     2321834 :         struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
     210     2321834 :         struct xfs_perag        *pag = bp->b_pag;
     211     2321834 :         xfs_failaddr_t          fa;
     212     2321834 :         unsigned int            level;
     213             : 
     214     2321834 :         if (!xfs_verify_magic(bp, block->bb_magic))
     215           0 :                 return __this_address;
     216             : 
     217     2321648 :         if (!xfs_has_reflink(mp))
     218           0 :                 return __this_address;
     219     2321648 :         fa = xfs_btree_sblock_v5hdr_verify(bp);
     220     2321723 :         if (fa)
     221             :                 return fa;
     222             : 
     223     2321704 :         level = be16_to_cpu(block->bb_level);
     224     4615921 :         if (pag && xfs_perag_initialised_agf(pag)) {
     225     1696620 :                 unsigned int    maxlevel = pag->pagf_refcount_level;
     226             : 
     227             : #ifdef CONFIG_XFS_ONLINE_REPAIR
     228             :                 /*
     229             :                  * Online repair could be rewriting the refcount btree, so
     230             :                  * we'll validate against the larger of either tree while this
     231             :                  * is going on.
     232             :                  */
     233     1696620 :                 maxlevel = max_t(unsigned int, maxlevel,
     234             :                                 pag->pagf_alt_refcount_level);
     235             : #endif
     236     1696620 :                 if (level >= maxlevel)
     237           0 :                         return __this_address;
     238      625084 :         } else if (level >= mp->m_refc_maxlevels)
     239           0 :                 return __this_address;
     240             : 
     241     2321704 :         return xfs_btree_sblock_verify(bp, mp->m_refc_mxr[level != 0]);
     242             : }
     243             : 
     244             : STATIC void
     245      290611 : xfs_refcountbt_read_verify(
     246             :         struct xfs_buf  *bp)
     247             : {
     248      290611 :         xfs_failaddr_t  fa;
     249             : 
     250      290611 :         if (!xfs_btree_sblock_verify_crc(bp))
     251          20 :                 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
     252             :         else {
     253      290591 :                 fa = xfs_refcountbt_verify(bp);
     254      290591 :                 if (fa)
     255           0 :                         xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     256             :         }
     257             : 
     258      290611 :         if (bp->b_error)
     259          20 :                 trace_xfs_btree_corrupt(bp, _RET_IP_);
     260      290611 : }
     261             : 
     262             : STATIC void
     263     1056520 : xfs_refcountbt_write_verify(
     264             :         struct xfs_buf  *bp)
     265             : {
     266     1056520 :         xfs_failaddr_t  fa;
     267             : 
     268     1056520 :         fa = xfs_refcountbt_verify(bp);
     269     1056558 :         if (fa) {
     270           0 :                 trace_xfs_btree_corrupt(bp, _RET_IP_);
     271           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     272           0 :                 return;
     273             :         }
     274     1056558 :         xfs_btree_sblock_calc_crc(bp);
     275             : 
     276             : }
     277             : 
     278             : const struct xfs_buf_ops xfs_refcountbt_buf_ops = {
     279             :         .name                   = "xfs_refcountbt",
     280             :         .magic                  = { 0, cpu_to_be32(XFS_REFC_CRC_MAGIC) },
     281             :         .verify_read            = xfs_refcountbt_read_verify,
     282             :         .verify_write           = xfs_refcountbt_write_verify,
     283             :         .verify_struct          = xfs_refcountbt_verify,
     284             : };
     285             : 
     286             : STATIC int
     287      300716 : xfs_refcountbt_keys_inorder(
     288             :         struct xfs_btree_cur            *cur,
     289             :         const union xfs_btree_key       *k1,
     290             :         const union xfs_btree_key       *k2)
     291             : {
     292      300716 :         return be32_to_cpu(k1->refc.rc_startblock) <
     293      300716 :                be32_to_cpu(k2->refc.rc_startblock);
     294             : }
     295             : 
     296             : STATIC int
     297   208279529 : xfs_refcountbt_recs_inorder(
     298             :         struct xfs_btree_cur            *cur,
     299             :         const union xfs_btree_rec       *r1,
     300             :         const union xfs_btree_rec       *r2)
     301             : {
     302   208279529 :         return  be32_to_cpu(r1->refc.rc_startblock) +
     303   208279529 :                 be32_to_cpu(r1->refc.rc_blockcount) <=
     304   208279529 :                 be32_to_cpu(r2->refc.rc_startblock);
     305             : }
     306             : 
     307             : STATIC enum xbtree_key_contig
     308           0 : xfs_refcountbt_keys_contiguous(
     309             :         struct xfs_btree_cur            *cur,
     310             :         const union xfs_btree_key       *key1,
     311             :         const union xfs_btree_key       *key2,
     312             :         const union xfs_btree_key       *mask)
     313             : {
     314           0 :         ASSERT(!mask || mask->refc.rc_startblock);
     315             : 
     316           0 :         return xbtree_key_contig(be32_to_cpu(key1->refc.rc_startblock),
     317           0 :                                  be32_to_cpu(key2->refc.rc_startblock));
     318             : }
     319             : 
     320             : const struct xfs_btree_ops xfs_refcountbt_ops = {
     321             :         .rec_len                = sizeof(struct xfs_refcount_rec),
     322             :         .key_len                = sizeof(struct xfs_refcount_key),
     323             :         .lru_refs               = XFS_REFC_BTREE_REF,
     324             : 
     325             :         .dup_cursor             = xfs_refcountbt_dup_cursor,
     326             :         .set_root               = xfs_refcountbt_set_root,
     327             :         .alloc_block            = xfs_refcountbt_alloc_block,
     328             :         .free_block             = xfs_refcountbt_free_block,
     329             :         .get_minrecs            = xfs_refcountbt_get_minrecs,
     330             :         .get_maxrecs            = xfs_refcountbt_get_maxrecs,
     331             :         .init_key_from_rec      = xfs_refcountbt_init_key_from_rec,
     332             :         .init_high_key_from_rec = xfs_refcountbt_init_high_key_from_rec,
     333             :         .init_rec_from_cur      = xfs_refcountbt_init_rec_from_cur,
     334             :         .init_ptr_from_cur      = xfs_refcountbt_init_ptr_from_cur,
     335             :         .key_diff               = xfs_refcountbt_key_diff,
     336             :         .buf_ops                = &xfs_refcountbt_buf_ops,
     337             :         .diff_two_keys          = xfs_refcountbt_diff_two_keys,
     338             :         .keys_inorder           = xfs_refcountbt_keys_inorder,
     339             :         .recs_inorder           = xfs_refcountbt_recs_inorder,
     340             :         .keys_contiguous        = xfs_refcountbt_keys_contiguous,
     341             : };
     342             : 
     343             : /*
     344             :  * Initialize a new refcount btree cursor.
     345             :  */
     346             : static struct xfs_btree_cur *
     347  1885641692 : xfs_refcountbt_init_common(
     348             :         struct xfs_mount        *mp,
     349             :         struct xfs_trans        *tp,
     350             :         struct xfs_perag        *pag)
     351             : {
     352  1885641692 :         struct xfs_btree_cur    *cur;
     353             : 
     354  1885641692 :         ASSERT(pag->pag_agno < mp->m_sb.sb_agcount);
     355             : 
     356  1885641692 :         cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_REFC,
     357  1885641692 :                         &xfs_refcountbt_ops, mp->m_refc_maxlevels,
     358             :                         xfs_refcountbt_cur_cache);
     359  1887155218 :         cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
     360             : 
     361  1887155218 :         cur->bc_ag.pag = xfs_perag_hold(pag);
     362  1890043546 :         cur->bc_ag.refc.nr_ops = 0;
     363  1890043546 :         cur->bc_ag.refc.shape_changes = 0;
     364  1890043546 :         return cur;
     365             : }
     366             : 
     367             : /* Create a btree cursor. */
     368             : struct xfs_btree_cur *
     369  1888141190 : xfs_refcountbt_init_cursor(
     370             :         struct xfs_mount        *mp,
     371             :         struct xfs_trans        *tp,
     372             :         struct xfs_buf          *agbp,
     373             :         struct xfs_perag        *pag)
     374             : {
     375  1888141190 :         struct xfs_agf          *agf = agbp->b_addr;
     376  1888141190 :         struct xfs_btree_cur    *cur;
     377             : 
     378  1888141190 :         cur = xfs_refcountbt_init_common(mp, tp, pag);
     379  1890050788 :         cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level);
     380  1890050788 :         cur->bc_ag.agbp = agbp;
     381  1890050788 :         return cur;
     382             : }
     383             : 
     384             : /* Create a btree cursor with a fake root for staging. */
     385             : struct xfs_btree_cur *
     386       91902 : xfs_refcountbt_stage_cursor(
     387             :         struct xfs_mount        *mp,
     388             :         struct xbtree_afakeroot *afake,
     389             :         struct xfs_perag        *pag)
     390             : {
     391       91902 :         struct xfs_btree_cur    *cur;
     392             : 
     393       91902 :         cur = xfs_refcountbt_init_common(mp, NULL, pag);
     394       92016 :         xfs_btree_stage_afakeroot(cur, afake);
     395       91903 :         return cur;
     396             : }
     397             : 
     398             : /*
     399             :  * Swap in the new btree root.  Once we pass this point the newly rebuilt btree
     400             :  * is in place and we have to kill off all the old btree blocks.
     401             :  */
     402             : void
     403       92047 : xfs_refcountbt_commit_staged_btree(
     404             :         struct xfs_btree_cur    *cur,
     405             :         struct xfs_trans        *tp,
     406             :         struct xfs_buf          *agbp)
     407             : {
     408       92047 :         struct xfs_agf          *agf = agbp->b_addr;
     409       92047 :         struct xbtree_afakeroot *afake = cur->bc_ag.afake;
     410             : 
     411       92047 :         ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
     412             : 
     413       92047 :         agf->agf_refcount_root = cpu_to_be32(afake->af_root);
     414       92047 :         agf->agf_refcount_level = cpu_to_be32(afake->af_levels);
     415       92047 :         agf->agf_refcount_blocks = cpu_to_be32(afake->af_blocks);
     416       92047 :         xfs_alloc_log_agf(tp, agbp, XFS_AGF_REFCOUNT_BLOCKS |
     417             :                                     XFS_AGF_REFCOUNT_ROOT |
     418             :                                     XFS_AGF_REFCOUNT_LEVEL);
     419       92034 :         xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_refcountbt_ops);
     420       92028 : }
     421             : 
     422             : /* Calculate number of records in a refcount btree block. */
     423             : static inline unsigned int
     424             : xfs_refcountbt_block_maxrecs(
     425             :         unsigned int            blocklen,
     426             :         bool                    leaf)
     427             : {
     428      133964 :         if (leaf)
     429       66982 :                 return blocklen / sizeof(struct xfs_refcount_rec);
     430       66982 :         return blocklen / (sizeof(struct xfs_refcount_key) +
     431             :                            sizeof(xfs_refcount_ptr_t));
     432             : }
     433             : 
     434             : /*
     435             :  * Calculate the number of records in a refcount btree block.
     436             :  */
     437             : unsigned int
     438      133964 : xfs_refcountbt_maxrecs(
     439             :         struct xfs_mount        *mp,
     440             :         unsigned int            blocklen,
     441             :         bool                    leaf)
     442             : {
     443      133964 :         blocklen -= XFS_REFCOUNT_BLOCK_LEN;
     444      133964 :         return xfs_refcountbt_block_maxrecs(blocklen, leaf);
     445             : }
     446             : 
     447             : /* Compute the max possible height of the maximally sized refcount btree. */
     448             : unsigned int
     449       62366 : xfs_refcountbt_maxlevels_ondisk(void)
     450             : {
     451       62366 :         unsigned int            minrecs[2];
     452       62366 :         unsigned int            blocklen;
     453             : 
     454       62366 :         blocklen = XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_SBLOCK_CRC_LEN;
     455             : 
     456       62366 :         minrecs[0] = xfs_refcountbt_block_maxrecs(blocklen, true) / 2;
     457       62366 :         minrecs[1] = xfs_refcountbt_block_maxrecs(blocklen, false) / 2;
     458             : 
     459       62366 :         return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_CRC_AG_BLOCKS);
     460             : }
     461             : 
     462             : /* Compute the maximum height of a refcount btree. */
     463             : void
     464       66972 : xfs_refcountbt_compute_maxlevels(
     465             :         struct xfs_mount                *mp)
     466             : {
     467       66972 :         if (!xfs_has_reflink(mp)) {
     468        4665 :                 mp->m_refc_maxlevels = 0;
     469        4665 :                 return;
     470             :         }
     471             : 
     472      124614 :         mp->m_refc_maxlevels = xfs_btree_compute_maxlevels(
     473       62307 :                         mp->m_refc_mnr, mp->m_sb.sb_agblocks);
     474       62307 :         ASSERT(mp->m_refc_maxlevels <= xfs_refcountbt_maxlevels_ondisk());
     475             : }
     476             : 
     477             : /* Calculate the refcount btree size for some records. */
     478             : xfs_extlen_t
     479     2994531 : xfs_refcountbt_calc_size(
     480             :         struct xfs_mount        *mp,
     481             :         unsigned long long      len)
     482             : {
     483     4214735 :         return xfs_btree_calc_size(mp->m_refc_mnr, len);
     484             : }
     485             : 
     486             : /*
     487             :  * Calculate the maximum refcount btree size.
     488             :  */
     489             : xfs_extlen_t
     490           0 : xfs_refcountbt_max_size(
     491             :         struct xfs_mount        *mp,
     492             :         xfs_agblock_t           agblocks)
     493             : {
     494             :         /* Bail out if we're uninitialized, which can happen in mkfs. */
     495           0 :         if (mp->m_refc_mxr[0] == 0)
     496             :                 return 0;
     497             : 
     498     1220189 :         return xfs_refcountbt_calc_size(mp, agblocks);
     499             : }
     500             : 
     501             : /*
     502             :  * Figure out how many blocks to reserve and how many are used by this btree.
     503             :  */
     504             : int
     505     1277122 : xfs_refcountbt_calc_reserves(
     506             :         struct xfs_mount        *mp,
     507             :         struct xfs_trans        *tp,
     508             :         struct xfs_perag        *pag,
     509             :         xfs_extlen_t            *ask,
     510             :         xfs_extlen_t            *used)
     511             : {
     512     1277122 :         struct xfs_buf          *agbp;
     513     1277122 :         struct xfs_agf          *agf;
     514     1277122 :         xfs_agblock_t           agblocks;
     515     1277122 :         xfs_extlen_t            tree_len;
     516     1277122 :         int                     error;
     517             : 
     518     1277122 :         if (!xfs_has_reflink(mp))
     519             :                 return 0;
     520             : 
     521     1220867 :         error = xfs_alloc_read_agf(pag, tp, 0, &agbp);
     522     1221349 :         if (error)
     523             :                 return error;
     524             : 
     525     1220921 :         agf = agbp->b_addr;
     526     1220921 :         agblocks = be32_to_cpu(agf->agf_length);
     527     1220921 :         tree_len = be32_to_cpu(agf->agf_refcount_blocks);
     528     1220921 :         xfs_trans_brelse(tp, agbp);
     529             : 
     530             :         /*
     531             :          * The log is permanently allocated, so the space it occupies will
     532             :          * never be available for the kinds of things that would require btree
     533             :          * expansion.  We therefore can pretend the space isn't there.
     534             :          */
     535     1220229 :         if (xfs_ag_contains_log(mp, pag->pag_agno))
     536      114867 :                 agblocks -= mp->m_sb.sb_logblocks;
     537             : 
     538     1219981 :         *ask += xfs_refcountbt_max_size(mp, agblocks);
     539     1219996 :         *used += tree_len;
     540             : 
     541     1219996 :         return error;
     542             : }
     543             : 
     544             : int __init
     545          59 : xfs_refcountbt_init_cur_cache(void)
     546             : {
     547          59 :         xfs_refcountbt_cur_cache = kmem_cache_create("xfs_refcbt_cur",
     548          59 :                         xfs_btree_cur_sizeof(xfs_refcountbt_maxlevels_ondisk()),
     549             :                         0, 0, NULL);
     550             : 
     551          59 :         if (!xfs_refcountbt_cur_cache)
     552           0 :                 return -ENOMEM;
     553             :         return 0;
     554             : }
     555             : 
     556             : void
     557          58 : xfs_refcountbt_destroy_cur_cache(void)
     558             : {
     559          58 :         kmem_cache_destroy(xfs_refcountbt_cur_cache);
     560          58 :         xfs_refcountbt_cur_cache = NULL;
     561          58 : }

Generated by: LCOV version 1.14