xref: /linux/fs/xfs/libxfs/xfs_rtbitmap.h (revision 46db7dec8bae04b2721c9d3e9e4fc75c14654754)
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 #include "xfs_rtgroup.h"
10 
11 struct xfs_rtalloc_args {
12 	struct xfs_rtgroup	*rtg;
13 	struct xfs_mount	*mp;
14 	struct xfs_trans	*tp;
15 
16 	struct xfs_buf		*rbmbp;	/* bitmap block buffer */
17 	struct xfs_buf		*sumbp;	/* summary block buffer */
18 
19 	xfs_fileoff_t		rbmoff;	/* bitmap block number */
20 	xfs_fileoff_t		sumoff;	/* summary block number */
21 };
22 
23 /* Return the payload of the buffer after the optional header. */
24 static inline void *
25 xfs_rtblock_payload(
26 	struct xfs_buf		*bp)
27 {
28 	if (!xfs_has_rtgroups(bp->b_mount))
29 		return bp->b_addr;
30 	return bp->b_addr + sizeof(struct xfs_rtbuf_blkinfo);
31 }
32 
33 static inline xfs_rtblock_t
34 xfs_rtx_to_rtb(
35 	struct xfs_rtgroup	*rtg,
36 	xfs_rtxnum_t		rtx)
37 {
38 	struct xfs_mount	*mp = rtg_mount(rtg);
39 	xfs_rtblock_t		start = xfs_group_start_fsb(rtg_group(rtg));
40 
41 	if (mp->m_rtxblklog >= 0)
42 		return start + (rtx << mp->m_rtxblklog);
43 	return start + (rtx * mp->m_sb.sb_rextsize);
44 }
45 
46 /* Convert an rgbno into an rt extent number. */
47 static inline xfs_rtxnum_t
48 xfs_rgbno_to_rtx(
49 	struct xfs_mount	*mp,
50 	xfs_rgblock_t		rgbno)
51 {
52 	if (likely(mp->m_rtxblklog >= 0))
53 		return rgbno >> mp->m_rtxblklog;
54 	return rgbno / mp->m_sb.sb_rextsize;
55 }
56 
57 static inline uint64_t
58 xfs_rtbxlen_to_blen(
59 	struct xfs_mount	*mp,
60 	xfs_rtbxlen_t		rtbxlen)
61 {
62 	if (mp->m_rtxblklog >= 0)
63 		return rtbxlen << mp->m_rtxblklog;
64 
65 	return rtbxlen * mp->m_sb.sb_rextsize;
66 }
67 
68 static inline xfs_extlen_t
69 xfs_rtxlen_to_extlen(
70 	struct xfs_mount	*mp,
71 	xfs_rtxlen_t		rtxlen)
72 {
73 	if (mp->m_rtxblklog >= 0)
74 		return rtxlen << mp->m_rtxblklog;
75 
76 	return rtxlen * mp->m_sb.sb_rextsize;
77 }
78 
79 /* Compute the misalignment between an extent length and a realtime extent .*/
80 static inline unsigned int
81 xfs_extlen_to_rtxmod(
82 	struct xfs_mount	*mp,
83 	xfs_extlen_t		len)
84 {
85 	if (mp->m_rtxblklog >= 0)
86 		return len & mp->m_rtxblkmask;
87 
88 	return len % mp->m_sb.sb_rextsize;
89 }
90 
91 static inline xfs_rtxlen_t
92 xfs_extlen_to_rtxlen(
93 	struct xfs_mount	*mp,
94 	xfs_extlen_t		len)
95 {
96 	if (mp->m_rtxblklog >= 0)
97 		return len >> mp->m_rtxblklog;
98 
99 	return len / mp->m_sb.sb_rextsize;
100 }
101 
102 /* Convert an rt block count into an rt extent count. */
103 static inline xfs_rtbxlen_t
104 xfs_blen_to_rtbxlen(
105 	struct xfs_mount	*mp,
106 	uint64_t		blen)
107 {
108 	if (likely(mp->m_rtxblklog >= 0))
109 		return blen >> mp->m_rtxblklog;
110 
111 	return div_u64(blen, mp->m_sb.sb_rextsize);
112 }
113 
114 /* Return the offset of a file block length within an rt extent. */
115 static inline xfs_extlen_t
116 xfs_blen_to_rtxoff(
117 	struct xfs_mount	*mp,
118 	xfs_filblks_t		blen)
119 {
120 	if (likely(mp->m_rtxblklog >= 0))
121 		return blen & mp->m_rtxblkmask;
122 
123 	return do_div(blen, mp->m_sb.sb_rextsize);
124 }
125 
126 /* Round this block count up to the nearest rt extent size. */
127 static inline xfs_filblks_t
128 xfs_blen_roundup_rtx(
129 	struct xfs_mount	*mp,
130 	xfs_filblks_t		blen)
131 {
132 	return roundup_64(blen, mp->m_sb.sb_rextsize);
133 }
134 
135 /* Convert an rt block number into an rt extent number. */
136 static inline xfs_rtxnum_t
137 xfs_rtb_to_rtx(
138 	struct xfs_mount	*mp,
139 	xfs_rtblock_t		rtbno)
140 {
141 	/* open-coded 64-bit masking operation */
142 	rtbno &= mp->m_groups[XG_TYPE_RTG].blkmask;
143 	if (likely(mp->m_rtxblklog >= 0))
144 		return rtbno >> mp->m_rtxblklog;
145 	return div_u64(rtbno, mp->m_sb.sb_rextsize);
146 }
147 
148 /* Return the offset of a rtgroup block number within an rt extent. */
149 static inline xfs_extlen_t
150 xfs_rgbno_to_rtxoff(
151 	struct xfs_mount	*mp,
152 	xfs_rgblock_t		rgbno)
153 {
154 	return rgbno % mp->m_sb.sb_rextsize;
155 }
156 
157 /* Return the offset of an rt block number within an rt extent. */
158 static inline xfs_extlen_t
159 xfs_rtb_to_rtxoff(
160 	struct xfs_mount	*mp,
161 	xfs_rtblock_t		rtbno)
162 {
163 	/* open-coded 64-bit masking operation */
164 	rtbno &= mp->m_groups[XG_TYPE_RTG].blkmask;
165 	if (likely(mp->m_rtxblklog >= 0))
166 		return rtbno & mp->m_rtxblkmask;
167 	return do_div(rtbno, mp->m_sb.sb_rextsize);
168 }
169 
170 /* Round this file block offset up to the nearest rt extent size. */
171 static inline xfs_rtblock_t
172 xfs_fileoff_roundup_rtx(
173 	struct xfs_mount	*mp,
174 	xfs_fileoff_t		off)
175 {
176 	return roundup_64(off, mp->m_sb.sb_rextsize);
177 }
178 
179 /* Round this file block offset down to the nearest rt extent size. */
180 static inline xfs_rtblock_t
181 xfs_fileoff_rounddown_rtx(
182 	struct xfs_mount	*mp,
183 	xfs_fileoff_t		off)
184 {
185 	return rounddown_64(off, mp->m_sb.sb_rextsize);
186 }
187 
188 /* Convert an rt extent number to a file block offset in the rt bitmap file. */
189 static inline xfs_fileoff_t
190 xfs_rtx_to_rbmblock(
191 	struct xfs_mount	*mp,
192 	xfs_rtxnum_t		rtx)
193 {
194 	if (xfs_has_rtgroups(mp))
195 		return div_u64(rtx, mp->m_rtx_per_rbmblock);
196 
197 	return rtx >> mp->m_blkbit_log;
198 }
199 
200 /* Convert an rt extent number to a word offset within an rt bitmap block. */
201 static inline unsigned int
202 xfs_rtx_to_rbmword(
203 	struct xfs_mount	*mp,
204 	xfs_rtxnum_t		rtx)
205 {
206 	if (xfs_has_rtgroups(mp)) {
207 		unsigned int	mod;
208 
209 		div_u64_rem(rtx >> XFS_NBWORDLOG, mp->m_blockwsize, &mod);
210 		return mod;
211 	}
212 
213 	return (rtx >> XFS_NBWORDLOG) & (mp->m_blockwsize - 1);
214 }
215 
216 /* Convert a file block offset in the rt bitmap file to an rt extent number. */
217 static inline xfs_rtxnum_t
218 xfs_rbmblock_to_rtx(
219 	struct xfs_mount	*mp,
220 	xfs_fileoff_t		rbmoff)
221 {
222 	if (xfs_has_rtgroups(mp))
223 		return rbmoff * mp->m_rtx_per_rbmblock;
224 
225 	return rbmoff << mp->m_blkbit_log;
226 }
227 
228 /* Return a pointer to a bitmap word within a rt bitmap block. */
229 static inline union xfs_rtword_raw *
230 xfs_rbmblock_wordptr(
231 	struct xfs_rtalloc_args	*args,
232 	unsigned int		index)
233 {
234 	union xfs_rtword_raw	*words = xfs_rtblock_payload(args->rbmbp);
235 
236 	return words + index;
237 }
238 
239 /* Convert an ondisk bitmap word to its incore representation. */
240 static inline xfs_rtword_t
241 xfs_rtbitmap_getword(
242 	struct xfs_rtalloc_args	*args,
243 	unsigned int		index)
244 {
245 	union xfs_rtword_raw	*word = xfs_rbmblock_wordptr(args, index);
246 
247 	if (xfs_has_rtgroups(args->mp))
248 		return be32_to_cpu(word->rtg);
249 	return word->old;
250 }
251 
252 /* Set an ondisk bitmap word from an incore representation. */
253 static inline void
254 xfs_rtbitmap_setword(
255 	struct xfs_rtalloc_args	*args,
256 	unsigned int		index,
257 	xfs_rtword_t		value)
258 {
259 	union xfs_rtword_raw	*word = xfs_rbmblock_wordptr(args, index);
260 
261 	if (xfs_has_rtgroups(args->mp))
262 		word->rtg = cpu_to_be32(value);
263 	else
264 		word->old = value;
265 }
266 
267 /*
268  * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t
269  * offset within the rt summary file.
270  */
271 static inline xfs_rtsumoff_t
272 xfs_rtsumoffs(
273 	struct xfs_mount	*mp,
274 	int			log2_len,
275 	xfs_fileoff_t		rbmoff)
276 {
277 	return log2_len * mp->m_sb.sb_rbmblocks + rbmoff;
278 }
279 
280 /*
281  * Convert an xfs_suminfo_t offset to a file block offset within the rt summary
282  * file.
283  */
284 static inline xfs_fileoff_t
285 xfs_rtsumoffs_to_block(
286 	struct xfs_mount	*mp,
287 	xfs_rtsumoff_t		rsumoff)
288 {
289 	if (xfs_has_rtgroups(mp))
290 		return rsumoff / mp->m_blockwsize;
291 
292 	return XFS_B_TO_FSBT(mp, rsumoff * sizeof(xfs_suminfo_t));
293 }
294 
295 /*
296  * Convert an xfs_suminfo_t offset to an info word offset within an rt summary
297  * block.
298  */
299 static inline unsigned int
300 xfs_rtsumoffs_to_infoword(
301 	struct xfs_mount	*mp,
302 	xfs_rtsumoff_t		rsumoff)
303 {
304 	unsigned int		mask = mp->m_blockmask >> XFS_SUMINFOLOG;
305 
306 	if (xfs_has_rtgroups(mp))
307 		return rsumoff % mp->m_blockwsize;
308 
309 	return rsumoff & mask;
310 }
311 
312 /* Return a pointer to a summary info word within a rt summary block. */
313 static inline union xfs_suminfo_raw *
314 xfs_rsumblock_infoptr(
315 	struct xfs_rtalloc_args	*args,
316 	unsigned int		index)
317 {
318 	union xfs_suminfo_raw	*info = xfs_rtblock_payload(args->sumbp);
319 
320 	return info + index;
321 }
322 
323 /* Get the current value of a summary counter. */
324 static inline xfs_suminfo_t
325 xfs_suminfo_get(
326 	struct xfs_rtalloc_args	*args,
327 	unsigned int		index)
328 {
329 	union xfs_suminfo_raw	*info = xfs_rsumblock_infoptr(args, index);
330 
331 	if (xfs_has_rtgroups(args->mp))
332 		return be32_to_cpu(info->rtg);
333 	return info->old;
334 }
335 
336 /* Add to the current value of a summary counter and return the new value. */
337 static inline xfs_suminfo_t
338 xfs_suminfo_add(
339 	struct xfs_rtalloc_args	*args,
340 	unsigned int		index,
341 	int			delta)
342 {
343 	union xfs_suminfo_raw	*info = xfs_rsumblock_infoptr(args, index);
344 
345 	if (xfs_has_rtgroups(args->mp)) {
346 		be32_add_cpu(&info->rtg, delta);
347 		return be32_to_cpu(info->rtg);
348 	}
349 
350 	info->old += delta;
351 	return info->old;
352 }
353 
354 /*
355  * Functions for walking free space rtextents in the realtime bitmap.
356  */
357 struct xfs_rtalloc_rec {
358 	xfs_rtxnum_t		ar_startext;
359 	xfs_rtbxlen_t		ar_extcount;
360 };
361 
362 typedef int (*xfs_rtalloc_query_range_fn)(
363 	struct xfs_rtgroup		*rtg,
364 	struct xfs_trans		*tp,
365 	const struct xfs_rtalloc_rec	*rec,
366 	void				*priv);
367 
368 #ifdef CONFIG_XFS_RT
369 void xfs_rtbuf_cache_relse(struct xfs_rtalloc_args *args);
370 int xfs_rtbitmap_read_buf(struct xfs_rtalloc_args *args, xfs_fileoff_t block);
371 int xfs_rtsummary_read_buf(struct xfs_rtalloc_args *args, xfs_fileoff_t block);
372 int xfs_rtcheck_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
373 		xfs_rtxlen_t len, int val, xfs_rtxnum_t *new, int *stat);
374 int xfs_rtfind_back(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
375 		xfs_rtxnum_t *rtblock);
376 int xfs_rtfind_forw(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
377 		xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock);
378 int xfs_rtmodify_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
379 		xfs_rtxlen_t len, int val);
380 int xfs_rtget_summary(struct xfs_rtalloc_args *args, int log,
381 		xfs_fileoff_t bbno, xfs_suminfo_t *sum);
382 int xfs_rtmodify_summary(struct xfs_rtalloc_args *args, int log,
383 		xfs_fileoff_t bbno, int delta);
384 int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
385 		xfs_rtxlen_t len);
386 int xfs_rtalloc_query_range(struct xfs_rtgroup *rtg, struct xfs_trans *tp,
387 		xfs_rtxnum_t start, xfs_rtxnum_t end,
388 		xfs_rtalloc_query_range_fn fn, void *priv);
389 int xfs_rtalloc_query_all(struct xfs_rtgroup *rtg, struct xfs_trans *tp,
390 		xfs_rtalloc_query_range_fn fn, void *priv);
391 int xfs_rtalloc_extent_is_free(struct xfs_rtgroup *rtg, struct xfs_trans *tp,
392 		xfs_rtxnum_t start, xfs_rtxlen_t len, bool *is_free);
393 int xfs_rtfree_extent(struct xfs_trans *tp, struct xfs_rtgroup *rtg,
394 		xfs_rtxnum_t start, xfs_rtxlen_t len);
395 /* Same as above, but in units of rt blocks. */
396 int xfs_rtfree_blocks(struct xfs_trans *tp, struct xfs_rtgroup *rtg,
397 		xfs_fsblock_t rtbno, xfs_filblks_t rtlen);
398 
399 xfs_rtxnum_t xfs_rtbitmap_rtx_per_rbmblock(struct xfs_mount *mp);
400 xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp);
401 xfs_filblks_t xfs_rtbitmap_blockcount_len(struct xfs_mount *mp,
402 		xfs_rtbxlen_t rtextents);
403 xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
404 		unsigned int *rsumlevels);
405 
406 const struct xfs_buf_ops *xfs_rtblock_ops(struct xfs_mount *mp,
407 		enum xfs_rtg_inodes type);
408 void xfs_rtfile_initialize_buf(struct xfs_rtgroup *rtg,
409 		enum xfs_rtg_inodes type, struct xfs_buf *bp,
410 		struct xfs_trans *tp);
411 int xfs_rtfile_initialize_blocks(struct xfs_rtgroup *rtg,
412 		enum xfs_rtg_inodes type, xfs_fileoff_t offset_fsb,
413 		xfs_fileoff_t end_fsb, void *data);
414 int xfs_rtbitmap_create(struct xfs_rtgroup *rtg, struct xfs_inode *ip,
415 		struct xfs_trans *tp, bool init);
416 int xfs_rtsummary_create(struct xfs_rtgroup *rtg, struct xfs_inode *ip,
417 		struct xfs_trans *tp, bool init);
418 
419 #else /* CONFIG_XFS_RT */
420 # define xfs_rtfree_extent(t,b,l)			(-ENOSYS)
421 
422 static inline int xfs_rtfree_blocks(struct xfs_trans *tp,
423 		struct xfs_rtgroup *rtg, xfs_fsblock_t rtbno,
424 		xfs_filblks_t rtlen)
425 {
426 	return -ENOSYS;
427 }
428 # define xfs_rtalloc_query_range(m,t,l,h,f,p)		(-ENOSYS)
429 # define xfs_rtalloc_query_all(m,t,f,p)			(-ENOSYS)
430 # define xfs_rtbitmap_read_buf(a,b)			(-ENOSYS)
431 # define xfs_rtsummary_read_buf(a,b)			(-ENOSYS)
432 # define xfs_rtbuf_cache_relse(a)			(0)
433 # define xfs_rtalloc_extent_is_free(m,t,s,l,i)		(-ENOSYS)
434 static inline xfs_filblks_t
435 xfs_rtbitmap_blockcount_len(struct xfs_mount *mp, xfs_rtbxlen_t rtextents)
436 {
437 	/* shut up gcc */
438 	return 0;
439 }
440 #endif /* CONFIG_XFS_RT */
441 
442 #endif /* __XFS_RTBITMAP_H__ */
443