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