1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Copyright (c) 2021-2024 Oracle. All Rights Reserved. 4 * Author: Darrick J. Wong <djwong@kernel.org> 5 */ 6 #ifndef __XFS_RTREFCOUNT_BTREE_H__ 7 #define __XFS_RTREFCOUNT_BTREE_H__ 8 9 struct xfs_buf; 10 struct xfs_btree_cur; 11 struct xfs_mount; 12 struct xbtree_ifakeroot; 13 struct xfs_rtgroup; 14 15 /* refcounts only exist on crc enabled filesystems */ 16 #define XFS_RTREFCOUNT_BLOCK_LEN XFS_BTREE_LBLOCK_CRC_LEN 17 18 struct xfs_btree_cur *xfs_rtrefcountbt_init_cursor(struct xfs_trans *tp, 19 struct xfs_rtgroup *rtg); 20 struct xfs_btree_cur *xfs_rtrefcountbt_stage_cursor(struct xfs_mount *mp, 21 struct xfs_rtgroup *rtg, struct xfs_inode *ip, 22 struct xbtree_ifakeroot *ifake); 23 void xfs_rtrefcountbt_commit_staged_btree(struct xfs_btree_cur *cur, 24 struct xfs_trans *tp); 25 unsigned int xfs_rtrefcountbt_maxrecs(struct xfs_mount *mp, 26 unsigned int blocklen, bool leaf); 27 void xfs_rtrefcountbt_compute_maxlevels(struct xfs_mount *mp); 28 unsigned int xfs_rtrefcountbt_droot_maxrecs(unsigned int blocklen, bool leaf); 29 30 /* 31 * Addresses of records, keys, and pointers within an incore rtrefcountbt block. 32 * 33 * (note that some of these may appear unused, but they are used in userspace) 34 */ 35 static inline struct xfs_refcount_rec * 36 xfs_rtrefcount_rec_addr( 37 struct xfs_btree_block *block, 38 unsigned int index) 39 { 40 return (struct xfs_refcount_rec *) 41 ((char *)block + XFS_RTREFCOUNT_BLOCK_LEN + 42 (index - 1) * sizeof(struct xfs_refcount_rec)); 43 } 44 45 static inline struct xfs_refcount_key * 46 xfs_rtrefcount_key_addr( 47 struct xfs_btree_block *block, 48 unsigned int index) 49 { 50 return (struct xfs_refcount_key *) 51 ((char *)block + XFS_RTREFCOUNT_BLOCK_LEN + 52 (index - 1) * sizeof(struct xfs_refcount_key)); 53 } 54 55 static inline xfs_rtrefcount_ptr_t * 56 xfs_rtrefcount_ptr_addr( 57 struct xfs_btree_block *block, 58 unsigned int index, 59 unsigned int maxrecs) 60 { 61 return (xfs_rtrefcount_ptr_t *) 62 ((char *)block + XFS_RTREFCOUNT_BLOCK_LEN + 63 maxrecs * sizeof(struct xfs_refcount_key) + 64 (index - 1) * sizeof(xfs_rtrefcount_ptr_t)); 65 } 66 67 unsigned int xfs_rtrefcountbt_maxlevels_ondisk(void); 68 int __init xfs_rtrefcountbt_init_cur_cache(void); 69 void xfs_rtrefcountbt_destroy_cur_cache(void); 70 71 xfs_filblks_t xfs_rtrefcountbt_calc_reserves(struct xfs_mount *mp); 72 unsigned long long xfs_rtrefcountbt_calc_size(struct xfs_mount *mp, 73 unsigned long long len); 74 75 /* Addresses of key, pointers, and records within an ondisk rtrefcount block. */ 76 77 static inline struct xfs_refcount_rec * 78 xfs_rtrefcount_droot_rec_addr( 79 struct xfs_rtrefcount_root *block, 80 unsigned int index) 81 { 82 return (struct xfs_refcount_rec *) 83 ((char *)(block + 1) + 84 (index - 1) * sizeof(struct xfs_refcount_rec)); 85 } 86 87 static inline struct xfs_refcount_key * 88 xfs_rtrefcount_droot_key_addr( 89 struct xfs_rtrefcount_root *block, 90 unsigned int index) 91 { 92 return (struct xfs_refcount_key *) 93 ((char *)(block + 1) + 94 (index - 1) * sizeof(struct xfs_refcount_key)); 95 } 96 97 static inline xfs_rtrefcount_ptr_t * 98 xfs_rtrefcount_droot_ptr_addr( 99 struct xfs_rtrefcount_root *block, 100 unsigned int index, 101 unsigned int maxrecs) 102 { 103 return (xfs_rtrefcount_ptr_t *) 104 ((char *)(block + 1) + 105 maxrecs * sizeof(struct xfs_refcount_key) + 106 (index - 1) * sizeof(xfs_rtrefcount_ptr_t)); 107 } 108 109 /* 110 * Address of pointers within the incore btree root. 111 * 112 * These are to be used when we know the size of the block and 113 * we don't have a cursor. 114 */ 115 static inline xfs_rtrefcount_ptr_t * 116 xfs_rtrefcount_broot_ptr_addr( 117 struct xfs_mount *mp, 118 struct xfs_btree_block *bb, 119 unsigned int index, 120 unsigned int block_size) 121 { 122 return xfs_rtrefcount_ptr_addr(bb, index, 123 xfs_rtrefcountbt_maxrecs(mp, block_size, false)); 124 } 125 126 /* 127 * Compute the space required for the incore btree root containing the given 128 * number of records. 129 */ 130 static inline size_t 131 xfs_rtrefcount_broot_space_calc( 132 struct xfs_mount *mp, 133 unsigned int level, 134 unsigned int nrecs) 135 { 136 size_t sz = XFS_RTREFCOUNT_BLOCK_LEN; 137 138 if (level > 0) 139 return sz + nrecs * (sizeof(struct xfs_refcount_key) + 140 sizeof(xfs_rtrefcount_ptr_t)); 141 return sz + nrecs * sizeof(struct xfs_refcount_rec); 142 } 143 144 /* 145 * Compute the space required for the incore btree root given the ondisk 146 * btree root block. 147 */ 148 static inline size_t 149 xfs_rtrefcount_broot_space(struct xfs_mount *mp, struct xfs_rtrefcount_root *bb) 150 { 151 return xfs_rtrefcount_broot_space_calc(mp, be16_to_cpu(bb->bb_level), 152 be16_to_cpu(bb->bb_numrecs)); 153 } 154 155 /* Compute the space required for the ondisk root block. */ 156 static inline size_t 157 xfs_rtrefcount_droot_space_calc( 158 unsigned int level, 159 unsigned int nrecs) 160 { 161 size_t sz = sizeof(struct xfs_rtrefcount_root); 162 163 if (level > 0) 164 return sz + nrecs * (sizeof(struct xfs_refcount_key) + 165 sizeof(xfs_rtrefcount_ptr_t)); 166 return sz + nrecs * sizeof(struct xfs_refcount_rec); 167 } 168 169 /* 170 * Compute the space required for the ondisk root block given an incore root 171 * block. 172 */ 173 static inline size_t 174 xfs_rtrefcount_droot_space(struct xfs_btree_block *bb) 175 { 176 return xfs_rtrefcount_droot_space_calc(be16_to_cpu(bb->bb_level), 177 be16_to_cpu(bb->bb_numrecs)); 178 } 179 180 int xfs_iformat_rtrefcount(struct xfs_inode *ip, struct xfs_dinode *dip); 181 void xfs_rtrefcountbt_to_disk(struct xfs_mount *mp, 182 struct xfs_btree_block *rblock, int rblocklen, 183 struct xfs_rtrefcount_root *dblock, int dblocklen); 184 void xfs_iflush_rtrefcount(struct xfs_inode *ip, struct xfs_dinode *dip); 185 186 #endif /* __XFS_RTREFCOUNT_BTREE_H__ */ 187