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