File Index
Files and directories
Sign in
FILE

xfs_rtbitmap.h

File preview with syntax highlighting.

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