xref: /linux/fs/xfs/libxfs/xfs_rtbitmap.h (revision 1fc51cf1)
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  * Convert an rt block number into an rt extent number, rounding up to the next
91  * rt extent if the rt block is not aligned to an rt extent boundary.
92  */
93 static inline xfs_rtxnum_t
xfs_rtb_to_rtxup(struct xfs_mount * mp,xfs_rtblock_t rtbno)94 xfs_rtb_to_rtxup(
95 	struct xfs_mount	*mp,
96 	xfs_rtblock_t		rtbno)
97 {
98 	if (likely(mp->m_rtxblklog >= 0)) {
99 		if (rtbno & mp->m_rtxblkmask)
100 			return (rtbno >> mp->m_rtxblklog) + 1;
101 		return rtbno >> mp->m_rtxblklog;
102 	}
103 
104 	if (do_div(rtbno, mp->m_sb.sb_rextsize))
105 		rtbno++;
106 	return rtbno;
107 }
108 
109 /* Round this rtblock up to the nearest rt extent size. */
110 static inline xfs_rtblock_t
xfs_rtb_roundup_rtx(struct xfs_mount * mp,xfs_rtblock_t rtbno)111 xfs_rtb_roundup_rtx(
112 	struct xfs_mount	*mp,
113 	xfs_rtblock_t		rtbno)
114 {
115 	return roundup_64(rtbno, mp->m_sb.sb_rextsize);
116 }
117 
118 /* Round this rtblock down to the nearest rt extent size. */
119 static inline xfs_rtblock_t
xfs_rtb_rounddown_rtx(struct xfs_mount * mp,xfs_rtblock_t rtbno)120 xfs_rtb_rounddown_rtx(
121 	struct xfs_mount	*mp,
122 	xfs_rtblock_t		rtbno)
123 {
124 	return rounddown_64(rtbno, mp->m_sb.sb_rextsize);
125 }
126 
127 /* Convert an rt extent number to a file block offset in the rt bitmap file. */
128 static inline xfs_fileoff_t
xfs_rtx_to_rbmblock(struct xfs_mount * mp,xfs_rtxnum_t rtx)129 xfs_rtx_to_rbmblock(
130 	struct xfs_mount	*mp,
131 	xfs_rtxnum_t		rtx)
132 {
133 	return rtx >> mp->m_blkbit_log;
134 }
135 
136 /* Convert an rt extent number to a word offset within an rt bitmap block. */
137 static inline unsigned int
xfs_rtx_to_rbmword(struct xfs_mount * mp,xfs_rtxnum_t rtx)138 xfs_rtx_to_rbmword(
139 	struct xfs_mount	*mp,
140 	xfs_rtxnum_t		rtx)
141 {
142 	return (rtx >> XFS_NBWORDLOG) & (mp->m_blockwsize - 1);
143 }
144 
145 /* Convert a file block offset in the rt bitmap file to an rt extent number. */
146 static inline xfs_rtxnum_t
xfs_rbmblock_to_rtx(struct xfs_mount * mp,xfs_fileoff_t rbmoff)147 xfs_rbmblock_to_rtx(
148 	struct xfs_mount	*mp,
149 	xfs_fileoff_t		rbmoff)
150 {
151 	return rbmoff << mp->m_blkbit_log;
152 }
153 
154 /* Return a pointer to a bitmap word within a rt bitmap block. */
155 static inline union xfs_rtword_raw *
xfs_rbmblock_wordptr(struct xfs_rtalloc_args * args,unsigned int index)156 xfs_rbmblock_wordptr(
157 	struct xfs_rtalloc_args	*args,
158 	unsigned int		index)
159 {
160 	union xfs_rtword_raw	*words = args->rbmbp->b_addr;
161 
162 	return words + index;
163 }
164 
165 /* Convert an ondisk bitmap word to its incore representation. */
166 static inline xfs_rtword_t
xfs_rtbitmap_getword(struct xfs_rtalloc_args * args,unsigned int index)167 xfs_rtbitmap_getword(
168 	struct xfs_rtalloc_args	*args,
169 	unsigned int		index)
170 {
171 	union xfs_rtword_raw	*word = xfs_rbmblock_wordptr(args, index);
172 
173 	return word->old;
174 }
175 
176 /* Set an ondisk bitmap word from an incore representation. */
177 static inline void
xfs_rtbitmap_setword(struct xfs_rtalloc_args * args,unsigned int index,xfs_rtword_t value)178 xfs_rtbitmap_setword(
179 	struct xfs_rtalloc_args	*args,
180 	unsigned int		index,
181 	xfs_rtword_t		value)
182 {
183 	union xfs_rtword_raw	*word = xfs_rbmblock_wordptr(args, index);
184 
185 	word->old = value;
186 }
187 
188 /*
189  * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t
190  * offset within the rt summary file.
191  */
192 static inline xfs_rtsumoff_t
xfs_rtsumoffs(struct xfs_mount * mp,int log2_len,xfs_fileoff_t rbmoff)193 xfs_rtsumoffs(
194 	struct xfs_mount	*mp,
195 	int			log2_len,
196 	xfs_fileoff_t		rbmoff)
197 {
198 	return log2_len * mp->m_sb.sb_rbmblocks + rbmoff;
199 }
200 
201 /*
202  * Convert an xfs_suminfo_t offset to a file block offset within the rt summary
203  * file.
204  */
205 static inline xfs_fileoff_t
xfs_rtsumoffs_to_block(struct xfs_mount * mp,xfs_rtsumoff_t rsumoff)206 xfs_rtsumoffs_to_block(
207 	struct xfs_mount	*mp,
208 	xfs_rtsumoff_t		rsumoff)
209 {
210 	return XFS_B_TO_FSBT(mp, rsumoff * sizeof(xfs_suminfo_t));
211 }
212 
213 /*
214  * Convert an xfs_suminfo_t offset to an info word offset within an rt summary
215  * block.
216  */
217 static inline unsigned int
xfs_rtsumoffs_to_infoword(struct xfs_mount * mp,xfs_rtsumoff_t rsumoff)218 xfs_rtsumoffs_to_infoword(
219 	struct xfs_mount	*mp,
220 	xfs_rtsumoff_t		rsumoff)
221 {
222 	unsigned int		mask = mp->m_blockmask >> XFS_SUMINFOLOG;
223 
224 	return rsumoff & mask;
225 }
226 
227 /* Return a pointer to a summary info word within a rt summary block. */
228 static inline union xfs_suminfo_raw *
xfs_rsumblock_infoptr(struct xfs_rtalloc_args * args,unsigned int index)229 xfs_rsumblock_infoptr(
230 	struct xfs_rtalloc_args	*args,
231 	unsigned int		index)
232 {
233 	union xfs_suminfo_raw	*info = args->sumbp->b_addr;
234 
235 	return info + index;
236 }
237 
238 /* Get the current value of a summary counter. */
239 static inline xfs_suminfo_t
xfs_suminfo_get(struct xfs_rtalloc_args * args,unsigned int index)240 xfs_suminfo_get(
241 	struct xfs_rtalloc_args	*args,
242 	unsigned int		index)
243 {
244 	union xfs_suminfo_raw	*info = xfs_rsumblock_infoptr(args, index);
245 
246 	return info->old;
247 }
248 
249 /* Add to the current value of a summary counter and return the new value. */
250 static inline xfs_suminfo_t
xfs_suminfo_add(struct xfs_rtalloc_args * args,unsigned int index,int delta)251 xfs_suminfo_add(
252 	struct xfs_rtalloc_args	*args,
253 	unsigned int		index,
254 	int			delta)
255 {
256 	union xfs_suminfo_raw	*info = xfs_rsumblock_infoptr(args, index);
257 
258 	info->old += delta;
259 	return info->old;
260 }
261 
262 /*
263  * Functions for walking free space rtextents in the realtime bitmap.
264  */
265 struct xfs_rtalloc_rec {
266 	xfs_rtxnum_t		ar_startext;
267 	xfs_rtbxlen_t		ar_extcount;
268 };
269 
270 typedef int (*xfs_rtalloc_query_range_fn)(
271 	struct xfs_mount		*mp,
272 	struct xfs_trans		*tp,
273 	const struct xfs_rtalloc_rec	*rec,
274 	void				*priv);
275 
276 #ifdef CONFIG_XFS_RT
277 void xfs_rtbuf_cache_relse(struct xfs_rtalloc_args *args);
278 int xfs_rtbitmap_read_buf(struct xfs_rtalloc_args *args, xfs_fileoff_t block);
279 int xfs_rtsummary_read_buf(struct xfs_rtalloc_args *args, xfs_fileoff_t block);
280 int xfs_rtcheck_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
281 		xfs_rtxlen_t len, int val, xfs_rtxnum_t *new, int *stat);
282 int xfs_rtfind_back(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
283 		xfs_rtxnum_t *rtblock);
284 int xfs_rtfind_forw(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
285 		xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock);
286 int xfs_rtmodify_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
287 		xfs_rtxlen_t len, int val);
288 int xfs_rtget_summary(struct xfs_rtalloc_args *args, int log,
289 		xfs_fileoff_t bbno, xfs_suminfo_t *sum);
290 int xfs_rtmodify_summary(struct xfs_rtalloc_args *args, int log,
291 		xfs_fileoff_t bbno, int delta);
292 int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
293 		xfs_rtxlen_t len);
294 int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp,
295 		xfs_rtxnum_t start, xfs_rtxnum_t end,
296 		xfs_rtalloc_query_range_fn fn, void *priv);
297 int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp,
298 			  xfs_rtalloc_query_range_fn fn,
299 			  void *priv);
300 int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp,
301 			       xfs_rtxnum_t start, xfs_rtxlen_t len,
302 			       bool *is_free);
303 /*
304  * Free an extent in the realtime subvolume.  Length is expressed in
305  * realtime extents, as is the block number.
306  */
307 int					/* error */
308 xfs_rtfree_extent(
309 	struct xfs_trans	*tp,	/* transaction pointer */
310 	xfs_rtxnum_t		start,	/* starting rtext number to free */
311 	xfs_rtxlen_t		len);	/* length of extent freed */
312 
313 /* Same as above, but in units of rt blocks. */
314 int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno,
315 		xfs_filblks_t rtlen);
316 
317 xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t
318 		rtextents);
319 xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
320 		unsigned int rsumlevels, xfs_extlen_t rbmblocks);
321 
322 int xfs_rtfile_initialize_blocks(struct xfs_inode *ip,
323 		xfs_fileoff_t offset_fsb, xfs_fileoff_t end_fsb, void *data);
324 
325 void xfs_rtbitmap_lock(struct xfs_mount *mp);
326 void xfs_rtbitmap_unlock(struct xfs_mount *mp);
327 void xfs_rtbitmap_trans_join(struct xfs_trans *tp);
328 
329 /* Lock the rt bitmap inode in shared mode */
330 #define XFS_RBMLOCK_BITMAP	(1U << 0)
331 /* Lock the rt summary inode in shared mode */
332 #define XFS_RBMLOCK_SUMMARY	(1U << 1)
333 
334 void xfs_rtbitmap_lock_shared(struct xfs_mount *mp,
335 		unsigned int rbmlock_flags);
336 void xfs_rtbitmap_unlock_shared(struct xfs_mount *mp,
337 		unsigned int rbmlock_flags);
338 #else /* CONFIG_XFS_RT */
339 # define xfs_rtfree_extent(t,b,l)			(-ENOSYS)
340 # define xfs_rtfree_blocks(t,rb,rl)			(-ENOSYS)
341 # define xfs_rtalloc_query_range(m,t,l,h,f,p)		(-ENOSYS)
342 # define xfs_rtalloc_query_all(m,t,f,p)			(-ENOSYS)
343 # define xfs_rtbitmap_read_buf(a,b)			(-ENOSYS)
344 # define xfs_rtsummary_read_buf(a,b)			(-ENOSYS)
345 # define xfs_rtbuf_cache_relse(a)			(0)
346 # define xfs_rtalloc_extent_is_free(m,t,s,l,i)		(-ENOSYS)
347 static inline xfs_filblks_t
xfs_rtbitmap_blockcount(struct xfs_mount * mp,xfs_rtbxlen_t rtextents)348 xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents)
349 {
350 	/* shut up gcc */
351 	return 0;
352 }
353 # define xfs_rtsummary_blockcount(mp, l, b)		(0)
354 # define xfs_rtbitmap_lock(mp)			do { } while (0)
355 # define xfs_rtbitmap_trans_join(tp)		do { } while (0)
356 # define xfs_rtbitmap_unlock(mp)		do { } while (0)
357 # define xfs_rtbitmap_lock_shared(mp, lf)	do { } while (0)
358 # define xfs_rtbitmap_unlock_shared(mp, lf)	do { } while (0)
359 #endif /* CONFIG_XFS_RT */
360 
361 #endif /* __XFS_RTBITMAP_H__ */
362