Line data Source code
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 : static inline xfs_rtblock_t
10 390079914 : xfs_rtx_to_rtb(
11 : struct xfs_mount *mp,
12 : xfs_rtxnum_t rtx)
13 : {
14 390079914 : if (mp->m_rtxblklog >= 0)
15 371215751 : return rtx << mp->m_rtxblklog;
16 :
17 18864163 : return rtx * mp->m_sb.sb_rextsize;
18 : }
19 :
20 : static inline xfs_extlen_t
21 86772618 : xfs_rtxlen_to_extlen(
22 : struct xfs_mount *mp,
23 : xfs_rtxlen_t rtxlen)
24 : {
25 86772618 : if (mp->m_rtxblklog >= 0)
26 79730738 : return rtxlen << mp->m_rtxblklog;
27 :
28 7041880 : return rtxlen * mp->m_sb.sb_rextsize;
29 : }
30 :
31 : /* Compute the misalignment between an extent length and a realtime extent .*/
32 : static inline unsigned int
33 173765469 : xfs_extlen_to_rtxmod(
34 : struct xfs_mount *mp,
35 : xfs_extlen_t len)
36 : {
37 173765469 : if (mp->m_rtxblklog >= 0)
38 159668095 : return len & mp->m_rtxblkmask;
39 :
40 14097374 : return len % mp->m_sb.sb_rextsize;
41 : }
42 :
43 : static inline xfs_rtxlen_t
44 1289248444 : xfs_extlen_to_rtxlen(
45 : struct xfs_mount *mp,
46 : xfs_extlen_t len)
47 : {
48 1289248444 : if (mp->m_rtxblklog >= 0)
49 1225087435 : return len >> mp->m_rtxblklog;
50 :
51 64161009 : return len / mp->m_sb.sb_rextsize;
52 : }
53 :
54 : static inline xfs_rtxnum_t
55 474617637 : xfs_rtb_to_rtx(
56 : struct xfs_mount *mp,
57 : xfs_rtblock_t rtbno,
58 : xfs_extlen_t *mod)
59 : {
60 474617637 : if (mp->m_rtxblklog >= 0) {
61 451457846 : *mod = rtbno & mp->m_rtxblkmask;
62 451457846 : return rtbno >> mp->m_rtxblklog;
63 : }
64 :
65 23159791 : return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, mod);
66 : }
67 :
68 : static inline xfs_rtxnum_t
69 2105184403 : xfs_rtb_to_rtxt(
70 : struct xfs_mount *mp,
71 : xfs_rtblock_t rtbno)
72 : {
73 2105184403 : if (mp->m_rtxblklog >= 0)
74 1991854195 : return rtbno >> mp->m_rtxblklog;
75 :
76 113330208 : return div_u64(rtbno, mp->m_sb.sb_rextsize);
77 : }
78 :
79 : /* Round this rtblock up to the nearest rt extent size. */
80 : static inline xfs_rtblock_t
81 : xfs_rtb_roundup_rtx(
82 : struct xfs_mount *mp,
83 : xfs_rtblock_t rtbno)
84 : {
85 47125323 : return roundup_64(rtbno, mp->m_sb.sb_rextsize);
86 : }
87 :
88 : /* Round this rtblock down to the nearest rt extent size. */
89 : static inline xfs_rtblock_t
90 : xfs_rtb_rounddown_rtx(
91 : struct xfs_mount *mp,
92 : xfs_rtblock_t rtbno)
93 : {
94 404214767 : return rounddown_64(rtbno, mp->m_sb.sb_rextsize);
95 : }
96 :
97 : /* Convert an rt extent number to a file block offset in the rt bitmap file. */
98 : static inline xfs_fileoff_t
99 3867730120 : xfs_rtx_to_rbmblock(
100 : struct xfs_mount *mp,
101 : xfs_rtxnum_t rtx)
102 : {
103 3867730120 : if (xfs_has_rtgroups(mp))
104 3552775072 : return div_u64(rtx, mp->m_rtx_per_rbmblock);
105 :
106 314955048 : return rtx >> mp->m_blkbit_log;
107 : }
108 :
109 : /* Convert an rt extent number to a word offset within an rt bitmap block. */
110 : static inline unsigned int
111 3515668668 : xfs_rtx_to_rbmword(
112 : struct xfs_mount *mp,
113 : xfs_rtxnum_t rtx)
114 : {
115 3515668668 : if (xfs_has_rtgroups(mp)) {
116 3243562300 : unsigned int mod;
117 :
118 3243562300 : div_u64_rem(rtx >> XFS_NBWORDLOG, mp->m_blockwsize, &mod);
119 3243425347 : return mod;
120 : }
121 :
122 272106368 : return (rtx >> XFS_NBWORDLOG) & (mp->m_blockwsize - 1);
123 : }
124 :
125 : /* Convert a file block offset in the rt bitmap file to an rt extent number. */
126 : static inline xfs_rtxnum_t
127 280996670 : xfs_rbmblock_to_rtx(
128 : struct xfs_mount *mp,
129 : xfs_fileoff_t rbmoff)
130 : {
131 280996670 : if (xfs_has_rtgroups(mp))
132 271510708 : return rbmoff * mp->m_rtx_per_rbmblock;
133 :
134 9485962 : return rbmoff << mp->m_blkbit_log;
135 : }
136 :
137 : /* Return a pointer to a bitmap word within a rt bitmap block buffer. */
138 : static inline union xfs_rtword_ondisk *
139 : xfs_rbmbuf_wordptr(
140 : struct xfs_mount *mp,
141 : void *buf,
142 : unsigned int rbmword)
143 : {
144 4197998468 : union xfs_rtword_ondisk *wordp = buf;
145 4197998468 : struct xfs_rtbuf_blkinfo *hdr = buf;
146 :
147 4197998468 : if (xfs_has_rtgroups(mp))
148 3572559130 : wordp = (union xfs_rtword_ondisk *)(hdr + 1);
149 :
150 3532395565 : return &wordp[rbmword];
151 : }
152 :
153 : /* Return a pointer to a bitmap word within a rt bitmap block. */
154 : static inline union xfs_rtword_ondisk *
155 : xfs_rbmblock_wordptr(
156 : struct xfs_buf *bp,
157 : unsigned int rbmword)
158 : {
159 4197998468 : return xfs_rbmbuf_wordptr(bp->b_mount, bp->b_addr, rbmword);
160 : }
161 :
162 : /*
163 : * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t
164 : * offset within the rt summary file.
165 : */
166 : static inline xfs_rtsumoff_t
167 : xfs_rtsumoffs(
168 : struct xfs_mount *mp,
169 : int log2_len,
170 : xfs_fileoff_t rbmoff)
171 : {
172 3140575215 : return log2_len * mp->m_sb.sb_rbmblocks + rbmoff;
173 : }
174 :
175 : /*
176 : * Convert an xfs_suminfo_t offset to a file block offset within the rt summary
177 : * file.
178 : */
179 : static inline xfs_fileoff_t
180 3062517497 : xfs_rtsumoffs_to_block(
181 : struct xfs_mount *mp,
182 : xfs_rtsumoff_t rsumoff)
183 : {
184 3062517497 : if (xfs_has_rtgroups(mp))
185 2862560480 : return rsumoff / mp->m_blockwsize;
186 :
187 199957017 : return XFS_B_TO_FSBT(mp, rsumoff * sizeof(xfs_suminfo_t));
188 : }
189 :
190 : /*
191 : * Convert an xfs_suminfo_t offset to an info word offset within an rt summary
192 : * block.
193 : */
194 : static inline unsigned int
195 3062517492 : xfs_rtsumoffs_to_infoword(
196 : struct xfs_mount *mp,
197 : xfs_rtsumoff_t rsumoff)
198 : {
199 3062517492 : unsigned int mask = mp->m_blockmask >> XFS_SUMINFOLOG;
200 :
201 3062517492 : if (xfs_has_rtgroups(mp))
202 2862560476 : return rsumoff % mp->m_blockwsize;
203 :
204 199957016 : return rsumoff & mask;
205 : }
206 :
207 : /* Return a pointer to a summary info word within a rt summary block buffer. */
208 : static inline union xfs_suminfo_ondisk *
209 : xfs_rsumbuf_infoptr(
210 : struct xfs_mount *mp,
211 : void *buf,
212 : unsigned int infoword)
213 : {
214 3063533226 : union xfs_suminfo_ondisk *infop = buf;
215 3063533226 : struct xfs_rtbuf_blkinfo *hdr = buf;
216 :
217 3063533226 : if (xfs_has_rtgroups(mp))
218 2863558721 : infop = (union xfs_suminfo_ondisk *)(hdr + 1);
219 :
220 3063533226 : return &infop[infoword];
221 : }
222 :
223 : /* Return a pointer to a summary info word within a rt summary block. */
224 : static inline union xfs_suminfo_ondisk *
225 : xfs_rsumblock_infoptr(
226 : struct xfs_buf *bp,
227 : unsigned int infoword)
228 : {
229 3063533226 : return xfs_rsumbuf_infoptr(bp->b_mount, bp->b_addr, infoword);
230 : }
231 :
232 : static inline const struct xfs_buf_ops *
233 : xfs_rtblock_ops(
234 : struct xfs_mount *mp,
235 : bool issum)
236 : {
237 4419050540 : if (xfs_has_rtgroups(mp)) {
238 3767630253 : if (issum)
239 : return &xfs_rtsummary_buf_ops;
240 3569922381 : return &xfs_rtbitmap_buf_ops;
241 : }
242 : return &xfs_rtbuf_ops;
243 : }
244 :
245 : /*
246 : * Functions for walking free space rtextents in the realtime bitmap.
247 : */
248 : struct xfs_rtalloc_rec {
249 : xfs_rtxnum_t ar_startext;
250 : xfs_rtbxlen_t ar_extcount;
251 : };
252 :
253 : typedef int (*xfs_rtalloc_query_range_fn)(
254 : struct xfs_mount *mp,
255 : struct xfs_trans *tp,
256 : const struct xfs_rtalloc_rec *rec,
257 : void *priv);
258 :
259 : #ifdef CONFIG_XFS_RT
260 : int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp,
261 : xfs_fileoff_t block, int issum, struct xfs_buf **bpp);
262 : int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp,
263 : xfs_rtxnum_t start, xfs_rtxlen_t len, int val,
264 : xfs_rtxnum_t *new, int *stat);
265 : int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp,
266 : xfs_rtxnum_t start, xfs_rtxnum_t limit,
267 : xfs_rtxnum_t *rtblock);
268 : int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp,
269 : xfs_rtxnum_t start, xfs_rtxnum_t limit,
270 : xfs_rtxnum_t *rtblock);
271 : int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp,
272 : xfs_rtxnum_t start, xfs_rtxlen_t len, int val);
273 : int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp,
274 : int log, xfs_fileoff_t bbno, int delta,
275 : struct xfs_buf **rbpp, xfs_fileoff_t *rsb,
276 : xfs_suminfo_t *sum);
277 : int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
278 : xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp,
279 : xfs_fileoff_t *rsb);
280 : int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp,
281 : xfs_rtxnum_t start, xfs_rtxlen_t len,
282 : struct xfs_buf **rbpp, xfs_fileoff_t *rsb);
283 : int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp,
284 : const struct xfs_rtalloc_rec *low_rec,
285 : const struct xfs_rtalloc_rec *high_rec,
286 : xfs_rtalloc_query_range_fn fn, void *priv);
287 : int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp,
288 : xfs_rtalloc_query_range_fn fn,
289 : void *priv);
290 : int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp,
291 : xfs_rtxnum_t start, xfs_rtxlen_t len,
292 : bool *is_free);
293 : /*
294 : * Free an extent in the realtime subvolume. Length is expressed in
295 : * realtime extents, as is the block number.
296 : */
297 : int /* error */
298 : xfs_rtfree_extent(
299 : struct xfs_trans *tp, /* transaction pointer */
300 : xfs_rtxnum_t start, /* starting rtext number to free */
301 : xfs_rtxlen_t len); /* length of extent freed */
302 :
303 : /* Same as above, but in units of rt blocks. */
304 : int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno,
305 : xfs_filblks_t rtlen);
306 :
307 : xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t
308 : rtextents);
309 : unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp,
310 : xfs_rtbxlen_t rtextents);
311 : xfs_rtword_t xfs_rtbitmap_getword(struct xfs_mount *mp,
312 : union xfs_rtword_ondisk *wordptr);
313 : void xfs_rtbitmap_setword(struct xfs_mount *mp,
314 : union xfs_rtword_ondisk *wordptr, xfs_rtword_t incore);
315 :
316 : xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
317 : unsigned int rsumlevels, xfs_extlen_t rbmblocks);
318 : unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp,
319 : unsigned int rsumlevels, xfs_extlen_t rbmblocks);
320 : xfs_suminfo_t xfs_suminfo_get(struct xfs_mount *mp,
321 : union xfs_suminfo_ondisk *infoptr);
322 : void xfs_suminfo_add(struct xfs_mount *mp, union xfs_suminfo_ondisk *infoptr,
323 : int delta);
324 :
325 : void xfs_rtbitmap_lock(struct xfs_trans *tp, struct xfs_mount *mp);
326 : void xfs_rtbitmap_unlock(struct xfs_mount *mp);
327 :
328 : /* Lock the rt bitmap inode in shared mode */
329 : #define XFS_RBMLOCK_BITMAP (1U << 0)
330 : /* Lock the rt summary inode in shared mode */
331 : #define XFS_RBMLOCK_SUMMARY (1U << 1)
332 :
333 : void xfs_rtbitmap_lock_shared(struct xfs_mount *mp,
334 : unsigned int rbmlock_flags);
335 : void xfs_rtbitmap_unlock_shared(struct xfs_mount *mp,
336 : unsigned int rbmlock_flags);
337 : #else /* CONFIG_XFS_RT */
338 : # define xfs_rtfree_extent(t,b,l) (-ENOSYS)
339 : # define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS)
340 : # define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS)
341 : # define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS)
342 : # define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS)
343 : # define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS)
344 : static inline xfs_filblks_t
345 : xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents)
346 : {
347 : /* shut up gcc */
348 : return 0;
349 : }
350 : # define xfs_rtbitmap_wordcount(mp, r) (0)
351 : # define xfs_rtsummary_blockcount(mp, l, b) (0)
352 : # define xfs_rtsummary_wordcount(mp, l, b) (0)
353 : # define xfs_rtbitmap_lock(tp, mp) do { } while (0)
354 : # define xfs_rtbitmap_unlock(mp) do { } while (0)
355 : # define xfs_rtbitmap_lock_shared(mp, lf) do { } while (0)
356 : # define xfs_rtbitmap_unlock_shared(mp, lf) do { } while (0)
357 : #endif /* CONFIG_XFS_RT */
358 :
359 : #endif /* __XFS_RTBITMAP_H__ */
|