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 9struct 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 20static inline xfs_rtblock_t 21xfs_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 31static inline xfs_extlen_t 32xfs_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 .*/ 43static inline unsigned int 44xfs_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 54static inline xfs_rtxlen_t 55xfs_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. */ 66static inline xfs_rtxnum_t 67xfs_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. */ 78static inline xfs_extlen_t 79xfs_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 */ 93static inline xfs_rtxnum_t 94xfs_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 */ 111static inline xfs_rtxnum_t 112xfs_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. */ 128static inline xfs_rtblock_t 129xfs_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. */ 137static inline xfs_rtblock_t 138xfs_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. */ 146static inline xfs_fileoff_t 147xfs_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. */ 155static inline unsigned int 156xfs_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. */ 164static inline xfs_rtxnum_t 165xfs_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. */ 173static inline union xfs_rtword_raw * 174xfs_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. */ 184static inline xfs_rtword_t 185xfs_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. */ 195static inline void 196xfs_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 */ 210static inline xfs_rtsumoff_t 211xfs_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 */ 223static inline xfs_fileoff_t 224xfs_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 */ 235static inline unsigned int 236xfs_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. */ 246static inline union xfs_suminfo_raw * 247xfs_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. */ 257static inline xfs_suminfo_t 258xfs_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. */ 268static inline xfs_suminfo_t 269xfs_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 */ 283struct xfs_rtalloc_rec { 284 xfs_rtxnum_t ar_startext; 285 xfs_rtbxlen_t ar_extcount; 286}; 287 288typedef 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 295void xfs_rtbuf_cache_relse(struct xfs_rtalloc_args *args); 296 297int xfs_rtbuf_get(struct xfs_rtalloc_args *args, xfs_fileoff_t block, 298 int issum); 299 300static inline int 301xfs_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 308static inline int 309xfs_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 316int 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); 318int xfs_rtfind_back(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 319 xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock); 320int xfs_rtfind_forw(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 321 xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock); 322int xfs_rtmodify_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 323 xfs_rtxlen_t len, int val); 324int xfs_rtget_summary(struct xfs_rtalloc_args *args, int log, 325 xfs_fileoff_t bbno, xfs_suminfo_t *sum); 326int xfs_rtmodify_summary(struct xfs_rtalloc_args *args, int log, 327 xfs_fileoff_t bbno, int delta); 328int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 329 xfs_rtxlen_t len); 330int 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); 334int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp, 335 xfs_rtalloc_query_range_fn fn, 336 void *priv); 337int 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 */ 344int /* error */ 345xfs_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. */ 351int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, 352 xfs_filblks_t rtlen); 353 354xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t 355 rtextents); 356unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp, 357 xfs_rtbxlen_t rtextents); 358 359xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp, 360 unsigned int rsumlevels, xfs_extlen_t rbmblocks); 361unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp, 362 unsigned int rsumlevels, xfs_extlen_t rbmblocks); 363#else /* CONFIG_XFS_RT */ 364# define xfs_rtfree_extent(t,b,l) (-ENOSYS) 365# define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) 366# define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS) 367# define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) 368# define xfs_rtbitmap_read_buf(a,b) (-ENOSYS) 369# define xfs_rtsummary_read_buf(a,b) (-ENOSYS) 370# define xfs_rtbuf_cache_relse(a) (0) 371# define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) 372static inline xfs_filblks_t 373xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) 374{ 375 /* shut up gcc */ 376 return 0; 377} 378# define xfs_rtbitmap_wordcount(mp, r) (0) 379# define xfs_rtsummary_blockcount(mp, l, b) (0) 380# define xfs_rtsummary_wordcount(mp, l, b) (0) 381#endif /* CONFIG_XFS_RT */ 382 383#endif /* __XFS_RTBITMAP_H__ */ 384