1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
6 #ifndef __XFS_RTBITMAP_H__
7 #define __XFS_RTBITMAP_H__
9 #include "xfs_rtgroup.h"
11 struct xfs_rtalloc_args
{
12 struct xfs_rtgroup
*rtg
;
16 struct xfs_buf
*rbmbp
; /* bitmap block buffer */
17 struct xfs_buf
*sumbp
; /* summary block buffer */
19 xfs_fileoff_t rbmoff
; /* bitmap block number */
20 xfs_fileoff_t sumoff
; /* summary block number */
23 static inline xfs_rtblock_t
25 struct xfs_rtgroup
*rtg
,
28 struct xfs_mount
*mp
= rtg_mount(rtg
);
29 xfs_rtblock_t start
= xfs_group_start_fsb(rtg_group(rtg
));
31 if (mp
->m_rtxblklog
>= 0)
32 return start
+ (rtx
<< mp
->m_rtxblklog
);
33 return start
+ (rtx
* mp
->m_sb
.sb_rextsize
);
36 /* Convert an rgbno into an rt extent number. */
37 static inline xfs_rtxnum_t
42 if (likely(mp
->m_rtxblklog
>= 0))
43 return rgbno
>> mp
->m_rtxblklog
;
44 return rgbno
/ mp
->m_sb
.sb_rextsize
;
47 static inline uint64_t
50 xfs_rtbxlen_t rtbxlen
)
52 if (mp
->m_rtxblklog
>= 0)
53 return rtbxlen
<< mp
->m_rtxblklog
;
55 return rtbxlen
* mp
->m_sb
.sb_rextsize
;
58 static inline xfs_extlen_t
63 if (mp
->m_rtxblklog
>= 0)
64 return rtxlen
<< mp
->m_rtxblklog
;
66 return rtxlen
* mp
->m_sb
.sb_rextsize
;
69 /* Compute the misalignment between an extent length and a realtime extent .*/
70 static inline unsigned int
75 if (mp
->m_rtxblklog
>= 0)
76 return len
& mp
->m_rtxblkmask
;
78 return len
% mp
->m_sb
.sb_rextsize
;
81 static inline xfs_rtxlen_t
86 if (mp
->m_rtxblklog
>= 0)
87 return len
>> mp
->m_rtxblklog
;
89 return len
/ mp
->m_sb
.sb_rextsize
;
92 /* Convert an rt block count into an rt extent count. */
93 static inline xfs_rtbxlen_t
98 if (likely(mp
->m_rtxblklog
>= 0))
99 return blen
>> mp
->m_rtxblklog
;
101 return div_u64(blen
, mp
->m_sb
.sb_rextsize
);
104 /* Return the offset of a file block length within an rt extent. */
105 static inline xfs_extlen_t
107 struct xfs_mount
*mp
,
110 if (likely(mp
->m_rtxblklog
>= 0))
111 return blen
& mp
->m_rtxblkmask
;
113 return do_div(blen
, mp
->m_sb
.sb_rextsize
);
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
,
122 return roundup_64(blen
, mp
->m_sb
.sb_rextsize
);
125 /* Convert an rt block number into an rt extent number. */
126 static inline xfs_rtxnum_t
128 struct xfs_mount
*mp
,
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
);
138 /* Return the offset of an rt block number within an rt extent. */
139 static inline xfs_extlen_t
141 struct xfs_mount
*mp
,
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
);
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
,
157 return roundup_64(off
, mp
->m_sb
.sb_rextsize
);
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
,
166 return rounddown_64(off
, mp
->m_sb
.sb_rextsize
);
169 /* Convert an rt extent number to a file block offset in the rt bitmap file. */
170 static inline xfs_fileoff_t
172 struct xfs_mount
*mp
,
175 if (xfs_has_rtgroups(mp
))
176 return div_u64(rtx
, mp
->m_rtx_per_rbmblock
);
178 return rtx
>> mp
->m_blkbit_log
;
181 /* Convert an rt extent number to a word offset within an rt bitmap block. */
182 static inline unsigned int
184 struct xfs_mount
*mp
,
187 if (xfs_has_rtgroups(mp
)) {
190 div_u64_rem(rtx
>> XFS_NBWORDLOG
, mp
->m_blockwsize
, &mod
);
194 return (rtx
>> XFS_NBWORDLOG
) & (mp
->m_blockwsize
- 1);
197 /* Convert a file block offset in the rt bitmap file to an rt extent number. */
198 static inline xfs_rtxnum_t
200 struct xfs_mount
*mp
,
201 xfs_fileoff_t rbmoff
)
203 if (xfs_has_rtgroups(mp
))
204 return rbmoff
* mp
->m_rtx_per_rbmblock
;
206 return rbmoff
<< mp
->m_blkbit_log
;
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
,
215 struct xfs_mount
*mp
= args
->mp
;
216 union xfs_rtword_raw
*words
;
217 struct xfs_rtbuf_blkinfo
*hdr
= args
->rbmbp
->b_addr
;
219 if (xfs_has_rtgroups(mp
))
220 words
= (union xfs_rtword_raw
*)(hdr
+ 1);
222 words
= args
->rbmbp
->b_addr
;
224 return words
+ index
;
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
,
233 union xfs_rtword_raw
*word
= xfs_rbmblock_wordptr(args
, index
);
235 if (xfs_has_rtgroups(args
->mp
))
236 return be32_to_cpu(word
->rtg
);
240 /* Set an ondisk bitmap word from an incore representation. */
242 xfs_rtbitmap_setword(
243 struct xfs_rtalloc_args
*args
,
247 union xfs_rtword_raw
*word
= xfs_rbmblock_wordptr(args
, index
);
249 if (xfs_has_rtgroups(args
->mp
))
250 word
->rtg
= cpu_to_be32(value
);
256 * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t
257 * offset within the rt summary file.
259 static inline xfs_rtsumoff_t
261 struct xfs_mount
*mp
,
263 xfs_fileoff_t rbmoff
)
265 return log2_len
* mp
->m_sb
.sb_rbmblocks
+ rbmoff
;
269 * Convert an xfs_suminfo_t offset to a file block offset within the rt summary
272 static inline xfs_fileoff_t
273 xfs_rtsumoffs_to_block(
274 struct xfs_mount
*mp
,
275 xfs_rtsumoff_t rsumoff
)
277 if (xfs_has_rtgroups(mp
))
278 return rsumoff
/ mp
->m_blockwsize
;
280 return XFS_B_TO_FSBT(mp
, rsumoff
* sizeof(xfs_suminfo_t
));
284 * Convert an xfs_suminfo_t offset to an info word offset within an rt summary
287 static inline unsigned int
288 xfs_rtsumoffs_to_infoword(
289 struct xfs_mount
*mp
,
290 xfs_rtsumoff_t rsumoff
)
292 unsigned int mask
= mp
->m_blockmask
>> XFS_SUMINFOLOG
;
294 if (xfs_has_rtgroups(mp
))
295 return rsumoff
% mp
->m_blockwsize
;
297 return rsumoff
& mask
;
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
,
306 union xfs_suminfo_raw
*info
;
307 struct xfs_rtbuf_blkinfo
*hdr
= args
->sumbp
->b_addr
;
309 if (xfs_has_rtgroups(args
->mp
))
310 info
= (union xfs_suminfo_raw
*)(hdr
+ 1);
312 info
= args
->sumbp
->b_addr
;
317 /* Get the current value of a summary counter. */
318 static inline xfs_suminfo_t
320 struct xfs_rtalloc_args
*args
,
323 union xfs_suminfo_raw
*info
= xfs_rsumblock_infoptr(args
, index
);
325 if (xfs_has_rtgroups(args
->mp
))
326 return be32_to_cpu(info
->rtg
);
330 /* Add to the current value of a summary counter and return the new value. */
331 static inline xfs_suminfo_t
333 struct xfs_rtalloc_args
*args
,
337 union xfs_suminfo_raw
*info
= xfs_rsumblock_infoptr(args
, index
);
339 if (xfs_has_rtgroups(args
->mp
)) {
340 be32_add_cpu(&info
->rtg
, delta
);
341 return be32_to_cpu(info
->rtg
);
348 static inline const struct xfs_buf_ops
*
350 struct xfs_mount
*mp
,
351 enum xfs_rtg_inodes type
)
353 if (xfs_has_rtgroups(mp
)) {
354 if (type
== XFS_RTGI_SUMMARY
)
355 return &xfs_rtsummary_buf_ops
;
356 return &xfs_rtbitmap_buf_ops
;
358 return &xfs_rtbuf_ops
;
362 * Functions for walking free space rtextents in the realtime bitmap.
364 struct xfs_rtalloc_rec
{
365 xfs_rtxnum_t ar_startext
;
366 xfs_rtbxlen_t ar_extcount
;
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
,
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
,
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
);
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
);
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
);
421 #else /* CONFIG_XFS_RT */
422 # define xfs_rtfree_extent(t,b,l) (-ENOSYS)
424 static inline int xfs_rtfree_blocks(struct xfs_trans
*tp
,
425 struct xfs_rtgroup
*rtg
, xfs_fsblock_t rtbno
,
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
)
442 #endif /* CONFIG_XFS_RT */
444 #endif /* __XFS_RTBITMAP_H__ */