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 struct xfs_rtalloc_args { 10 struct xfs_mount *mp; 11 struct xfs_trans *tp; 12 13 struct xfs_buf *rbmbp; /* bitmap block buffer */ 14 struct xfs_buf *sumbp; /* summary block buffer */ 15 16 xfs_fileoff_t rbmoff; /* bitmap block number */ 17 xfs_fileoff_t sumoff; /* summary block number */ 18 }; 19 20 static inline xfs_rtblock_t 21 xfs_rtx_to_rtb( 22 struct xfs_mount *mp, 23 xfs_rtxnum_t rtx) 24 { 25 if (mp->m_rtxblklog >= 0) 26 return rtx << mp->m_rtxblklog; 27 28 return rtx * mp->m_sb.sb_rextsize; 29 } 30 31 static inline xfs_extlen_t 32 xfs_rtxlen_to_extlen( 33 struct xfs_mount *mp, 34 xfs_rtxlen_t rtxlen) 35 { 36 if (mp->m_rtxblklog >= 0) 37 return rtxlen << mp->m_rtxblklog; 38 39 return rtxlen * mp->m_sb.sb_rextsize; 40 } 41 42 /* Compute the misalignment between an extent length and a realtime extent .*/ 43 static inline unsigned int 44 xfs_extlen_to_rtxmod( 45 struct xfs_mount *mp, 46 xfs_extlen_t len) 47 { 48 if (mp->m_rtxblklog >= 0) 49 return len & mp->m_rtxblkmask; 50 51 return len % mp->m_sb.sb_rextsize; 52 } 53 54 static inline xfs_rtxlen_t 55 xfs_extlen_to_rtxlen( 56 struct xfs_mount *mp, 57 xfs_extlen_t len) 58 { 59 if (mp->m_rtxblklog >= 0) 60 return len >> mp->m_rtxblklog; 61 62 return len / mp->m_sb.sb_rextsize; 63 } 64 65 /* Convert an rt block number into an rt extent number. */ 66 static inline xfs_rtxnum_t 67 xfs_rtb_to_rtx( 68 struct xfs_mount *mp, 69 xfs_rtblock_t rtbno) 70 { 71 if (likely(mp->m_rtxblklog >= 0)) 72 return rtbno >> mp->m_rtxblklog; 73 74 return div_u64(rtbno, mp->m_sb.sb_rextsize); 75 } 76 77 /* Return the offset of an rt block number within an rt extent. */ 78 static inline xfs_extlen_t 79 xfs_rtb_to_rtxoff( 80 struct xfs_mount *mp, 81 xfs_rtblock_t rtbno) 82 { 83 if (likely(mp->m_rtxblklog >= 0)) 84 return rtbno & mp->m_rtxblkmask; 85 86 return do_div(rtbno, mp->m_sb.sb_rextsize); 87 } 88 89 /* 90 * Crack an rt block number into an rt extent number and an offset within that 91 * rt extent. Returns the rt extent number directly and the offset in @off. 92 */ 93 static inline xfs_rtxnum_t 94 xfs_rtb_to_rtxrem( 95 struct xfs_mount *mp, 96 xfs_rtblock_t rtbno, 97 xfs_extlen_t *off) 98 { 99 if (likely(mp->m_rtxblklog >= 0)) { 100 *off = rtbno & mp->m_rtxblkmask; 101 return rtbno >> mp->m_rtxblklog; 102 } 103 104 return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, off); 105 } 106 107 /* 108 * Convert an rt block number into an rt extent number, rounding up to the next 109 * rt extent if the rt block is not aligned to an rt extent boundary. 110 */ 111 static inline xfs_rtxnum_t 112 xfs_rtb_to_rtxup( 113 struct xfs_mount *mp, 114 xfs_rtblock_t rtbno) 115 { 116 if (likely(mp->m_rtxblklog >= 0)) { 117 if (rtbno & mp->m_rtxblkmask) 118 return (rtbno >> mp->m_rtxblklog) + 1; 119 return rtbno >> mp->m_rtxblklog; 120 } 121 122 if (do_div(rtbno, mp->m_sb.sb_rextsize)) 123 rtbno++; 124 return rtbno; 125 } 126 127 /* Round this rtblock up to the nearest rt extent size. */ 128 static inline xfs_rtblock_t 129 xfs_rtb_roundup_rtx( 130 struct xfs_mount *mp, 131 xfs_rtblock_t rtbno) 132 { 133 return roundup_64(rtbno, mp->m_sb.sb_rextsize); 134 } 135 136 /* Round this rtblock down to the nearest rt extent size. */ 137 static inline xfs_rtblock_t 138 xfs_rtb_rounddown_rtx( 139 struct xfs_mount *mp, 140 xfs_rtblock_t rtbno) 141 { 142 return rounddown_64(rtbno, mp->m_sb.sb_rextsize); 143 } 144 145 /* Convert an rt extent number to a file block offset in the rt bitmap file. */ 146 static inline xfs_fileoff_t 147 xfs_rtx_to_rbmblock( 148 struct xfs_mount *mp, 149 xfs_rtxnum_t rtx) 150 { 151 return rtx >> mp->m_blkbit_log; 152 } 153 154 /* Convert an rt extent number to a word offset within an rt bitmap block. */ 155 static inline unsigned int 156 xfs_rtx_to_rbmword( 157 struct xfs_mount *mp, 158 xfs_rtxnum_t rtx) 159 { 160 return (rtx >> XFS_NBWORDLOG) & (mp->m_blockwsize - 1); 161 } 162 163 /* Convert a file block offset in the rt bitmap file to an rt extent number. */ 164 static inline xfs_rtxnum_t 165 xfs_rbmblock_to_rtx( 166 struct xfs_mount *mp, 167 xfs_fileoff_t rbmoff) 168 { 169 return rbmoff << mp->m_blkbit_log; 170 } 171 172 /* Return a pointer to a bitmap word within a rt bitmap block. */ 173 static inline union xfs_rtword_raw * 174 xfs_rbmblock_wordptr( 175 struct xfs_rtalloc_args *args, 176 unsigned int index) 177 { 178 union xfs_rtword_raw *words = args->rbmbp->b_addr; 179 180 return words + index; 181 } 182 183 /* Convert an ondisk bitmap word to its incore representation. */ 184 static inline xfs_rtword_t 185 xfs_rtbitmap_getword( 186 struct xfs_rtalloc_args *args, 187 unsigned int index) 188 { 189 union xfs_rtword_raw *word = xfs_rbmblock_wordptr(args, index); 190 191 return word->old; 192 } 193 194 /* Set an ondisk bitmap word from an incore representation. */ 195 static inline void 196 xfs_rtbitmap_setword( 197 struct xfs_rtalloc_args *args, 198 unsigned int index, 199 xfs_rtword_t value) 200 { 201 union xfs_rtword_raw *word = xfs_rbmblock_wordptr(args, index); 202 203 word->old = value; 204 } 205 206 /* 207 * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t 208 * offset within the rt summary file. 209 */ 210 static inline xfs_rtsumoff_t 211 xfs_rtsumoffs( 212 struct xfs_mount *mp, 213 int log2_len, 214 xfs_fileoff_t rbmoff) 215 { 216 return log2_len * mp->m_sb.sb_rbmblocks + rbmoff; 217 } 218 219 /* 220 * Convert an xfs_suminfo_t offset to a file block offset within the rt summary 221 * file. 222 */ 223 static inline xfs_fileoff_t 224 xfs_rtsumoffs_to_block( 225 struct xfs_mount *mp, 226 xfs_rtsumoff_t rsumoff) 227 { 228 return XFS_B_TO_FSBT(mp, rsumoff * sizeof(xfs_suminfo_t)); 229 } 230 231 /* 232 * Convert an xfs_suminfo_t offset to an info word offset within an rt summary 233 * block. 234 */ 235 static inline unsigned int 236 xfs_rtsumoffs_to_infoword( 237 struct xfs_mount *mp, 238 xfs_rtsumoff_t rsumoff) 239 { 240 unsigned int mask = mp->m_blockmask >> XFS_SUMINFOLOG; 241 242 return rsumoff & mask; 243 } 244 245 /* Return a pointer to a summary info word within a rt summary block. */ 246 static inline union xfs_suminfo_raw * 247 xfs_rsumblock_infoptr( 248 struct xfs_rtalloc_args *args, 249 unsigned int index) 250 { 251 union xfs_suminfo_raw *info = args->sumbp->b_addr; 252 253 return info + index; 254 } 255 256 /* Get the current value of a summary counter. */ 257 static inline xfs_suminfo_t 258 xfs_suminfo_get( 259 struct xfs_rtalloc_args *args, 260 unsigned int index) 261 { 262 union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(args, index); 263 264 return info->old; 265 } 266 267 /* Add to the current value of a summary counter and return the new value. */ 268 static inline xfs_suminfo_t 269 xfs_suminfo_add( 270 struct xfs_rtalloc_args *args, 271 unsigned int index, 272 int delta) 273 { 274 union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(args, index); 275 276 info->old += delta; 277 return info->old; 278 } 279 280 /* 281 * Functions for walking free space rtextents in the realtime bitmap. 282 */ 283 struct xfs_rtalloc_rec { 284 xfs_rtxnum_t ar_startext; 285 xfs_rtbxlen_t ar_extcount; 286 }; 287 288 typedef int (*xfs_rtalloc_query_range_fn)( 289 struct xfs_mount *mp, 290 struct xfs_trans *tp, 291 const struct xfs_rtalloc_rec *rec, 292 void *priv); 293 294 #ifdef CONFIG_XFS_RT 295 void xfs_rtbuf_cache_relse(struct xfs_rtalloc_args *args); 296 297 int xfs_rtbuf_get(struct xfs_rtalloc_args *args, xfs_fileoff_t block, 298 int issum); 299 300 static inline int 301 xfs_rtbitmap_read_buf( 302 struct xfs_rtalloc_args *args, 303 xfs_fileoff_t block) 304 { 305 return xfs_rtbuf_get(args, block, 0); 306 } 307 308 static inline int 309 xfs_rtsummary_read_buf( 310 struct xfs_rtalloc_args *args, 311 xfs_fileoff_t block) 312 { 313 return xfs_rtbuf_get(args, block, 1); 314 } 315 316 int xfs_rtcheck_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 317 xfs_rtxlen_t len, int val, xfs_rtxnum_t *new, int *stat); 318 int xfs_rtfind_back(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 319 xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock); 320 int xfs_rtfind_forw(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 321 xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock); 322 int xfs_rtmodify_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 323 xfs_rtxlen_t len, int val); 324 int xfs_rtget_summary(struct xfs_rtalloc_args *args, int log, 325 xfs_fileoff_t bbno, xfs_suminfo_t *sum); 326 int xfs_rtmodify_summary(struct xfs_rtalloc_args *args, int log, 327 xfs_fileoff_t bbno, int delta); 328 int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 329 xfs_rtxlen_t len); 330 int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, 331 const struct xfs_rtalloc_rec *low_rec, 332 const struct xfs_rtalloc_rec *high_rec, 333 xfs_rtalloc_query_range_fn fn, void *priv); 334 int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp, 335 xfs_rtalloc_query_range_fn fn, 336 void *priv); 337 int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp, 338 xfs_rtxnum_t start, xfs_rtxlen_t len, 339 bool *is_free); 340 /* 341 * Free an extent in the realtime subvolume. Length is expressed in 342 * realtime extents, as is the block number. 343 */ 344 int /* error */ 345 xfs_rtfree_extent( 346 struct xfs_trans *tp, /* transaction pointer */ 347 xfs_rtxnum_t start, /* starting rtext number to free */ 348 xfs_rtxlen_t len); /* length of extent freed */ 349 350 /* Same as above, but in units of rt blocks. */ 351 int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, 352 xfs_filblks_t rtlen); 353 354 uint8_t xfs_compute_rextslog(xfs_rtbxlen_t rtextents); 355 356 /* Do we support an rt volume having this number of rtextents? */ 357 static inline bool 358 xfs_validate_rtextents( 359 xfs_rtbxlen_t rtextents) 360 { 361 /* No runt rt volumes */ 362 if (rtextents == 0) 363 return false; 364 365 return true; 366 } 367 368 xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t 369 rtextents); 370 unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp, 371 xfs_rtbxlen_t rtextents); 372 373 xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp, 374 unsigned int rsumlevels, xfs_extlen_t rbmblocks); 375 unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp, 376 unsigned int rsumlevels, xfs_extlen_t rbmblocks); 377 #else /* CONFIG_XFS_RT */ 378 # define xfs_rtfree_extent(t,b,l) (-ENOSYS) 379 # define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) 380 # define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS) 381 # define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) 382 # define xfs_rtbitmap_read_buf(a,b) (-ENOSYS) 383 # define xfs_rtsummary_read_buf(a,b) (-ENOSYS) 384 # define xfs_rtbuf_cache_relse(a) (0) 385 # define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) 386 # define xfs_compute_rextslog(rtx) (0) 387 # define xfs_validate_rtextents(rtx) (false) 388 static inline xfs_filblks_t 389 xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) 390 { 391 /* shut up gcc */ 392 return 0; 393 } 394 # define xfs_rtbitmap_wordcount(mp, r) (0) 395 # define xfs_rtsummary_blockcount(mp, l, b) (0) 396 # define xfs_rtsummary_wordcount(mp, l, b) (0) 397 #endif /* CONFIG_XFS_RT */ 398 399 #endif /* __XFS_RTBITMAP_H__ */ 400