1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 4 * All Rights Reserved. 5 */ 6 #ifndef __XFS_RTBITMAP_H__ 7 #define __XFS_RTBITMAP_H__ 8 9 #include "xfs_rtgroup.h" 10 11 struct xfs_rtalloc_args { 12 struct xfs_rtgroup *rtg; 13 struct xfs_mount *mp; 14 struct xfs_trans *tp; 15 16 struct xfs_buf *rbmbp; /* bitmap block buffer */ 17 struct xfs_buf *sumbp; /* summary block buffer */ 18 19 xfs_fileoff_t rbmoff; /* bitmap block number */ 20 xfs_fileoff_t sumoff; /* summary block number */ 21 }; 22 23 /* Return the payload of the buffer after the optional header. */ 24 static inline void * 25 xfs_rtblock_payload( 26 struct xfs_buf *bp) 27 { 28 if (!xfs_has_rtgroups(bp->b_mount)) 29 return bp->b_addr; 30 return bp->b_addr + sizeof(struct xfs_rtbuf_blkinfo); 31 } 32 33 static inline xfs_rtblock_t 34 xfs_rtx_to_rtb( 35 struct xfs_rtgroup *rtg, 36 xfs_rtxnum_t rtx) 37 { 38 struct xfs_mount *mp = rtg_mount(rtg); 39 xfs_rtblock_t start = xfs_group_start_fsb(rtg_group(rtg)); 40 41 if (mp->m_rtxblklog >= 0) 42 return start + (rtx << mp->m_rtxblklog); 43 return start + (rtx * mp->m_sb.sb_rextsize); 44 } 45 46 /* Convert an rgbno into an rt extent number. */ 47 static inline xfs_rtxnum_t 48 xfs_rgbno_to_rtx( 49 struct xfs_mount *mp, 50 xfs_rgblock_t rgbno) 51 { 52 if (likely(mp->m_rtxblklog >= 0)) 53 return rgbno >> mp->m_rtxblklog; 54 return rgbno / mp->m_sb.sb_rextsize; 55 } 56 57 static inline uint64_t 58 xfs_rtbxlen_to_blen( 59 struct xfs_mount *mp, 60 xfs_rtbxlen_t rtbxlen) 61 { 62 if (mp->m_rtxblklog >= 0) 63 return rtbxlen << mp->m_rtxblklog; 64 65 return rtbxlen * mp->m_sb.sb_rextsize; 66 } 67 68 static inline xfs_extlen_t 69 xfs_rtxlen_to_extlen( 70 struct xfs_mount *mp, 71 xfs_rtxlen_t rtxlen) 72 { 73 if (mp->m_rtxblklog >= 0) 74 return rtxlen << mp->m_rtxblklog; 75 76 return rtxlen * mp->m_sb.sb_rextsize; 77 } 78 79 /* Compute the misalignment between an extent length and a realtime extent .*/ 80 static inline unsigned int 81 xfs_extlen_to_rtxmod( 82 struct xfs_mount *mp, 83 xfs_extlen_t len) 84 { 85 if (mp->m_rtxblklog >= 0) 86 return len & mp->m_rtxblkmask; 87 88 return len % mp->m_sb.sb_rextsize; 89 } 90 91 static inline xfs_rtxlen_t 92 xfs_extlen_to_rtxlen( 93 struct xfs_mount *mp, 94 xfs_extlen_t len) 95 { 96 if (mp->m_rtxblklog >= 0) 97 return len >> mp->m_rtxblklog; 98 99 return len / mp->m_sb.sb_rextsize; 100 } 101 102 /* Convert an rt block count into an rt extent count. */ 103 static inline xfs_rtbxlen_t 104 xfs_blen_to_rtbxlen( 105 struct xfs_mount *mp, 106 uint64_t blen) 107 { 108 if (likely(mp->m_rtxblklog >= 0)) 109 return blen >> mp->m_rtxblklog; 110 111 return div_u64(blen, mp->m_sb.sb_rextsize); 112 } 113 114 /* Return the offset of a file block length within an rt extent. */ 115 static inline xfs_extlen_t 116 xfs_blen_to_rtxoff( 117 struct xfs_mount *mp, 118 xfs_filblks_t blen) 119 { 120 if (likely(mp->m_rtxblklog >= 0)) 121 return blen & mp->m_rtxblkmask; 122 123 return do_div(blen, mp->m_sb.sb_rextsize); 124 } 125 126 /* Round this block count up to the nearest rt extent size. */ 127 static inline xfs_filblks_t 128 xfs_blen_roundup_rtx( 129 struct xfs_mount *mp, 130 xfs_filblks_t blen) 131 { 132 return roundup_64(blen, mp->m_sb.sb_rextsize); 133 } 134 135 /* Convert an rt block number into an rt extent number. */ 136 static inline xfs_rtxnum_t 137 xfs_rtb_to_rtx( 138 struct xfs_mount *mp, 139 xfs_rtblock_t rtbno) 140 { 141 /* open-coded 64-bit masking operation */ 142 rtbno &= mp->m_groups[XG_TYPE_RTG].blkmask; 143 if (likely(mp->m_rtxblklog >= 0)) 144 return rtbno >> mp->m_rtxblklog; 145 return div_u64(rtbno, mp->m_sb.sb_rextsize); 146 } 147 148 /* Return the offset of a rtgroup block number within an rt extent. */ 149 static inline xfs_extlen_t 150 xfs_rgbno_to_rtxoff( 151 struct xfs_mount *mp, 152 xfs_rgblock_t rgbno) 153 { 154 return rgbno % mp->m_sb.sb_rextsize; 155 } 156 157 /* Return the offset of an rt block number within an rt extent. */ 158 static inline xfs_extlen_t 159 xfs_rtb_to_rtxoff( 160 struct xfs_mount *mp, 161 xfs_rtblock_t rtbno) 162 { 163 /* open-coded 64-bit masking operation */ 164 rtbno &= mp->m_groups[XG_TYPE_RTG].blkmask; 165 if (likely(mp->m_rtxblklog >= 0)) 166 return rtbno & mp->m_rtxblkmask; 167 return do_div(rtbno, mp->m_sb.sb_rextsize); 168 } 169 170 /* Round this file block offset up to the nearest rt extent size. */ 171 static inline xfs_rtblock_t 172 xfs_fileoff_roundup_rtx( 173 struct xfs_mount *mp, 174 xfs_fileoff_t off) 175 { 176 return roundup_64(off, mp->m_sb.sb_rextsize); 177 } 178 179 /* Round this file block offset down to the nearest rt extent size. */ 180 static inline xfs_rtblock_t 181 xfs_fileoff_rounddown_rtx( 182 struct xfs_mount *mp, 183 xfs_fileoff_t off) 184 { 185 return rounddown_64(off, mp->m_sb.sb_rextsize); 186 } 187 188 /* Convert an rt extent number to a file block offset in the rt bitmap file. */ 189 static inline xfs_fileoff_t 190 xfs_rtx_to_rbmblock( 191 struct xfs_mount *mp, 192 xfs_rtxnum_t rtx) 193 { 194 if (xfs_has_rtgroups(mp)) 195 return div_u64(rtx, mp->m_rtx_per_rbmblock); 196 197 return rtx >> mp->m_blkbit_log; 198 } 199 200 /* Convert an rt extent number to a word offset within an rt bitmap block. */ 201 static inline unsigned int 202 xfs_rtx_to_rbmword( 203 struct xfs_mount *mp, 204 xfs_rtxnum_t rtx) 205 { 206 if (xfs_has_rtgroups(mp)) { 207 unsigned int mod; 208 209 div_u64_rem(rtx >> XFS_NBWORDLOG, mp->m_blockwsize, &mod); 210 return mod; 211 } 212 213 return (rtx >> XFS_NBWORDLOG) & (mp->m_blockwsize - 1); 214 } 215 216 /* Convert a file block offset in the rt bitmap file to an rt extent number. */ 217 static inline xfs_rtxnum_t 218 xfs_rbmblock_to_rtx( 219 struct xfs_mount *mp, 220 xfs_fileoff_t rbmoff) 221 { 222 if (xfs_has_rtgroups(mp)) 223 return rbmoff * mp->m_rtx_per_rbmblock; 224 225 return rbmoff << mp->m_blkbit_log; 226 } 227 228 /* Return a pointer to a bitmap word within a rt bitmap block. */ 229 static inline union xfs_rtword_raw * 230 xfs_rbmblock_wordptr( 231 struct xfs_rtalloc_args *args, 232 unsigned int index) 233 { 234 union xfs_rtword_raw *words = xfs_rtblock_payload(args->rbmbp); 235 236 return words + index; 237 } 238 239 /* Convert an ondisk bitmap word to its incore representation. */ 240 static inline xfs_rtword_t 241 xfs_rtbitmap_getword( 242 struct xfs_rtalloc_args *args, 243 unsigned int index) 244 { 245 union xfs_rtword_raw *word = xfs_rbmblock_wordptr(args, index); 246 247 if (xfs_has_rtgroups(args->mp)) 248 return be32_to_cpu(word->rtg); 249 return word->old; 250 } 251 252 /* Set an ondisk bitmap word from an incore representation. */ 253 static inline void 254 xfs_rtbitmap_setword( 255 struct xfs_rtalloc_args *args, 256 unsigned int index, 257 xfs_rtword_t value) 258 { 259 union xfs_rtword_raw *word = xfs_rbmblock_wordptr(args, index); 260 261 if (xfs_has_rtgroups(args->mp)) 262 word->rtg = cpu_to_be32(value); 263 else 264 word->old = value; 265 } 266 267 /* 268 * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t 269 * offset within the rt summary file. 270 */ 271 static inline xfs_rtsumoff_t 272 xfs_rtsumoffs( 273 struct xfs_mount *mp, 274 int log2_len, 275 xfs_fileoff_t rbmoff) 276 { 277 return log2_len * mp->m_sb.sb_rbmblocks + rbmoff; 278 } 279 280 /* 281 * Convert an xfs_suminfo_t offset to a file block offset within the rt summary 282 * file. 283 */ 284 static inline xfs_fileoff_t 285 xfs_rtsumoffs_to_block( 286 struct xfs_mount *mp, 287 xfs_rtsumoff_t rsumoff) 288 { 289 if (xfs_has_rtgroups(mp)) 290 return rsumoff / mp->m_blockwsize; 291 292 return XFS_B_TO_FSBT(mp, rsumoff * sizeof(xfs_suminfo_t)); 293 } 294 295 /* 296 * Convert an xfs_suminfo_t offset to an info word offset within an rt summary 297 * block. 298 */ 299 static inline unsigned int 300 xfs_rtsumoffs_to_infoword( 301 struct xfs_mount *mp, 302 xfs_rtsumoff_t rsumoff) 303 { 304 unsigned int mask = mp->m_blockmask >> XFS_SUMINFOLOG; 305 306 if (xfs_has_rtgroups(mp)) 307 return rsumoff % mp->m_blockwsize; 308 309 return rsumoff & mask; 310 } 311 312 /* Return a pointer to a summary info word within a rt summary block. */ 313 static inline union xfs_suminfo_raw * 314 xfs_rsumblock_infoptr( 315 struct xfs_rtalloc_args *args, 316 unsigned int index) 317 { 318 union xfs_suminfo_raw *info = xfs_rtblock_payload(args->sumbp); 319 320 return info + index; 321 } 322 323 /* Get the current value of a summary counter. */ 324 static inline xfs_suminfo_t 325 xfs_suminfo_get( 326 struct xfs_rtalloc_args *args, 327 unsigned int index) 328 { 329 union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(args, index); 330 331 if (xfs_has_rtgroups(args->mp)) 332 return be32_to_cpu(info->rtg); 333 return info->old; 334 } 335 336 /* Add to the current value of a summary counter and return the new value. */ 337 static inline xfs_suminfo_t 338 xfs_suminfo_add( 339 struct xfs_rtalloc_args *args, 340 unsigned int index, 341 int delta) 342 { 343 union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(args, index); 344 345 if (xfs_has_rtgroups(args->mp)) { 346 be32_add_cpu(&info->rtg, delta); 347 return be32_to_cpu(info->rtg); 348 } 349 350 info->old += delta; 351 return info->old; 352 } 353 354 /* 355 * Functions for walking free space rtextents in the realtime bitmap. 356 */ 357 struct xfs_rtalloc_rec { 358 xfs_rtxnum_t ar_startext; 359 xfs_rtbxlen_t ar_extcount; 360 }; 361 362 typedef int (*xfs_rtalloc_query_range_fn)( 363 struct xfs_rtgroup *rtg, 364 struct xfs_trans *tp, 365 const struct xfs_rtalloc_rec *rec, 366 void *priv); 367 368 #ifdef CONFIG_XFS_RT 369 void xfs_rtbuf_cache_relse(struct xfs_rtalloc_args *args); 370 int xfs_rtbitmap_read_buf(struct xfs_rtalloc_args *args, xfs_fileoff_t block); 371 int xfs_rtsummary_read_buf(struct xfs_rtalloc_args *args, xfs_fileoff_t block); 372 int xfs_rtcheck_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 373 xfs_rtxlen_t len, int val, xfs_rtxnum_t *new, int *stat); 374 int xfs_rtfind_back(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 375 xfs_rtxnum_t *rtblock); 376 int xfs_rtfind_forw(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 377 xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock); 378 int xfs_rtmodify_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 379 xfs_rtxlen_t len, int val); 380 int xfs_rtget_summary(struct xfs_rtalloc_args *args, int log, 381 xfs_fileoff_t bbno, xfs_suminfo_t *sum); 382 int xfs_rtmodify_summary(struct xfs_rtalloc_args *args, int log, 383 xfs_fileoff_t bbno, int delta); 384 int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 385 xfs_rtxlen_t len); 386 int xfs_rtalloc_query_range(struct xfs_rtgroup *rtg, struct xfs_trans *tp, 387 xfs_rtxnum_t start, xfs_rtxnum_t end, 388 xfs_rtalloc_query_range_fn fn, void *priv); 389 int xfs_rtalloc_query_all(struct xfs_rtgroup *rtg, struct xfs_trans *tp, 390 xfs_rtalloc_query_range_fn fn, void *priv); 391 int xfs_rtalloc_extent_is_free(struct xfs_rtgroup *rtg, struct xfs_trans *tp, 392 xfs_rtxnum_t start, xfs_rtxlen_t len, bool *is_free); 393 int xfs_rtfree_extent(struct xfs_trans *tp, struct xfs_rtgroup *rtg, 394 xfs_rtxnum_t start, xfs_rtxlen_t len); 395 /* Same as above, but in units of rt blocks. */ 396 int xfs_rtfree_blocks(struct xfs_trans *tp, struct xfs_rtgroup *rtg, 397 xfs_fsblock_t rtbno, xfs_filblks_t rtlen); 398 399 xfs_rtxnum_t xfs_rtbitmap_rtx_per_rbmblock(struct xfs_mount *mp); 400 xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp); 401 xfs_filblks_t xfs_rtbitmap_blockcount_len(struct xfs_mount *mp, 402 xfs_rtbxlen_t rtextents); 403 xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp, 404 unsigned int *rsumlevels); 405 406 const struct xfs_buf_ops *xfs_rtblock_ops(struct xfs_mount *mp, 407 enum xfs_rtg_inodes type); 408 void xfs_rtfile_initialize_buf(struct xfs_rtgroup *rtg, 409 enum xfs_rtg_inodes type, struct xfs_buf *bp, 410 struct xfs_trans *tp); 411 int xfs_rtfile_initialize_blocks(struct xfs_rtgroup *rtg, 412 enum xfs_rtg_inodes type, xfs_fileoff_t offset_fsb, 413 xfs_fileoff_t end_fsb, void *data); 414 int xfs_rtbitmap_create(struct xfs_rtgroup *rtg, struct xfs_inode *ip, 415 struct xfs_trans *tp, bool init); 416 int xfs_rtsummary_create(struct xfs_rtgroup *rtg, struct xfs_inode *ip, 417 struct xfs_trans *tp, bool init); 418 419 #else /* CONFIG_XFS_RT */ 420 # define xfs_rtfree_extent(t,b,l) (-ENOSYS) 421 422 static inline int xfs_rtfree_blocks(struct xfs_trans *tp, 423 struct xfs_rtgroup *rtg, xfs_fsblock_t rtbno, 424 xfs_filblks_t rtlen) 425 { 426 return -ENOSYS; 427 } 428 # define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS) 429 # define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) 430 # define xfs_rtbitmap_read_buf(a,b) (-ENOSYS) 431 # define xfs_rtsummary_read_buf(a,b) (-ENOSYS) 432 # define xfs_rtbuf_cache_relse(a) (0) 433 # define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) 434 static inline xfs_filblks_t 435 xfs_rtbitmap_blockcount_len(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) 436 { 437 /* shut up gcc */ 438 return 0; 439 } 440 #endif /* CONFIG_XFS_RT */ 441 442 #endif /* __XFS_RTBITMAP_H__ */ 443