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

Generated by: LCOV version 1.14