xref: /linux/fs/xfs/libxfs/xfs_rtbitmap.h (revision d53b8e36925256097a08d7cb749198d85cbf9b2b)
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
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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
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
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
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
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
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 *
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
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
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
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
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 
364 void xfs_rtbitmap_lock(struct xfs_trans *tp, struct xfs_mount *mp);
365 void xfs_rtbitmap_unlock(struct xfs_mount *mp);
366 
367 /* Lock the rt bitmap inode in shared mode */
368 #define XFS_RBMLOCK_BITMAP	(1U << 0)
369 /* Lock the rt summary inode in shared mode */
370 #define XFS_RBMLOCK_SUMMARY	(1U << 1)
371 
372 void xfs_rtbitmap_lock_shared(struct xfs_mount *mp,
373 		unsigned int rbmlock_flags);
374 void xfs_rtbitmap_unlock_shared(struct xfs_mount *mp,
375 		unsigned int rbmlock_flags);
376 #else /* CONFIG_XFS_RT */
377 # define xfs_rtfree_extent(t,b,l)			(-ENOSYS)
378 # define xfs_rtfree_blocks(t,rb,rl)			(-ENOSYS)
379 # define xfs_rtalloc_query_range(m,t,l,h,f,p)		(-ENOSYS)
380 # define xfs_rtalloc_query_all(m,t,f,p)			(-ENOSYS)
381 # define xfs_rtbitmap_read_buf(a,b)			(-ENOSYS)
382 # define xfs_rtsummary_read_buf(a,b)			(-ENOSYS)
383 # define xfs_rtbuf_cache_relse(a)			(0)
384 # define xfs_rtalloc_extent_is_free(m,t,s,l,i)		(-ENOSYS)
385 static inline xfs_filblks_t
386 xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents)
387 {
388 	/* shut up gcc */
389 	return 0;
390 }
391 # define xfs_rtbitmap_wordcount(mp, r)			(0)
392 # define xfs_rtsummary_blockcount(mp, l, b)		(0)
393 # define xfs_rtsummary_wordcount(mp, l, b)		(0)
394 # define xfs_rtbitmap_lock(tp, mp)		do { } while (0)
395 # define xfs_rtbitmap_unlock(mp)		do { } while (0)
396 # define xfs_rtbitmap_lock_shared(mp, lf)	do { } while (0)
397 # define xfs_rtbitmap_unlock_shared(mp, lf)	do { } while (0)
398 #endif /* CONFIG_XFS_RT */
399 
400 #endif /* __XFS_RTBITMAP_H__ */
401