1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2018-2024 Oracle. All Rights Reserved. 4 * Author: Darrick J. Wong <djwong@kernel.org> 5 */ 6 #include "xfs.h" 7 #include "xfs_fs.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_log_format.h" 11 #include "xfs_trans_resv.h" 12 #include "xfs_bit.h" 13 #include "xfs_sb.h" 14 #include "xfs_mount.h" 15 #include "xfs_defer.h" 16 #include "xfs_inode.h" 17 #include "xfs_trans.h" 18 #include "xfs_alloc.h" 19 #include "xfs_btree.h" 20 #include "xfs_btree_staging.h" 21 #include "xfs_rtrmap_btree.h" 22 #include "xfs_trace.h" 23 #include "xfs_cksum.h" 24 #include "xfs_error.h" 25 #include "xfs_extent_busy.h" 26 #include "xfs_rtgroup.h" 27 28 static struct kmem_cache *xfs_rtrmapbt_cur_cache; 29 30 /* 31 * Realtime Reverse Map btree. 32 * 33 * This is a btree used to track the owner(s) of a given extent in the realtime 34 * device. See the comments in xfs_rmap_btree.c for more information. 35 * 36 * This tree is basically the same as the regular rmap btree except that it 37 * is rooted in an inode and does not live in free space. 38 */ 39 40 static struct xfs_btree_cur * 41 xfs_rtrmapbt_dup_cursor( 42 struct xfs_btree_cur *cur) 43 { 44 return xfs_rtrmapbt_init_cursor(cur->bc_tp, to_rtg(cur->bc_group)); 45 } 46 47 static xfs_failaddr_t 48 xfs_rtrmapbt_verify( 49 struct xfs_buf *bp) 50 { 51 struct xfs_mount *mp = bp->b_target->bt_mount; 52 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); 53 xfs_failaddr_t fa; 54 int level; 55 56 if (!xfs_verify_magic(bp, block->bb_magic)) 57 return __this_address; 58 59 if (!xfs_has_rmapbt(mp)) 60 return __this_address; 61 fa = xfs_btree_fsblock_v5hdr_verify(bp, XFS_RMAP_OWN_UNKNOWN); 62 if (fa) 63 return fa; 64 level = be16_to_cpu(block->bb_level); 65 if (level > mp->m_rtrmap_maxlevels) 66 return __this_address; 67 68 return xfs_btree_fsblock_verify(bp, mp->m_rtrmap_mxr[level != 0]); 69 } 70 71 static void 72 xfs_rtrmapbt_read_verify( 73 struct xfs_buf *bp) 74 { 75 xfs_failaddr_t fa; 76 77 if (!xfs_btree_fsblock_verify_crc(bp)) 78 xfs_verifier_error(bp, -EFSBADCRC, __this_address); 79 else { 80 fa = xfs_rtrmapbt_verify(bp); 81 if (fa) 82 xfs_verifier_error(bp, -EFSCORRUPTED, fa); 83 } 84 85 if (bp->b_error) 86 trace_xfs_btree_corrupt(bp, _RET_IP_); 87 } 88 89 static void 90 xfs_rtrmapbt_write_verify( 91 struct xfs_buf *bp) 92 { 93 xfs_failaddr_t fa; 94 95 fa = xfs_rtrmapbt_verify(bp); 96 if (fa) { 97 trace_xfs_btree_corrupt(bp, _RET_IP_); 98 xfs_verifier_error(bp, -EFSCORRUPTED, fa); 99 return; 100 } 101 xfs_btree_fsblock_calc_crc(bp); 102 103 } 104 105 const struct xfs_buf_ops xfs_rtrmapbt_buf_ops = { 106 .name = "xfs_rtrmapbt", 107 .magic = { 0, cpu_to_be32(XFS_RTRMAP_CRC_MAGIC) }, 108 .verify_read = xfs_rtrmapbt_read_verify, 109 .verify_write = xfs_rtrmapbt_write_verify, 110 .verify_struct = xfs_rtrmapbt_verify, 111 }; 112 113 const struct xfs_btree_ops xfs_rtrmapbt_ops = { 114 .name = "rtrmap", 115 .type = XFS_BTREE_TYPE_INODE, 116 .geom_flags = XFS_BTGEO_OVERLAPPING | 117 XFS_BTGEO_IROOT_RECORDS, 118 119 .rec_len = sizeof(struct xfs_rmap_rec), 120 /* Overlapping btree; 2 keys per pointer. */ 121 .key_len = 2 * sizeof(struct xfs_rmap_key), 122 .ptr_len = XFS_BTREE_LONG_PTR_LEN, 123 124 .lru_refs = XFS_RMAP_BTREE_REF, 125 .statoff = XFS_STATS_CALC_INDEX(xs_rtrmap_2), 126 127 .dup_cursor = xfs_rtrmapbt_dup_cursor, 128 .buf_ops = &xfs_rtrmapbt_buf_ops, 129 }; 130 131 /* Allocate a new rt rmap btree cursor. */ 132 struct xfs_btree_cur * 133 xfs_rtrmapbt_init_cursor( 134 struct xfs_trans *tp, 135 struct xfs_rtgroup *rtg) 136 { 137 struct xfs_inode *ip = NULL; 138 struct xfs_mount *mp = rtg_mount(rtg); 139 struct xfs_btree_cur *cur; 140 141 return NULL; /* XXX */ 142 143 xfs_assert_ilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL); 144 145 cur = xfs_btree_alloc_cursor(mp, tp, &xfs_rtrmapbt_ops, 146 mp->m_rtrmap_maxlevels, xfs_rtrmapbt_cur_cache); 147 148 cur->bc_ino.ip = ip; 149 cur->bc_group = xfs_group_hold(rtg_group(rtg)); 150 cur->bc_ino.whichfork = XFS_DATA_FORK; 151 cur->bc_nlevels = be16_to_cpu(ip->i_df.if_broot->bb_level) + 1; 152 cur->bc_ino.forksize = xfs_inode_fork_size(ip, XFS_DATA_FORK); 153 154 return cur; 155 } 156 157 /* 158 * Install a new rt reverse mapping btree root. Caller is responsible for 159 * invalidating and freeing the old btree blocks. 160 */ 161 void 162 xfs_rtrmapbt_commit_staged_btree( 163 struct xfs_btree_cur *cur, 164 struct xfs_trans *tp) 165 { 166 struct xbtree_ifakeroot *ifake = cur->bc_ino.ifake; 167 struct xfs_ifork *ifp; 168 int flags = XFS_ILOG_CORE | XFS_ILOG_DBROOT; 169 170 ASSERT(cur->bc_flags & XFS_BTREE_STAGING); 171 172 /* 173 * Free any resources hanging off the real fork, then shallow-copy the 174 * staging fork's contents into the real fork to transfer everything 175 * we just built. 176 */ 177 ifp = xfs_ifork_ptr(cur->bc_ino.ip, XFS_DATA_FORK); 178 xfs_idestroy_fork(ifp); 179 memcpy(ifp, ifake->if_fork, sizeof(struct xfs_ifork)); 180 181 cur->bc_ino.ip->i_projid = cur->bc_group->xg_gno; 182 xfs_trans_log_inode(tp, cur->bc_ino.ip, flags); 183 xfs_btree_commit_ifakeroot(cur, tp, XFS_DATA_FORK); 184 } 185 186 /* Calculate number of records in a rt reverse mapping btree block. */ 187 static inline unsigned int 188 xfs_rtrmapbt_block_maxrecs( 189 unsigned int blocklen, 190 bool leaf) 191 { 192 if (leaf) 193 return blocklen / sizeof(struct xfs_rmap_rec); 194 return blocklen / 195 (2 * sizeof(struct xfs_rmap_key) + sizeof(xfs_rtrmap_ptr_t)); 196 } 197 198 /* 199 * Calculate number of records in an rt reverse mapping btree block. 200 */ 201 unsigned int 202 xfs_rtrmapbt_maxrecs( 203 struct xfs_mount *mp, 204 unsigned int blocklen, 205 bool leaf) 206 { 207 blocklen -= XFS_RTRMAP_BLOCK_LEN; 208 return xfs_rtrmapbt_block_maxrecs(blocklen, leaf); 209 } 210 211 /* Compute the max possible height for realtime reverse mapping btrees. */ 212 unsigned int 213 xfs_rtrmapbt_maxlevels_ondisk(void) 214 { 215 unsigned int minrecs[2]; 216 unsigned int blocklen; 217 218 blocklen = XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_LBLOCK_CRC_LEN; 219 220 minrecs[0] = xfs_rtrmapbt_block_maxrecs(blocklen, true) / 2; 221 minrecs[1] = xfs_rtrmapbt_block_maxrecs(blocklen, false) / 2; 222 223 /* We need at most one record for every block in an rt group. */ 224 return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_RGBLOCKS); 225 } 226 227 int __init 228 xfs_rtrmapbt_init_cur_cache(void) 229 { 230 xfs_rtrmapbt_cur_cache = kmem_cache_create("xfs_rtrmapbt_cur", 231 xfs_btree_cur_sizeof(xfs_rtrmapbt_maxlevels_ondisk()), 232 0, 0, NULL); 233 234 if (!xfs_rtrmapbt_cur_cache) 235 return -ENOMEM; 236 return 0; 237 } 238 239 void 240 xfs_rtrmapbt_destroy_cur_cache(void) 241 { 242 kmem_cache_destroy(xfs_rtrmapbt_cur_cache); 243 xfs_rtrmapbt_cur_cache = NULL; 244 } 245 246 /* Compute the maximum height of an rt reverse mapping btree. */ 247 void 248 xfs_rtrmapbt_compute_maxlevels( 249 struct xfs_mount *mp) 250 { 251 unsigned int d_maxlevels, r_maxlevels; 252 253 if (!xfs_has_rtrmapbt(mp)) { 254 mp->m_rtrmap_maxlevels = 0; 255 return; 256 } 257 258 /* 259 * The realtime rmapbt lives on the data device, which means that its 260 * maximum height is constrained by the size of the data device and 261 * the height required to store one rmap record for each block in an 262 * rt group. 263 */ 264 d_maxlevels = xfs_btree_space_to_height(mp->m_rtrmap_mnr, 265 mp->m_sb.sb_dblocks); 266 r_maxlevels = xfs_btree_compute_maxlevels(mp->m_rtrmap_mnr, 267 mp->m_groups[XG_TYPE_RTG].blocks); 268 269 /* Add one level to handle the inode root level. */ 270 mp->m_rtrmap_maxlevels = min(d_maxlevels, r_maxlevels) + 1; 271 } 272