LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_btree.h (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 36 37 97.3 %
Date: 2023-07-31 20:08:34 Functions: 2 2 100.0 %

          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             : #ifndef __XFS_BTREE_H__
       7             : #define __XFS_BTREE_H__
       8             : 
       9             : struct xfs_buf;
      10             : struct xfs_inode;
      11             : struct xfs_mount;
      12             : struct xfs_trans;
      13             : struct xfs_ifork;
      14             : struct xfs_perag;
      15             : struct xfs_rtgroup;
      16             : 
      17             : /*
      18             :  * Generic key, ptr and record wrapper structures.
      19             :  *
      20             :  * These are disk format structures, and are converted where necessary
      21             :  * by the btree specific code that needs to interpret them.
      22             :  */
      23             : union xfs_btree_ptr {
      24             :         __be32                  s;      /* short form ptr */
      25             :         __be64                  l;      /* long form ptr */
      26             : };
      27             : 
      28             : /*
      29             :  * The in-core btree key.  Overlapping btrees actually store two keys
      30             :  * per pointer, so we reserve enough memory to hold both.  The __*bigkey
      31             :  * items should never be accessed directly.
      32             :  */
      33             : union xfs_btree_key {
      34             :         struct xfs_bmbt_key             bmbt;
      35             :         xfs_bmdr_key_t                  bmbr;   /* bmbt root block */
      36             :         xfs_alloc_key_t                 alloc;
      37             :         struct xfs_inobt_key            inobt;
      38             :         struct xfs_rmap_key             rmap;
      39             :         struct xfs_rmap_key             __rmap_bigkey[2];
      40             :         struct xfs_refcount_key         refc;
      41             : };
      42             : 
      43             : union xfs_btree_rec {
      44             :         struct xfs_bmbt_rec             bmbt;
      45             :         xfs_bmdr_rec_t                  bmbr;   /* bmbt root block */
      46             :         struct xfs_alloc_rec            alloc;
      47             :         struct xfs_inobt_rec            inobt;
      48             :         struct xfs_rmap_rec             rmap;
      49             :         struct xfs_refcount_rec         refc;
      50             : };
      51             : 
      52             : /*
      53             :  * This nonsense is to make -wlint happy.
      54             :  */
      55             : #define XFS_LOOKUP_EQ   ((xfs_lookup_t)XFS_LOOKUP_EQi)
      56             : #define XFS_LOOKUP_LE   ((xfs_lookup_t)XFS_LOOKUP_LEi)
      57             : #define XFS_LOOKUP_GE   ((xfs_lookup_t)XFS_LOOKUP_GEi)
      58             : 
      59             : #define XFS_BTNUM_BNO   ((xfs_btnum_t)XFS_BTNUM_BNOi)
      60             : #define XFS_BTNUM_CNT   ((xfs_btnum_t)XFS_BTNUM_CNTi)
      61             : #define XFS_BTNUM_BMAP  ((xfs_btnum_t)XFS_BTNUM_BMAPi)
      62             : #define XFS_BTNUM_INO   ((xfs_btnum_t)XFS_BTNUM_INOi)
      63             : #define XFS_BTNUM_FINO  ((xfs_btnum_t)XFS_BTNUM_FINOi)
      64             : #define XFS_BTNUM_RMAP  ((xfs_btnum_t)XFS_BTNUM_RMAPi)
      65             : #define XFS_BTNUM_REFC  ((xfs_btnum_t)XFS_BTNUM_REFCi)
      66             : #define XFS_BTNUM_RCBAG ((xfs_btnum_t)XFS_BTNUM_RCBAGi)
      67             : #define XFS_BTNUM_RTRMAP ((xfs_btnum_t)XFS_BTNUM_RTRMAPi)
      68             : #define XFS_BTNUM_RTREFC ((xfs_btnum_t)XFS_BTNUM_RTREFCi)
      69             : 
      70             : struct xfs_btree_ops;
      71             : uint32_t xfs_btree_magic(struct xfs_mount *mp, const struct xfs_btree_ops *ops);
      72             : 
      73             : /*
      74             :  * For logging record fields.
      75             :  */
      76             : #define XFS_BB_MAGIC            (1u << 0)
      77             : #define XFS_BB_LEVEL            (1u << 1)
      78             : #define XFS_BB_NUMRECS          (1u << 2)
      79             : #define XFS_BB_LEFTSIB          (1u << 3)
      80             : #define XFS_BB_RIGHTSIB         (1u << 4)
      81             : #define XFS_BB_BLKNO            (1u << 5)
      82             : #define XFS_BB_LSN              (1u << 6)
      83             : #define XFS_BB_UUID             (1u << 7)
      84             : #define XFS_BB_OWNER            (1u << 8)
      85             : #define XFS_BB_NUM_BITS         5
      86             : #define XFS_BB_ALL_BITS         ((1u << XFS_BB_NUM_BITS) - 1)
      87             : #define XFS_BB_NUM_BITS_CRC     9
      88             : #define XFS_BB_ALL_BITS_CRC     ((1u << XFS_BB_NUM_BITS_CRC) - 1)
      89             : 
      90             : /*
      91             :  * Generic stats interface
      92             :  */
      93             : #define XFS_BTREE_STATS_INC(cur, stat)  \
      94             :         XFS_STATS_INC_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat)
      95             : #define XFS_BTREE_STATS_ADD(cur, stat, val)     \
      96             :         XFS_STATS_ADD_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat, val)
      97             : 
      98             : enum xbtree_key_contig {
      99             :         XBTREE_KEY_GAP = 0,
     100             :         XBTREE_KEY_CONTIGUOUS,
     101             :         XBTREE_KEY_OVERLAP,
     102             : };
     103             : 
     104             : /*
     105             :  * Decide if these two numeric btree key fields are contiguous, overlapping,
     106             :  * or if there's a gap between them.  @x should be the field from the high
     107             :  * key and @y should be the field from the low key.
     108             :  */
     109             : static inline enum xbtree_key_contig xbtree_key_contig(uint64_t x, uint64_t y)
     110             : {
     111  6817076879 :         x++;
     112  6817076879 :         if (x < y)
     113             :                 return XBTREE_KEY_GAP;
     114  6817076879 :         if (x == y)
     115  5773562545 :                 return XBTREE_KEY_CONTIGUOUS;
     116             :         return XBTREE_KEY_OVERLAP;
     117             : }
     118             : 
     119             : struct xfs_btree_ops {
     120             :         /* size of the key and record structures */
     121             :         size_t  key_len;
     122             :         size_t  rec_len;
     123             : 
     124             :         /* XFS_BTREE_* flags that determine the geometry of the btree */
     125             :         unsigned int    geom_flags;
     126             : 
     127             :         /* LRU refcount to set on each btree buffer created */
     128             :         int     lru_refs;
     129             : 
     130             :         /* cursor operations */
     131             :         struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *);
     132             :         void    (*update_cursor)(struct xfs_btree_cur *src,
     133             :                                  struct xfs_btree_cur *dst);
     134             : 
     135             :         /* update btree root pointer */
     136             :         void    (*set_root)(struct xfs_btree_cur *cur,
     137             :                             const union xfs_btree_ptr *nptr, int level_change);
     138             : 
     139             :         /* block allocation / freeing */
     140             :         int     (*alloc_block)(struct xfs_btree_cur *cur,
     141             :                                const union xfs_btree_ptr *start_bno,
     142             :                                union xfs_btree_ptr *new_bno,
     143             :                                int *stat);
     144             :         int     (*free_block)(struct xfs_btree_cur *cur, struct xfs_buf *bp);
     145             : 
     146             :         /* update last record information */
     147             :         void    (*update_lastrec)(struct xfs_btree_cur *cur,
     148             :                                   const struct xfs_btree_block *block,
     149             :                                   const union xfs_btree_rec *rec,
     150             :                                   int ptr, int reason);
     151             : 
     152             :         /* records in block/level */
     153             :         int     (*get_minrecs)(struct xfs_btree_cur *cur, int level);
     154             :         int     (*get_maxrecs)(struct xfs_btree_cur *cur, int level);
     155             : 
     156             :         /* records on disk.  Matter for the root in inode case. */
     157             :         int     (*get_dmaxrecs)(struct xfs_btree_cur *cur, int level);
     158             : 
     159             :         /* init values of btree structures */
     160             :         void    (*init_key_from_rec)(union xfs_btree_key *key,
     161             :                                      const union xfs_btree_rec *rec);
     162             :         void    (*init_rec_from_cur)(struct xfs_btree_cur *cur,
     163             :                                      union xfs_btree_rec *rec);
     164             :         void    (*init_ptr_from_cur)(struct xfs_btree_cur *cur,
     165             :                                      union xfs_btree_ptr *ptr);
     166             :         void    (*init_high_key_from_rec)(union xfs_btree_key *key,
     167             :                                           const union xfs_btree_rec *rec);
     168             : 
     169             :         /* difference between key value and cursor value */
     170             :         int64_t (*key_diff)(struct xfs_btree_cur *cur,
     171             :                             const union xfs_btree_key *key);
     172             : 
     173             :         /*
     174             :          * Difference between key2 and key1 -- positive if key1 > key2,
     175             :          * negative if key1 < key2, and zero if equal.  If the @mask parameter
     176             :          * is non NULL, each key field to be used in the comparison must
     177             :          * contain a nonzero value.
     178             :          */
     179             :         int64_t (*diff_two_keys)(struct xfs_btree_cur *cur,
     180             :                                  const union xfs_btree_key *key1,
     181             :                                  const union xfs_btree_key *key2,
     182             :                                  const union xfs_btree_key *mask);
     183             : 
     184             :         const struct xfs_buf_ops        *buf_ops;
     185             : 
     186             :         /* check that k1 is lower than k2 */
     187             :         int     (*keys_inorder)(struct xfs_btree_cur *cur,
     188             :                                 const union xfs_btree_key *k1,
     189             :                                 const union xfs_btree_key *k2);
     190             : 
     191             :         /* check that r1 is lower than r2 */
     192             :         int     (*recs_inorder)(struct xfs_btree_cur *cur,
     193             :                                 const union xfs_btree_rec *r1,
     194             :                                 const union xfs_btree_rec *r2);
     195             : 
     196             :         /*
     197             :          * Are these two btree keys immediately adjacent?
     198             :          *
     199             :          * Given two btree keys @key1 and @key2, decide if it is impossible for
     200             :          * there to be a third btree key K satisfying the relationship
     201             :          * @key1 < K < @key2.  To determine if two btree records are
     202             :          * immediately adjacent, @key1 should be the high key of the first
     203             :          * record and @key2 should be the low key of the second record.
     204             :          * If the @mask parameter is non NULL, each key field to be used in the
     205             :          * comparison must contain a nonzero value.
     206             :          */
     207             :         enum xbtree_key_contig (*keys_contiguous)(struct xfs_btree_cur *cur,
     208             :                                const union xfs_btree_key *key1,
     209             :                                const union xfs_btree_key *key2,
     210             :                                const union xfs_btree_key *mask);
     211             : 
     212             :         /* Functions for manipulating the btree root block. */
     213             :         const struct xfs_ifork_broot_ops *iroot_ops;
     214             : };
     215             : 
     216             : /*
     217             :  * Reasons for the update_lastrec method to be called.
     218             :  */
     219             : #define LASTREC_UPDATE  0
     220             : #define LASTREC_INSREC  1
     221             : #define LASTREC_DELREC  2
     222             : 
     223             : 
     224             : union xfs_btree_irec {
     225             :         struct xfs_alloc_rec_incore     a;
     226             :         struct xfs_bmbt_irec            b;
     227             :         struct xfs_inobt_rec_incore     i;
     228             :         struct xfs_rmap_irec            r;
     229             :         struct xfs_refcount_irec        rc;
     230             : };
     231             : 
     232             : struct xbtree_refc {
     233             :         unsigned int    nr_ops;         /* # record updates */
     234             :         unsigned int    shape_changes;  /* # of extent splits */
     235             : };
     236             : 
     237             : /* Per-AG btree information. */
     238             : struct xfs_btree_cur_ag {
     239             :         struct xfs_perag                *pag;
     240             :         union {
     241             :                 struct xfs_buf          *agbp;
     242             :                 struct xbtree_afakeroot *afake; /* for staging cursor */
     243             :         };
     244             :         union {
     245             :                 struct xbtree_refc      refc;
     246             :                 struct {
     247             :                         bool            active; /* allocation cursor state */
     248             :                 } abt;
     249             :         };
     250             : };
     251             : 
     252             : /* Btree-in-inode cursor information */
     253             : struct xfs_btree_cur_ino {
     254             :         struct xfs_inode                *ip;
     255             :         struct xfs_rtgroup              *rtg;   /* if realtime metadata */
     256             :         struct xbtree_ifakeroot         *ifake; /* for staging cursor */
     257             :         int                             allocated;
     258             :         short                           forksize;
     259             :         char                            whichfork;
     260             :         char                            flags;
     261             : /* We are converting a delalloc reservation */
     262             : #define XFS_BTCUR_BMBT_WASDEL           (1 << 0)
     263             : 
     264             : /* For extent swap, ignore owner check in verifier */
     265             : #define XFS_BTCUR_BMBT_INVALID_OWNER    (1 << 1)
     266             :         struct xbtree_refc              refc;
     267             : };
     268             : 
     269             : /* In-memory btree information */
     270             : struct xfbtree;
     271             : 
     272             : struct xfs_btree_cur_mem {
     273             :         struct xfbtree                  *xfbtree;
     274             :         struct xfs_buf                  *head_bp;
     275             :         struct xfs_perag                *pag;
     276             :         struct xfs_rtgroup              *rtg;
     277             : };
     278             : 
     279             : struct xfs_btree_level {
     280             :         /* buffer pointer */
     281             :         struct xfs_buf          *bp;
     282             : 
     283             :         /* key/record number */
     284             :         uint16_t                ptr;
     285             : 
     286             :         /* readahead info */
     287             : #define XFS_BTCUR_LEFTRA        (1 << 0) /* left sibling has been read-ahead */
     288             : #define XFS_BTCUR_RIGHTRA       (1 << 1) /* right sibling has been read-ahead */
     289             :         uint16_t                ra;
     290             : };
     291             : 
     292             : /*
     293             :  * Btree cursor structure.
     294             :  * This collects all information needed by the btree code in one place.
     295             :  */
     296             : struct xfs_btree_cur
     297             : {
     298             :         struct xfs_trans        *bc_tp; /* transaction we're in, if any */
     299             :         struct xfs_mount        *bc_mp; /* file system mount struct */
     300             :         const struct xfs_btree_ops *bc_ops;
     301             :         struct kmem_cache       *bc_cache; /* cursor cache */
     302             :         unsigned int            bc_flags; /* btree features - below */
     303             :         xfs_btnum_t             bc_btnum; /* identifies which btree type */
     304             :         union xfs_btree_irec    bc_rec; /* current insert/search record value */
     305             :         uint8_t                 bc_nlevels; /* number of levels in the tree */
     306             :         uint8_t                 bc_maxlevels; /* maximum levels for this btree type */
     307             :         int                     bc_statoff; /* offset of btree stats array */
     308             : 
     309             :         /*
     310             :          * Short btree pointers need an agno to be able to turn the pointers
     311             :          * into physical addresses for IO, so the btree cursor switches between
     312             :          * bc_ino and bc_ag based on whether XFS_BTREE_LONG_PTRS is set for the
     313             :          * cursor.
     314             :          */
     315             :         union {
     316             :                 struct xfs_btree_cur_ag bc_ag;
     317             :                 struct xfs_btree_cur_ino bc_ino;
     318             :                 struct xfs_btree_cur_mem bc_mem;
     319             :         };
     320             : 
     321             :         /* Must be at the end of the struct! */
     322             :         struct xfs_btree_level  bc_levels[];
     323             : };
     324             : 
     325             : /*
     326             :  * Compute the size of a btree cursor that can handle a btree of a given
     327             :  * height.  The bc_levels array handles node and leaf blocks, so its size
     328             :  * is exactly nlevels.
     329             :  */
     330             : static inline size_t
     331             : xfs_btree_cur_sizeof(unsigned int nlevels)
     332             : {
     333         472 :         return struct_size_t(struct xfs_btree_cur, bc_levels, nlevels);
     334             : }
     335             : 
     336             : /* cursor flags */
     337             : #define XFS_BTREE_LONG_PTRS             (1<<0)    /* pointers are 64bits long */
     338             : #define XFS_BTREE_ROOT_IN_INODE         (1<<1)    /* root may be variable size */
     339             : #define XFS_BTREE_LASTREC_UPDATE        (1<<2)    /* track last rec externally */
     340             : #define XFS_BTREE_CRC_BLOCKS            (1<<3)    /* uses extended btree blocks */
     341             : #define XFS_BTREE_OVERLAPPING           (1<<4)    /* overlapping intervals */
     342             : /*
     343             :  * The root of this btree is a fakeroot structure so that we can stage a btree
     344             :  * rebuild without leaving it accessible via primary metadata.  The ops struct
     345             :  * is dynamically allocated and must be freed when the cursor is deleted.
     346             :  */
     347             : #define XFS_BTREE_STAGING               (1<<5)
     348             : #define XFS_BTREE_IROOT_RECORDS         (1<<6)    /* iroot can store records */
     349             : 
     350             : /* btree stored in memory; not compatible with ROOT_IN_INODE */
     351             : #ifdef CONFIG_XFS_BTREE_IN_XFILE
     352             : # define XFS_BTREE_IN_XFILE             (1<<7)
     353             : #else
     354             : # define XFS_BTREE_IN_XFILE             (0)
     355             : #endif
     356             : 
     357             : #define XFS_BTREE_NOERROR       0
     358             : #define XFS_BTREE_ERROR         1
     359             : 
     360             : /*
     361             :  * Convert from buffer to btree block header.
     362             :  */
     363             : #define XFS_BUF_TO_BLOCK(bp)    ((struct xfs_btree_block *)((bp)->b_addr))
     364             : 
     365             : /*
     366             :  * Internal long and short btree block checks.  They return NULL if the
     367             :  * block is ok or the address of the failed check otherwise.
     368             :  */
     369             : xfs_failaddr_t __xfs_btree_check_lblock(struct xfs_btree_cur *cur,
     370             :                 struct xfs_btree_block *block, int level, struct xfs_buf *bp);
     371             : xfs_failaddr_t __xfs_btree_check_sblock(struct xfs_btree_cur *cur,
     372             :                 struct xfs_btree_block *block, int level, struct xfs_buf *bp);
     373             : 
     374             : /*
     375             :  * Check that block header is ok.
     376             :  */
     377             : int
     378             : xfs_btree_check_block(
     379             :         struct xfs_btree_cur    *cur,   /* btree cursor */
     380             :         struct xfs_btree_block  *block, /* generic btree block pointer */
     381             :         int                     level,  /* level of the btree block */
     382             :         struct xfs_buf          *bp);   /* buffer containing block, if any */
     383             : 
     384             : /*
     385             :  * Check that (long) pointer is ok.
     386             :  */
     387             : bool                                    /* error (0 or EFSCORRUPTED) */
     388             : xfs_btree_check_lptr(
     389             :         struct xfs_btree_cur    *cur,   /* btree cursor */
     390             :         xfs_fsblock_t           fsbno,  /* btree block disk address */
     391             :         int                     level); /* btree block level */
     392             : 
     393             : /*
     394             :  * Check that (short) pointer is ok.
     395             :  */
     396             : bool                                    /* error (0 or EFSCORRUPTED) */
     397             : xfs_btree_check_sptr(
     398             :         struct xfs_btree_cur    *cur,   /* btree cursor */
     399             :         xfs_agblock_t           agbno,  /* btree block disk address */
     400             :         int                     level); /* btree block level */
     401             : 
     402             : /*
     403             :  * Delete the btree cursor.
     404             :  */
     405             : void
     406             : xfs_btree_del_cursor(
     407             :         struct xfs_btree_cur    *cur,   /* btree cursor */
     408             :         int                     error); /* del because of error */
     409             : 
     410             : /*
     411             :  * Duplicate the btree cursor.
     412             :  * Allocate a new one, copy the record, re-get the buffers.
     413             :  */
     414             : int                                     /* error */
     415             : xfs_btree_dup_cursor(
     416             :         struct xfs_btree_cur            *cur,   /* input cursor */
     417             :         struct xfs_btree_cur            **ncur);/* output cursor */
     418             : 
     419             : /*
     420             :  * Compute first and last byte offsets for the fields given.
     421             :  * Interprets the offsets table, which contains struct field offsets.
     422             :  */
     423             : void
     424             : xfs_btree_offsets(
     425             :         uint32_t                fields, /* bitmask of fields */
     426             :         const short             *offsets,/* table of field offsets */
     427             :         int                     nbits,  /* number of bits to inspect */
     428             :         int                     *first, /* output: first byte offset */
     429             :         int                     *last); /* output: last byte offset */
     430             : 
     431             : /*
     432             :  * Get a buffer for the block, return it read in.
     433             :  * Long-form addressing.
     434             :  */
     435             : int                                     /* error */
     436             : xfs_btree_read_bufl(
     437             :         struct xfs_mount        *mp,    /* file system mount point */
     438             :         struct xfs_trans        *tp,    /* transaction pointer */
     439             :         xfs_fsblock_t           fsbno,  /* file system block number */
     440             :         struct xfs_buf          **bpp,  /* buffer for fsbno */
     441             :         int                     refval, /* ref count value for buffer */
     442             :         const struct xfs_buf_ops *ops);
     443             : 
     444             : /*
     445             :  * Read-ahead the block, don't wait for it, don't return a buffer.
     446             :  * Long-form addressing.
     447             :  */
     448             : void                                    /* error */
     449             : xfs_btree_reada_bufl(
     450             :         struct xfs_mount        *mp,    /* file system mount point */
     451             :         xfs_fsblock_t           fsbno,  /* file system block number */
     452             :         xfs_extlen_t            count,  /* count of filesystem blocks */
     453             :         const struct xfs_buf_ops *ops);
     454             : 
     455             : /*
     456             :  * Read-ahead the block, don't wait for it, don't return a buffer.
     457             :  * Short-form addressing.
     458             :  */
     459             : void                                    /* error */
     460             : xfs_btree_reada_bufs(
     461             :         struct xfs_mount        *mp,    /* file system mount point */
     462             :         xfs_agnumber_t          agno,   /* allocation group number */
     463             :         xfs_agblock_t           agbno,  /* allocation group block number */
     464             :         xfs_extlen_t            count,  /* count of filesystem blocks */
     465             :         const struct xfs_buf_ops *ops);
     466             : 
     467             : /*
     468             :  * Initialise a new btree block header
     469             :  */
     470             : void xfs_btree_init_buf(struct xfs_mount *mp, struct xfs_buf *bp,
     471             :                 const struct xfs_btree_ops *ops, __u16 level, __u16 numrecs,
     472             :                 __u64 owner);
     473             : void xfs_btree_init_block(struct xfs_mount *mp,
     474             :                 struct xfs_btree_block *buf, const struct xfs_btree_ops *ops,
     475             :                 __u16 level, __u16 numrecs, __u64 owner);
     476             : 
     477             : /*
     478             :  * Common btree core entry points.
     479             :  */
     480             : int xfs_btree_increment(struct xfs_btree_cur *, int, int *);
     481             : int xfs_btree_decrement(struct xfs_btree_cur *, int, int *);
     482             : int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *);
     483             : int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *);
     484             : int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *);
     485             : int xfs_btree_insert(struct xfs_btree_cur *, int *);
     486             : int xfs_btree_delete(struct xfs_btree_cur *, int *);
     487             : int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *);
     488             : int xfs_btree_change_owner(struct xfs_btree_cur *cur, uint64_t new_owner,
     489             :                            struct list_head *buffer_list);
     490             : 
     491             : /*
     492             :  * btree block CRC helpers
     493             :  */
     494             : void xfs_btree_lblock_calc_crc(struct xfs_buf *);
     495             : bool xfs_btree_lblock_verify_crc(struct xfs_buf *);
     496             : void xfs_btree_sblock_calc_crc(struct xfs_buf *);
     497             : bool xfs_btree_sblock_verify_crc(struct xfs_buf *);
     498             : 
     499             : /*
     500             :  * Internal btree helpers also used by xfs_bmap.c.
     501             :  */
     502             : void xfs_btree_log_block(struct xfs_btree_cur *, struct xfs_buf *, uint32_t);
     503             : void xfs_btree_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int, int);
     504             : 
     505             : /*
     506             :  * Helpers.
     507             :  */
     508             : static inline int xfs_btree_get_numrecs(const struct xfs_btree_block *block)
     509             : {
     510 >78507*10^7 :         return be16_to_cpu(block->bb_numrecs);
     511             : }
     512             : 
     513             : static inline void xfs_btree_set_numrecs(struct xfs_btree_block *block,
     514             :                 uint16_t numrecs)
     515             : {
     516  2792953035 :         block->bb_numrecs = cpu_to_be16(numrecs);
     517             : }
     518             : 
     519             : static inline int xfs_btree_get_level(const struct xfs_btree_block *block)
     520             : {
     521 88885393373 :         return be16_to_cpu(block->bb_level);
     522             : }
     523             : 
     524             : 
     525             : /*
     526             :  * Min and max functions for extlen, agblock, fileoff, and filblks types.
     527             :  */
     528             : #define XFS_EXTLEN_MIN(a,b)     min_t(xfs_extlen_t, (a), (b))
     529             : #define XFS_EXTLEN_MAX(a,b)     max_t(xfs_extlen_t, (a), (b))
     530             : #define XFS_AGBLOCK_MIN(a,b)    min_t(xfs_agblock_t, (a), (b))
     531             : #define XFS_AGBLOCK_MAX(a,b)    max_t(xfs_agblock_t, (a), (b))
     532             : #define XFS_FILEOFF_MIN(a,b)    min_t(xfs_fileoff_t, (a), (b))
     533             : #define XFS_FILEOFF_MAX(a,b)    max_t(xfs_fileoff_t, (a), (b))
     534             : #define XFS_FILBLKS_MIN(a,b)    min_t(xfs_filblks_t, (a), (b))
     535             : #define XFS_FILBLKS_MAX(a,b)    max_t(xfs_filblks_t, (a), (b))
     536             : 
     537             : xfs_failaddr_t xfs_btree_sblock_v5hdr_verify(struct xfs_buf *bp);
     538             : xfs_failaddr_t xfs_btree_sblock_verify(struct xfs_buf *bp,
     539             :                 unsigned int max_recs);
     540             : xfs_failaddr_t xfs_btree_lblock_v5hdr_verify(struct xfs_buf *bp,
     541             :                 uint64_t owner);
     542             : xfs_failaddr_t xfs_btree_lblock_verify(struct xfs_buf *bp,
     543             :                 unsigned int max_recs);
     544             : 
     545             : unsigned int xfs_btree_compute_maxlevels(const unsigned int *limits,
     546             :                 unsigned long long records);
     547             : unsigned long long xfs_btree_calc_size(const unsigned int *limits,
     548             :                 unsigned long long records);
     549             : unsigned int xfs_btree_space_to_height(const unsigned int *limits,
     550             :                 unsigned long long blocks);
     551             : 
     552             : /*
     553             :  * Return codes for the query range iterator function are 0 to continue
     554             :  * iterating, and non-zero to stop iterating.  Any non-zero value will be
     555             :  * passed up to the _query_range caller.  The special value -ECANCELED can be
     556             :  * used to stop iteration, because _query_range never generates that error
     557             :  * code on its own.
     558             :  */
     559             : typedef int (*xfs_btree_query_range_fn)(struct xfs_btree_cur *cur,
     560             :                 const union xfs_btree_rec *rec, void *priv);
     561             : 
     562             : int xfs_btree_query_range(struct xfs_btree_cur *cur,
     563             :                 const union xfs_btree_irec *low_rec,
     564             :                 const union xfs_btree_irec *high_rec,
     565             :                 xfs_btree_query_range_fn fn, void *priv);
     566             : int xfs_btree_query_all(struct xfs_btree_cur *cur, xfs_btree_query_range_fn fn,
     567             :                 void *priv);
     568             : 
     569             : typedef int (*xfs_btree_visit_blocks_fn)(struct xfs_btree_cur *cur, int level,
     570             :                 void *data);
     571             : /* Visit record blocks. */
     572             : #define XFS_BTREE_VISIT_RECORDS         (1 << 0)
     573             : /* Visit leaf blocks. */
     574             : #define XFS_BTREE_VISIT_LEAVES          (1 << 1)
     575             : /* Visit all blocks. */
     576             : #define XFS_BTREE_VISIT_ALL             (XFS_BTREE_VISIT_RECORDS | \
     577             :                                          XFS_BTREE_VISIT_LEAVES)
     578             : int xfs_btree_visit_blocks(struct xfs_btree_cur *cur,
     579             :                 xfs_btree_visit_blocks_fn fn, unsigned int flags, void *data);
     580             : 
     581             : int xfs_btree_count_blocks(struct xfs_btree_cur *cur, xfs_extlen_t *blocks);
     582             : 
     583             : union xfs_btree_rec *xfs_btree_rec_addr(struct xfs_btree_cur *cur, int n,
     584             :                 struct xfs_btree_block *block);
     585             : union xfs_btree_key *xfs_btree_key_addr(struct xfs_btree_cur *cur, int n,
     586             :                 struct xfs_btree_block *block);
     587             : union xfs_btree_key *xfs_btree_high_key_addr(struct xfs_btree_cur *cur, int n,
     588             :                 struct xfs_btree_block *block);
     589             : union xfs_btree_ptr *xfs_btree_ptr_addr(struct xfs_btree_cur *cur, int n,
     590             :                 struct xfs_btree_block *block);
     591             : int xfs_btree_lookup_get_block(struct xfs_btree_cur *cur, int level,
     592             :                 const union xfs_btree_ptr *pp, struct xfs_btree_block **blkp);
     593             : struct xfs_btree_block *xfs_btree_get_block(struct xfs_btree_cur *cur,
     594             :                 int level, struct xfs_buf **bpp);
     595             : bool xfs_btree_ptr_is_null(struct xfs_btree_cur *cur,
     596             :                 const union xfs_btree_ptr *ptr);
     597             : int64_t xfs_btree_diff_two_ptrs(struct xfs_btree_cur *cur,
     598             :                                 const union xfs_btree_ptr *a,
     599             :                                 const union xfs_btree_ptr *b);
     600             : void xfs_btree_get_sibling(struct xfs_btree_cur *cur,
     601             :                            struct xfs_btree_block *block,
     602             :                            union xfs_btree_ptr *ptr, int lr);
     603             : void xfs_btree_get_keys(struct xfs_btree_cur *cur,
     604             :                 struct xfs_btree_block *block, union xfs_btree_key *key);
     605             : union xfs_btree_key *xfs_btree_high_key_from_key(struct xfs_btree_cur *cur,
     606             :                 union xfs_btree_key *key);
     607             : typedef bool (*xfs_btree_key_gap_fn)(struct xfs_btree_cur *cur,
     608             :                 const union xfs_btree_key *key1,
     609             :                 const union xfs_btree_key *key2);
     610             : 
     611             : int xfs_btree_has_records(struct xfs_btree_cur *cur,
     612             :                 const union xfs_btree_irec *low,
     613             :                 const union xfs_btree_irec *high,
     614             :                 const union xfs_btree_key *mask,
     615             :                 enum xbtree_recpacking *outcome);
     616             : 
     617             : bool xfs_btree_has_more_records(struct xfs_btree_cur *cur);
     618             : struct xfs_ifork *xfs_btree_ifork_ptr(struct xfs_btree_cur *cur);
     619             : 
     620             : /* Key comparison helpers */
     621             : static inline bool
     622             : xfs_btree_keycmp_lt(
     623             :         struct xfs_btree_cur            *cur,
     624             :         const union xfs_btree_key       *key1,
     625             :         const union xfs_btree_key       *key2)
     626             : {
     627 >23773*10^7 :         return cur->bc_ops->diff_two_keys(cur, key1, key2, NULL) < 0;
     628             : }
     629             : 
     630             : static inline bool
     631             : xfs_btree_keycmp_gt(
     632             :         struct xfs_btree_cur            *cur,
     633             :         const union xfs_btree_key       *key1,
     634             :         const union xfs_btree_key       *key2)
     635             : {
     636 >41858*10^7 :         return cur->bc_ops->diff_two_keys(cur, key1, key2, NULL) > 0;
     637             : }
     638             : 
     639             : static inline bool
     640             : xfs_btree_keycmp_eq(
     641             :         struct xfs_btree_cur            *cur,
     642             :         const union xfs_btree_key       *key1,
     643             :         const union xfs_btree_key       *key2)
     644             : {
     645  3266283284 :         return cur->bc_ops->diff_two_keys(cur, key1, key2, NULL) == 0;
     646             : }
     647             : 
     648             : static inline bool
     649             : xfs_btree_keycmp_le(
     650             :         struct xfs_btree_cur            *cur,
     651             :         const union xfs_btree_key       *key1,
     652             :         const union xfs_btree_key       *key2)
     653             : {
     654  7213517560 :         return !xfs_btree_keycmp_gt(cur, key1, key2);
     655             : }
     656             : 
     657             : static inline bool
     658             : xfs_btree_keycmp_ge(
     659             :         struct xfs_btree_cur            *cur,
     660             :         const union xfs_btree_key       *key1,
     661             :         const union xfs_btree_key       *key2)
     662             : {
     663 >22825*10^7 :         return !xfs_btree_keycmp_lt(cur, key1, key2);
     664             : }
     665             : 
     666             : static inline bool
     667             : xfs_btree_keycmp_ne(
     668             :         struct xfs_btree_cur            *cur,
     669             :         const union xfs_btree_key       *key1,
     670             :         const union xfs_btree_key       *key2)
     671             : {
     672    65589472 :         return !xfs_btree_keycmp_eq(cur, key1, key2);
     673             : }
     674             : 
     675             : /* Masked key comparison helpers */
     676             : static inline bool
     677             : xfs_btree_masked_keycmp_lt(
     678             :         struct xfs_btree_cur            *cur,
     679             :         const union xfs_btree_key       *key1,
     680             :         const union xfs_btree_key       *key2,
     681             :         const union xfs_btree_key       *mask)
     682             : {
     683    24872887 :         return cur->bc_ops->diff_two_keys(cur, key1, key2, mask) < 0;
     684             : }
     685             : 
     686             : static inline bool
     687             : xfs_btree_masked_keycmp_gt(
     688             :         struct xfs_btree_cur            *cur,
     689             :         const union xfs_btree_key       *key1,
     690             :         const union xfs_btree_key       *key2,
     691             :         const union xfs_btree_key       *mask)
     692             : {
     693  6842071473 :         return cur->bc_ops->diff_two_keys(cur, key1, key2, mask) > 0;
     694             : }
     695             : 
     696             : static inline bool
     697             : xfs_btree_masked_keycmp_ge(
     698             :         struct xfs_btree_cur            *cur,
     699             :         const union xfs_btree_key       *key1,
     700             :         const union xfs_btree_key       *key2,
     701             :         const union xfs_btree_key       *mask)
     702             : {
     703    24873176 :         return !xfs_btree_masked_keycmp_lt(cur, key1, key2, mask);
     704             : }
     705             : 
     706             : /* Does this cursor point to the last block in the given level? */
     707             : static inline bool
     708    90493495 : xfs_btree_islastblock(
     709             :         struct xfs_btree_cur    *cur,
     710             :         int                     level)
     711             : {
     712    90493495 :         struct xfs_btree_block  *block;
     713    90493495 :         struct xfs_buf          *bp;
     714             : 
     715    90493495 :         block = xfs_btree_get_block(cur, level, &bp);
     716             : 
     717    90468968 :         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
     718           0 :                 return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK);
     719    90468968 :         return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK);
     720             : }
     721             : 
     722             : void xfs_btree_set_ptr_null(struct xfs_btree_cur *cur,
     723             :                 union xfs_btree_ptr *ptr);
     724             : int xfs_btree_get_buf_block(struct xfs_btree_cur *cur,
     725             :                 const union xfs_btree_ptr *ptr, struct xfs_btree_block **block,
     726             :                 struct xfs_buf **bpp);
     727             : int xfs_btree_read_buf_block(struct xfs_btree_cur *cur,
     728             :                 const union xfs_btree_ptr *ptr, int flags,
     729             :                 struct xfs_btree_block **block, struct xfs_buf **bpp);
     730             : void xfs_btree_set_sibling(struct xfs_btree_cur *cur,
     731             :                 struct xfs_btree_block *block, const union xfs_btree_ptr *ptr,
     732             :                 int lr);
     733             : void xfs_btree_init_block_cur(struct xfs_btree_cur *cur,
     734             :                 struct xfs_buf *bp, int level, int numrecs);
     735             : void xfs_btree_copy_ptrs(struct xfs_btree_cur *cur,
     736             :                 union xfs_btree_ptr *dst_ptr,
     737             :                 const union xfs_btree_ptr *src_ptr, int numptrs);
     738             : void xfs_btree_copy_keys(struct xfs_btree_cur *cur,
     739             :                 union xfs_btree_key *dst_key,
     740             :                 const union xfs_btree_key *src_key, int numkeys);
     741             : 
     742             : static inline struct xfs_btree_cur *
     743 12045749828 : xfs_btree_alloc_cursor(
     744             :         struct xfs_mount        *mp,
     745             :         struct xfs_trans        *tp,
     746             :         xfs_btnum_t             btnum,
     747             :         const struct xfs_btree_ops *ops,
     748             :         uint8_t                 maxlevels,
     749             :         struct kmem_cache       *cache)
     750             : {
     751 12045749828 :         struct xfs_btree_cur    *cur;
     752             : 
     753 12045749828 :         cur = kmem_cache_zalloc(cache, GFP_NOFS | __GFP_NOFAIL);
     754 12055874510 :         cur->bc_ops = ops;
     755 12055874510 :         cur->bc_tp = tp;
     756 12055874510 :         cur->bc_mp = mp;
     757 12055874510 :         cur->bc_btnum = btnum;
     758 12055874510 :         cur->bc_maxlevels = maxlevels;
     759 12055874510 :         cur->bc_cache = cache;
     760 12055874510 :         cur->bc_flags = ops->geom_flags;
     761 12055874510 :         if (xfs_has_crc(mp))
     762 12053685270 :                 cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
     763             : 
     764 12055874510 :         return cur;
     765             : }
     766             : 
     767             : int __init xfs_btree_init_cur_caches(void);
     768             : void xfs_btree_destroy_cur_caches(void);
     769             : 
     770             : int xfs_btree_goto_left_edge(struct xfs_btree_cur *cur);
     771             : 
     772             : int xfs_btree_alloc_imeta_block(struct xfs_btree_cur *cur,
     773             :                 const union xfs_btree_ptr *start, union xfs_btree_ptr *newp,
     774             :                 int *stat);
     775             : int xfs_btree_free_imeta_block(struct xfs_btree_cur *cur, struct xfs_buf *bp);
     776             : 
     777             : #endif  /* __XFS_BTREE_H__ */

Generated by: LCOV version 1.14