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
xfs_rtx_to_rtb(struct xfs_mount * mp,xfs_rtxnum_t rtx)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
xfs_rtxlen_to_extlen(struct xfs_mount * mp,xfs_rtxlen_t rtxlen)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
xfs_extlen_to_rtxmod(struct xfs_mount * mp,xfs_extlen_t len)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
xfs_extlen_to_rtxlen(struct xfs_mount * mp,xfs_extlen_t len)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
xfs_rtb_to_rtx(struct xfs_mount * mp,xfs_rtblock_t rtbno)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
xfs_rtb_to_rtxoff(struct xfs_mount * mp,xfs_rtblock_t rtbno)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
xfs_rtb_to_rtxrem(struct xfs_mount * mp,xfs_rtblock_t rtbno,xfs_extlen_t * off)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
xfs_rtb_to_rtxup(struct xfs_mount * mp,xfs_rtblock_t rtbno)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
xfs_rtb_roundup_rtx(struct xfs_mount * mp,xfs_rtblock_t rtbno)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
xfs_rtb_rounddown_rtx(struct xfs_mount * mp,xfs_rtblock_t rtbno)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
xfs_rtx_to_rbmblock(struct xfs_mount * mp,xfs_rtxnum_t rtx)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
xfs_rtx_to_rbmword(struct xfs_mount * mp,xfs_rtxnum_t rtx)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
xfs_rbmblock_to_rtx(struct xfs_mount * mp,xfs_fileoff_t rbmoff)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 *
xfs_rbmblock_wordptr(struct xfs_rtalloc_args * args,unsigned int index)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
xfs_rtbitmap_getword(struct xfs_rtalloc_args * args,unsigned int index)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
xfs_rtbitmap_setword(struct xfs_rtalloc_args * args,unsigned int index,xfs_rtword_t value)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
xfs_rtsumoffs(struct xfs_mount * mp,int log2_len,xfs_fileoff_t rbmoff)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
xfs_rtsumoffs_to_block(struct xfs_mount * mp,xfs_rtsumoff_t rsumoff)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
xfs_rtsumoffs_to_infoword(struct xfs_mount * mp,xfs_rtsumoff_t rsumoff)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 *
xfs_rsumblock_infoptr(struct xfs_rtalloc_args * args,unsigned int index)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
xfs_suminfo_get(struct xfs_rtalloc_args * args,unsigned int index)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
xfs_suminfo_add(struct xfs_rtalloc_args * args,unsigned int index,int delta)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
xfs_rtbitmap_read_buf(struct xfs_rtalloc_args * args,xfs_fileoff_t block)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
xfs_rtsummary_read_buf(struct xfs_rtalloc_args * args,xfs_fileoff_t block)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 xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t
355 rtextents);
356 unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp,
357 xfs_rtbxlen_t rtextents);
358
359 xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
360 unsigned int rsumlevels, xfs_extlen_t rbmblocks);
361 unsigned 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)
372 static inline xfs_filblks_t
xfs_rtbitmap_blockcount(struct xfs_mount * mp,xfs_rtbxlen_t rtextents)373 xfs_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