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