LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_alloc_btree.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 216 240 90.0 %
Date: 2023-07-31 20:08:34 Functions: 31 33 93.9 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2000-2001,2005 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_btree.h"
      14             : #include "xfs_btree_staging.h"
      15             : #include "xfs_alloc_btree.h"
      16             : #include "xfs_alloc.h"
      17             : #include "xfs_extent_busy.h"
      18             : #include "xfs_error.h"
      19             : #include "xfs_trace.h"
      20             : #include "xfs_trans.h"
      21             : #include "xfs_ag.h"
      22             : 
      23             : static struct kmem_cache        *xfs_allocbt_cur_cache;
      24             : 
      25             : STATIC struct xfs_btree_cur *
      26    10070064 : xfs_allocbt_dup_cursor(
      27             :         struct xfs_btree_cur    *cur)
      28             : {
      29    10070064 :         return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp,
      30             :                         cur->bc_ag.agbp, cur->bc_ag.pag, cur->bc_btnum);
      31             : }
      32             : 
      33             : STATIC void
      34       59734 : xfs_allocbt_set_root(
      35             :         struct xfs_btree_cur            *cur,
      36             :         const union xfs_btree_ptr       *ptr,
      37             :         int                             inc)
      38             : {
      39       59734 :         struct xfs_buf          *agbp = cur->bc_ag.agbp;
      40       59734 :         struct xfs_agf          *agf = agbp->b_addr;
      41       59734 :         int                     btnum = cur->bc_btnum;
      42             : 
      43       59734 :         ASSERT(ptr->s != 0);
      44             : 
      45       59734 :         agf->agf_roots[btnum] = ptr->s;
      46       59734 :         be32_add_cpu(&agf->agf_levels[btnum], inc);
      47       59734 :         cur->bc_ag.pag->pagf_levels[btnum] += inc;
      48             : 
      49       59734 :         xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
      50       59734 : }
      51             : 
      52             : STATIC int
      53      176405 : xfs_allocbt_alloc_block(
      54             :         struct xfs_btree_cur            *cur,
      55             :         const union xfs_btree_ptr       *start,
      56             :         union xfs_btree_ptr             *new,
      57             :         int                             *stat)
      58             : {
      59      176405 :         int                     error;
      60      176405 :         xfs_agblock_t           bno;
      61             : 
      62             :         /* Allocate the new block from the freelist. If we can't, give up.  */
      63      176405 :         error = xfs_alloc_get_freelist(cur->bc_ag.pag, cur->bc_tp,
      64             :                         cur->bc_ag.agbp, &bno, 1);
      65      176406 :         if (error)
      66             :                 return error;
      67             : 
      68      176406 :         if (bno == NULLAGBLOCK) {
      69           0 :                 *stat = 0;
      70           0 :                 return 0;
      71             :         }
      72             : 
      73      176406 :         atomic64_inc(&cur->bc_mp->m_allocbt_blks);
      74      176406 :         xfs_extent_busy_reuse(cur->bc_mp, cur->bc_ag.pag, bno, 1, false);
      75             : 
      76      176406 :         new->s = cpu_to_be32(bno);
      77             : 
      78      176406 :         *stat = 1;
      79      176406 :         return 0;
      80             : }
      81             : 
      82             : STATIC int
      83       78882 : xfs_allocbt_free_block(
      84             :         struct xfs_btree_cur    *cur,
      85             :         struct xfs_buf          *bp)
      86             : {
      87       78882 :         struct xfs_buf          *agbp = cur->bc_ag.agbp;
      88       78882 :         xfs_agblock_t           bno;
      89       78882 :         int                     error;
      90             : 
      91       78882 :         bno = xfs_daddr_to_agbno(cur->bc_mp, xfs_buf_daddr(bp));
      92       78882 :         error = xfs_alloc_put_freelist(cur->bc_ag.pag, cur->bc_tp, agbp, NULL,
      93             :                         bno, 1);
      94       78882 :         if (error)
      95             :                 return error;
      96             : 
      97       78882 :         atomic64_dec(&cur->bc_mp->m_allocbt_blks);
      98       78882 :         xfs_extent_busy_insert(cur->bc_tp, agbp->b_pag, bno, 1,
      99             :                               XFS_EXTENT_BUSY_SKIP_DISCARD);
     100       78882 :         return 0;
     101             : }
     102             : 
     103             : /*
     104             :  * Update the longest extent in the AGF
     105             :  */
     106             : STATIC void
     107   279853061 : xfs_allocbt_update_lastrec(
     108             :         struct xfs_btree_cur            *cur,
     109             :         const struct xfs_btree_block    *block,
     110             :         const union xfs_btree_rec       *rec,
     111             :         int                             ptr,
     112             :         int                             reason)
     113             : {
     114   279853061 :         struct xfs_agf          *agf = cur->bc_ag.agbp->b_addr;
     115   279853061 :         struct xfs_perag        *pag;
     116   279853061 :         __be32                  len;
     117   279853061 :         int                     numrecs;
     118             : 
     119   279853061 :         ASSERT(cur->bc_btnum == XFS_BTNUM_CNT);
     120             : 
     121   279853061 :         switch (reason) {
     122             :         case LASTREC_UPDATE:
     123             :                 /*
     124             :                  * If this is the last leaf block and it's the last record,
     125             :                  * then update the size of the longest extent in the AG.
     126             :                  */
     127           0 :                 if (ptr != xfs_btree_get_numrecs(block))
     128             :                         return;
     129           0 :                 len = rec->alloc.ar_blockcount;
     130           0 :                 break;
     131   148049926 :         case LASTREC_INSREC:
     132   148049926 :                 if (be32_to_cpu(rec->alloc.ar_blockcount) <=
     133   148049926 :                     be32_to_cpu(agf->agf_longest))
     134             :                         return;
     135             :                 len = rec->alloc.ar_blockcount;
     136             :                 break;
     137             :         case LASTREC_DELREC:
     138   131803135 :                 numrecs = xfs_btree_get_numrecs(block);
     139   131803135 :                 if (ptr <= numrecs)
     140             :                         return;
     141    25591876 :                 ASSERT(ptr == numrecs + 1);
     142             : 
     143    25591876 :                 if (numrecs) {
     144    16020907 :                         xfs_alloc_rec_t *rrp;
     145             : 
     146    16020907 :                         rrp = XFS_ALLOC_REC_ADDR(cur->bc_mp, block, numrecs);
     147    16020907 :                         len = rrp->ar_blockcount;
     148             :                 } else {
     149             :                         len = 0;
     150             :                 }
     151             : 
     152             :                 break;
     153           0 :         default:
     154           0 :                 ASSERT(0);
     155           0 :                 return;
     156             :         }
     157             : 
     158    51193588 :         agf->agf_longest = len;
     159    51193588 :         pag = cur->bc_ag.agbp->b_pag;
     160    51193588 :         pag->pagf_longest = be32_to_cpu(len);
     161    51193588 :         xfs_alloc_log_agf(cur->bc_tp, cur->bc_ag.agbp, XFS_AGF_LONGEST);
     162             : }
     163             : 
     164             : STATIC int
     165    81302904 : xfs_allocbt_get_minrecs(
     166             :         struct xfs_btree_cur    *cur,
     167             :         int                     level)
     168             : {
     169    81302904 :         return cur->bc_mp->m_alloc_mnr[level != 0];
     170             : }
     171             : 
     172             : STATIC int
     173 25793691667 : xfs_allocbt_get_maxrecs(
     174             :         struct xfs_btree_cur    *cur,
     175             :         int                     level)
     176             : {
     177 25793691667 :         return cur->bc_mp->m_alloc_mxr[level != 0];
     178             : }
     179             : 
     180             : STATIC void
     181 36606057241 : xfs_allocbt_init_key_from_rec(
     182             :         union xfs_btree_key             *key,
     183             :         const union xfs_btree_rec       *rec)
     184             : {
     185 36606057241 :         key->alloc.ar_startblock = rec->alloc.ar_startblock;
     186 36606057241 :         key->alloc.ar_blockcount = rec->alloc.ar_blockcount;
     187 36606057241 : }
     188             : 
     189             : STATIC void
     190  2179691728 : xfs_bnobt_init_high_key_from_rec(
     191             :         union xfs_btree_key             *key,
     192             :         const union xfs_btree_rec       *rec)
     193             : {
     194  2179691728 :         __u32                           x;
     195             : 
     196  2179691728 :         x = be32_to_cpu(rec->alloc.ar_startblock);
     197  2179691728 :         x += be32_to_cpu(rec->alloc.ar_blockcount) - 1;
     198  2179691728 :         key->alloc.ar_startblock = cpu_to_be32(x);
     199  2179691728 :         key->alloc.ar_blockcount = 0;
     200  2179691728 : }
     201             : 
     202             : STATIC void
     203           0 : xfs_cntbt_init_high_key_from_rec(
     204             :         union xfs_btree_key             *key,
     205             :         const union xfs_btree_rec       *rec)
     206             : {
     207           0 :         key->alloc.ar_blockcount = rec->alloc.ar_blockcount;
     208           0 :         key->alloc.ar_startblock = 0;
     209           0 : }
     210             : 
     211             : STATIC void
     212  9044388055 : xfs_allocbt_init_rec_from_cur(
     213             :         struct xfs_btree_cur    *cur,
     214             :         union xfs_btree_rec     *rec)
     215             : {
     216  9044388055 :         rec->alloc.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock);
     217  9044388055 :         rec->alloc.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount);
     218  9044388055 : }
     219             : 
     220             : STATIC void
     221  3573369706 : xfs_allocbt_init_ptr_from_cur(
     222             :         struct xfs_btree_cur    *cur,
     223             :         union xfs_btree_ptr     *ptr)
     224             : {
     225  3573369706 :         struct xfs_agf          *agf = cur->bc_ag.agbp->b_addr;
     226             : 
     227  3573369706 :         ASSERT(cur->bc_ag.pag->pag_agno == be32_to_cpu(agf->agf_seqno));
     228             : 
     229  3573369706 :         ptr->s = agf->agf_roots[cur->bc_btnum];
     230  3574640232 : }
     231             : 
     232             : STATIC int64_t
     233 23103399565 : xfs_bnobt_key_diff(
     234             :         struct xfs_btree_cur            *cur,
     235             :         const union xfs_btree_key       *key)
     236             : {
     237 23103399565 :         struct xfs_alloc_rec_incore     *rec = &cur->bc_rec.a;
     238 23103399565 :         const struct xfs_alloc_rec      *kp = &key->alloc;
     239             : 
     240 23103399565 :         return (int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock;
     241             : }
     242             : 
     243             : STATIC int64_t
     244  8071753535 : xfs_cntbt_key_diff(
     245             :         struct xfs_btree_cur            *cur,
     246             :         const union xfs_btree_key       *key)
     247             : {
     248  8071753535 :         struct xfs_alloc_rec_incore     *rec = &cur->bc_rec.a;
     249  8071753535 :         const struct xfs_alloc_rec      *kp = &key->alloc;
     250  8071753535 :         int64_t                         diff;
     251             : 
     252  8071753535 :         diff = (int64_t)be32_to_cpu(kp->ar_blockcount) - rec->ar_blockcount;
     253  8071753535 :         if (diff)
     254             :                 return diff;
     255             : 
     256  4474419623 :         return (int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock;
     257             : }
     258             : 
     259             : STATIC int64_t
     260  8863997473 : xfs_bnobt_diff_two_keys(
     261             :         struct xfs_btree_cur            *cur,
     262             :         const union xfs_btree_key       *k1,
     263             :         const union xfs_btree_key       *k2,
     264             :         const union xfs_btree_key       *mask)
     265             : {
     266  8863997473 :         ASSERT(!mask || mask->alloc.ar_startblock);
     267             : 
     268  8863997473 :         return (int64_t)be32_to_cpu(k1->alloc.ar_startblock) -
     269  8863997473 :                         be32_to_cpu(k2->alloc.ar_startblock);
     270             : }
     271             : 
     272             : STATIC int64_t
     273   189911406 : xfs_cntbt_diff_two_keys(
     274             :         struct xfs_btree_cur            *cur,
     275             :         const union xfs_btree_key       *k1,
     276             :         const union xfs_btree_key       *k2,
     277             :         const union xfs_btree_key       *mask)
     278             : {
     279   189911406 :         int64_t                         diff;
     280             : 
     281   189911406 :         ASSERT(!mask || (mask->alloc.ar_blockcount &&
     282             :                          mask->alloc.ar_startblock));
     283             : 
     284   189911406 :         diff =  be32_to_cpu(k1->alloc.ar_blockcount) -
     285   189911406 :                 be32_to_cpu(k2->alloc.ar_blockcount);
     286   189911406 :         if (diff)
     287             :                 return diff;
     288             : 
     289   128581128 :         return  be32_to_cpu(k1->alloc.ar_startblock) -
     290   128581128 :                 be32_to_cpu(k2->alloc.ar_startblock);
     291             : }
     292             : 
     293             : static xfs_failaddr_t
     294    11166457 : xfs_allocbt_verify(
     295             :         struct xfs_buf          *bp)
     296             : {
     297    11166457 :         struct xfs_mount        *mp = bp->b_mount;
     298    11166457 :         struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
     299    11166457 :         struct xfs_perag        *pag = bp->b_pag;
     300    11166457 :         xfs_failaddr_t          fa;
     301    11166457 :         unsigned int            level;
     302    11166457 :         xfs_btnum_t             btnum = XFS_BTNUM_BNOi;
     303             : 
     304    11166457 :         if (!xfs_verify_magic(bp, block->bb_magic))
     305           0 :                 return __this_address;
     306             : 
     307    11165878 :         if (xfs_has_crc(mp)) {
     308    11138201 :                 fa = xfs_btree_sblock_v5hdr_verify(bp);
     309    11138466 :                 if (fa)
     310             :                         return fa;
     311             :         }
     312             : 
     313             :         /*
     314             :          * The perag may not be attached during grow operations or fully
     315             :          * initialized from the AGF during log recovery. Therefore we can only
     316             :          * check against maximum tree depth from those contexts.
     317             :          *
     318             :          * Otherwise check against the per-tree limit. Peek at one of the
     319             :          * verifier magic values to determine the type of tree we're verifying
     320             :          * against.
     321             :          */
     322    11166253 :         level = be16_to_cpu(block->bb_level);
     323    11166253 :         if (bp->b_ops->magic[0] == cpu_to_be32(XFS_ABTC_MAGIC))
     324     5637638 :                 btnum = XFS_BTNUM_CNTi;
     325    22250264 :         if (pag && xfs_perag_initialised_agf(pag)) {
     326     7672536 :                 unsigned int    maxlevel = pag->pagf_levels[btnum];
     327             : 
     328             : #ifdef CONFIG_XFS_ONLINE_REPAIR
     329             :                 /*
     330             :                  * Online repair could be rewriting the free space btrees, so
     331             :                  * we'll validate against the larger of either tree while this
     332             :                  * is going on.
     333             :                  */
     334     7672587 :                 maxlevel = max_t(unsigned int, maxlevel,
     335             :                                  pag->pagf_alt_levels[btnum]);
     336             : #endif
     337     7672607 :                 if (level >= maxlevel)
     338           0 :                         return __this_address;
     339     3493718 :         } else if (level >= mp->m_alloc_maxlevels)
     340           0 :                 return __this_address;
     341             : 
     342    11166324 :         return xfs_btree_sblock_verify(bp, mp->m_alloc_mxr[level != 0]);
     343             : }
     344             : 
     345             : static void
     346      692779 : xfs_allocbt_read_verify(
     347             :         struct xfs_buf  *bp)
     348             : {
     349      692779 :         xfs_failaddr_t  fa;
     350             : 
     351      692779 :         if (!xfs_btree_sblock_verify_crc(bp))
     352        1280 :                 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
     353             :         else {
     354      691499 :                 fa = xfs_allocbt_verify(bp);
     355      691499 :                 if (fa)
     356           0 :                         xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     357             :         }
     358             : 
     359      692779 :         if (bp->b_error)
     360        1280 :                 trace_xfs_btree_corrupt(bp, _RET_IP_);
     361      692779 : }
     362             : 
     363             : static void
     364     6460446 : xfs_allocbt_write_verify(
     365             :         struct xfs_buf  *bp)
     366             : {
     367     6460446 :         xfs_failaddr_t  fa;
     368             : 
     369     6460446 :         fa = xfs_allocbt_verify(bp);
     370     6460234 :         if (fa) {
     371           0 :                 trace_xfs_btree_corrupt(bp, _RET_IP_);
     372           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     373           0 :                 return;
     374             :         }
     375     6460234 :         xfs_btree_sblock_calc_crc(bp);
     376             : 
     377             : }
     378             : 
     379             : const struct xfs_buf_ops xfs_bnobt_buf_ops = {
     380             :         .name = "xfs_bnobt",
     381             :         .magic = { cpu_to_be32(XFS_ABTB_MAGIC),
     382             :                    cpu_to_be32(XFS_ABTB_CRC_MAGIC) },
     383             :         .verify_read = xfs_allocbt_read_verify,
     384             :         .verify_write = xfs_allocbt_write_verify,
     385             :         .verify_struct = xfs_allocbt_verify,
     386             : };
     387             : 
     388             : const struct xfs_buf_ops xfs_cntbt_buf_ops = {
     389             :         .name = "xfs_cntbt",
     390             :         .magic = { cpu_to_be32(XFS_ABTC_MAGIC),
     391             :                    cpu_to_be32(XFS_ABTC_CRC_MAGIC) },
     392             :         .verify_read = xfs_allocbt_read_verify,
     393             :         .verify_write = xfs_allocbt_write_verify,
     394             :         .verify_struct = xfs_allocbt_verify,
     395             : };
     396             : 
     397             : STATIC int
     398      561789 : xfs_bnobt_keys_inorder(
     399             :         struct xfs_btree_cur            *cur,
     400             :         const union xfs_btree_key       *k1,
     401             :         const union xfs_btree_key       *k2)
     402             : {
     403      561789 :         return be32_to_cpu(k1->alloc.ar_startblock) <
     404      561789 :                be32_to_cpu(k2->alloc.ar_startblock);
     405             : }
     406             : 
     407             : STATIC int
     408   376349805 : xfs_bnobt_recs_inorder(
     409             :         struct xfs_btree_cur            *cur,
     410             :         const union xfs_btree_rec       *r1,
     411             :         const union xfs_btree_rec       *r2)
     412             : {
     413   376349805 :         return be32_to_cpu(r1->alloc.ar_startblock) +
     414   376349805 :                 be32_to_cpu(r1->alloc.ar_blockcount) <=
     415   376349805 :                 be32_to_cpu(r2->alloc.ar_startblock);
     416             : }
     417             : 
     418             : STATIC int
     419      483497 : xfs_cntbt_keys_inorder(
     420             :         struct xfs_btree_cur            *cur,
     421             :         const union xfs_btree_key       *k1,
     422             :         const union xfs_btree_key       *k2)
     423             : {
     424      483497 :         return be32_to_cpu(k1->alloc.ar_blockcount) <
     425      483497 :                 be32_to_cpu(k2->alloc.ar_blockcount) ||
     426      250054 :                 (k1->alloc.ar_blockcount == k2->alloc.ar_blockcount &&
     427      250054 :                  be32_to_cpu(k1->alloc.ar_startblock) <
     428      250054 :                  be32_to_cpu(k2->alloc.ar_startblock));
     429             : }
     430             : 
     431             : STATIC int
     432   508218060 : xfs_cntbt_recs_inorder(
     433             :         struct xfs_btree_cur            *cur,
     434             :         const union xfs_btree_rec       *r1,
     435             :         const union xfs_btree_rec       *r2)
     436             : {
     437   508218060 :         return be32_to_cpu(r1->alloc.ar_blockcount) <
     438   508218060 :                 be32_to_cpu(r2->alloc.ar_blockcount) ||
     439   382337051 :                 (r1->alloc.ar_blockcount == r2->alloc.ar_blockcount &&
     440   382337051 :                  be32_to_cpu(r1->alloc.ar_startblock) <
     441   382337051 :                  be32_to_cpu(r2->alloc.ar_startblock));
     442             : }
     443             : 
     444             : STATIC enum xbtree_key_contig
     445           0 : xfs_allocbt_keys_contiguous(
     446             :         struct xfs_btree_cur            *cur,
     447             :         const union xfs_btree_key       *key1,
     448             :         const union xfs_btree_key       *key2,
     449             :         const union xfs_btree_key       *mask)
     450             : {
     451           0 :         ASSERT(!mask || mask->alloc.ar_startblock);
     452             : 
     453           0 :         return xbtree_key_contig(be32_to_cpu(key1->alloc.ar_startblock),
     454           0 :                                  be32_to_cpu(key2->alloc.ar_startblock));
     455             : }
     456             : 
     457             : const struct xfs_btree_ops xfs_bnobt_ops = {
     458             :         .rec_len                = sizeof(xfs_alloc_rec_t),
     459             :         .key_len                = sizeof(xfs_alloc_key_t),
     460             :         .lru_refs               = XFS_ALLOC_BTREE_REF,
     461             : 
     462             :         .dup_cursor             = xfs_allocbt_dup_cursor,
     463             :         .set_root               = xfs_allocbt_set_root,
     464             :         .alloc_block            = xfs_allocbt_alloc_block,
     465             :         .free_block             = xfs_allocbt_free_block,
     466             :         .update_lastrec         = xfs_allocbt_update_lastrec,
     467             :         .get_minrecs            = xfs_allocbt_get_minrecs,
     468             :         .get_maxrecs            = xfs_allocbt_get_maxrecs,
     469             :         .init_key_from_rec      = xfs_allocbt_init_key_from_rec,
     470             :         .init_high_key_from_rec = xfs_bnobt_init_high_key_from_rec,
     471             :         .init_rec_from_cur      = xfs_allocbt_init_rec_from_cur,
     472             :         .init_ptr_from_cur      = xfs_allocbt_init_ptr_from_cur,
     473             :         .key_diff               = xfs_bnobt_key_diff,
     474             :         .buf_ops                = &xfs_bnobt_buf_ops,
     475             :         .diff_two_keys          = xfs_bnobt_diff_two_keys,
     476             :         .keys_inorder           = xfs_bnobt_keys_inorder,
     477             :         .recs_inorder           = xfs_bnobt_recs_inorder,
     478             :         .keys_contiguous        = xfs_allocbt_keys_contiguous,
     479             : };
     480             : 
     481             : const struct xfs_btree_ops xfs_cntbt_ops = {
     482             :         .rec_len                = sizeof(xfs_alloc_rec_t),
     483             :         .key_len                = sizeof(xfs_alloc_key_t),
     484             :         .lru_refs               = XFS_ALLOC_BTREE_REF,
     485             :         .geom_flags             = XFS_BTREE_LASTREC_UPDATE,
     486             : 
     487             :         .dup_cursor             = xfs_allocbt_dup_cursor,
     488             :         .set_root               = xfs_allocbt_set_root,
     489             :         .alloc_block            = xfs_allocbt_alloc_block,
     490             :         .free_block             = xfs_allocbt_free_block,
     491             :         .update_lastrec         = xfs_allocbt_update_lastrec,
     492             :         .get_minrecs            = xfs_allocbt_get_minrecs,
     493             :         .get_maxrecs            = xfs_allocbt_get_maxrecs,
     494             :         .init_key_from_rec      = xfs_allocbt_init_key_from_rec,
     495             :         .init_high_key_from_rec = xfs_cntbt_init_high_key_from_rec,
     496             :         .init_rec_from_cur      = xfs_allocbt_init_rec_from_cur,
     497             :         .init_ptr_from_cur      = xfs_allocbt_init_ptr_from_cur,
     498             :         .key_diff               = xfs_cntbt_key_diff,
     499             :         .buf_ops                = &xfs_cntbt_buf_ops,
     500             :         .diff_two_keys          = xfs_cntbt_diff_two_keys,
     501             :         .keys_inorder           = xfs_cntbt_keys_inorder,
     502             :         .recs_inorder           = xfs_cntbt_recs_inorder,
     503             :         .keys_contiguous        = NULL, /* not needed right now */
     504             : };
     505             : 
     506             : /* Allocate most of a new allocation btree cursor. */
     507             : STATIC struct xfs_btree_cur *
     508  2017967349 : xfs_allocbt_init_common(
     509             :         struct xfs_mount        *mp,
     510             :         struct xfs_trans        *tp,
     511             :         struct xfs_perag        *pag,
     512             :         xfs_btnum_t             btnum)
     513             : {
     514  2017967349 :         struct xfs_btree_cur    *cur;
     515             : 
     516  2017967349 :         ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT);
     517             : 
     518  2017967349 :         if (btnum == XFS_BTNUM_CNT) {
     519   965444503 :                 cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_cntbt_ops,
     520   965444503 :                                 mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
     521   965407298 :                 cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtc_2);
     522             :         } else {
     523  1052522846 :                 cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_bnobt_ops,
     524  1052522846 :                                 mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
     525  1052443724 :                 cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtb_2);
     526             :         }
     527             : 
     528  2017851022 :         cur->bc_ag.pag = xfs_perag_hold(pag);
     529  2018521028 :         cur->bc_ag.abt.active = false;
     530  2018521028 :         return cur;
     531             : }
     532             : 
     533             : /*
     534             :  * Allocate a new allocation btree cursor.
     535             :  */
     536             : struct xfs_btree_cur *                  /* new alloc btree cursor */
     537  2017861438 : xfs_allocbt_init_cursor(
     538             :         struct xfs_mount        *mp,            /* file system mount point */
     539             :         struct xfs_trans        *tp,            /* transaction pointer */
     540             :         struct xfs_buf          *agbp,          /* buffer for agf structure */
     541             :         struct xfs_perag        *pag,
     542             :         xfs_btnum_t             btnum)          /* btree identifier */
     543             : {
     544  2017861438 :         struct xfs_agf          *agf = agbp->b_addr;
     545  2017861438 :         struct xfs_btree_cur    *cur;
     546             : 
     547  2017861438 :         cur = xfs_allocbt_init_common(mp, tp, pag, btnum);
     548  2018370293 :         if (btnum == XFS_BTNUM_CNT)
     549   965433794 :                 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
     550             :         else
     551  1052936499 :                 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]);
     552             : 
     553  2018370293 :         cur->bc_ag.agbp = agbp;
     554             : 
     555  2018370293 :         return cur;
     556             : }
     557             : 
     558             : /* Create a free space btree cursor with a fake root for staging. */
     559             : struct xfs_btree_cur *
     560      283758 : xfs_allocbt_stage_cursor(
     561             :         struct xfs_mount        *mp,
     562             :         struct xbtree_afakeroot *afake,
     563             :         struct xfs_perag        *pag,
     564             :         xfs_btnum_t             btnum)
     565             : {
     566      283758 :         struct xfs_btree_cur    *cur;
     567             : 
     568      283758 :         cur = xfs_allocbt_init_common(mp, NULL, pag, btnum);
     569      284392 :         xfs_btree_stage_afakeroot(cur, afake);
     570      284368 :         return cur;
     571             : }
     572             : 
     573             : /*
     574             :  * Install a new free space btree root.  Caller is responsible for invalidating
     575             :  * and freeing the old btree blocks.
     576             :  */
     577             : void
     578      284595 : xfs_allocbt_commit_staged_btree(
     579             :         struct xfs_btree_cur    *cur,
     580             :         struct xfs_trans        *tp,
     581             :         struct xfs_buf          *agbp)
     582             : {
     583      284595 :         struct xfs_agf          *agf = agbp->b_addr;
     584      284595 :         struct xbtree_afakeroot *afake = cur->bc_ag.afake;
     585             : 
     586      284595 :         ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
     587             : 
     588      284595 :         agf->agf_roots[cur->bc_btnum] = cpu_to_be32(afake->af_root);
     589      284637 :         agf->agf_levels[cur->bc_btnum] = cpu_to_be32(afake->af_levels);
     590      284563 :         xfs_alloc_log_agf(tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
     591             : 
     592      284610 :         if (cur->bc_btnum == XFS_BTNUM_BNO) {
     593      142281 :                 xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_bnobt_ops);
     594             :         } else {
     595      142329 :                 cur->bc_flags |= XFS_BTREE_LASTREC_UPDATE;
     596      142329 :                 xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_cntbt_ops);
     597             :         }
     598      284568 : }
     599             : 
     600             : /* Calculate number of records in an alloc btree block. */
     601             : static inline unsigned int
     602             : xfs_allocbt_block_maxrecs(
     603             :         unsigned int            blocklen,
     604             :         bool                    leaf)
     605             : {
     606      133964 :         if (leaf)
     607       66982 :                 return blocklen / sizeof(xfs_alloc_rec_t);
     608       66982 :         return blocklen / (sizeof(xfs_alloc_key_t) + sizeof(xfs_alloc_ptr_t));
     609             : }
     610             : 
     611             : /*
     612             :  * Calculate number of records in an alloc btree block.
     613             :  */
     614             : unsigned int
     615      133964 : xfs_allocbt_maxrecs(
     616             :         struct xfs_mount        *mp,
     617             :         unsigned int            blocklen,
     618             :         bool                    leaf)
     619             : {
     620      133964 :         blocklen -= XFS_ALLOC_BLOCK_LEN(mp);
     621      133964 :         return xfs_allocbt_block_maxrecs(blocklen, leaf);
     622             : }
     623             : 
     624             : /* Free space btrees are at their largest when every other block is free. */
     625             : #define XFS_MAX_FREESP_RECORDS  ((XFS_MAX_AG_BLOCKS + 1) / 2)
     626             : 
     627             : /* Compute the max possible height for free space btrees. */
     628             : unsigned int
     629       67031 : xfs_allocbt_maxlevels_ondisk(void)
     630             : {
     631       67031 :         unsigned int            minrecs[2];
     632       67031 :         unsigned int            blocklen;
     633             : 
     634       67031 :         blocklen = min(XFS_MIN_BLOCKSIZE - XFS_BTREE_SBLOCK_LEN,
     635             :                        XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_SBLOCK_CRC_LEN);
     636             : 
     637       67031 :         minrecs[0] = xfs_allocbt_block_maxrecs(blocklen, true) / 2;
     638       67031 :         minrecs[1] = xfs_allocbt_block_maxrecs(blocklen, false) / 2;
     639             : 
     640       67031 :         return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_FREESP_RECORDS);
     641             : }
     642             : 
     643             : /* Calculate the freespace btree size for some records. */
     644             : xfs_extlen_t
     645     3012759 : xfs_allocbt_calc_size(
     646             :         struct xfs_mount        *mp,
     647             :         unsigned long long      len)
     648             : {
     649     3012759 :         return xfs_btree_calc_size(mp->m_alloc_mnr, len);
     650             : }
     651             : 
     652             : int __init
     653          59 : xfs_allocbt_init_cur_cache(void)
     654             : {
     655          59 :         xfs_allocbt_cur_cache = kmem_cache_create("xfs_bnobt_cur",
     656          59 :                         xfs_btree_cur_sizeof(xfs_allocbt_maxlevels_ondisk()),
     657             :                         0, 0, NULL);
     658             : 
     659          59 :         if (!xfs_allocbt_cur_cache)
     660           0 :                 return -ENOMEM;
     661             :         return 0;
     662             : }
     663             : 
     664             : void
     665          58 : xfs_allocbt_destroy_cur_cache(void)
     666             : {
     667          58 :         kmem_cache_destroy(xfs_allocbt_cur_cache);
     668          58 :         xfs_allocbt_cur_cache = NULL;
     669          58 : }

Generated by: LCOV version 1.14