Commit | Line | Data |
---|---|---|
13928113 DW |
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 | ||
fa5a3872 DW |
9 | static inline xfs_rtblock_t |
10 | xfs_rtx_to_rtb( | |
11 | struct xfs_mount *mp, | |
12 | xfs_rtxnum_t rtx) | |
13 | { | |
ef5a83b7 DW |
14 | if (mp->m_rtxblklog >= 0) |
15 | return rtx << mp->m_rtxblklog; | |
16 | ||
fa5a3872 DW |
17 | return rtx * mp->m_sb.sb_rextsize; |
18 | } | |
19 | ||
20 | static inline xfs_extlen_t | |
21 | xfs_rtxlen_to_extlen( | |
22 | struct xfs_mount *mp, | |
23 | xfs_rtxlen_t rtxlen) | |
24 | { | |
ef5a83b7 DW |
25 | if (mp->m_rtxblklog >= 0) |
26 | return rtxlen << mp->m_rtxblklog; | |
27 | ||
fa5a3872 DW |
28 | return rtxlen * mp->m_sb.sb_rextsize; |
29 | } | |
30 | ||
68db60bf DW |
31 | /* Compute the misalignment between an extent length and a realtime extent .*/ |
32 | static inline unsigned int | |
33 | xfs_extlen_to_rtxmod( | |
34 | struct xfs_mount *mp, | |
35 | xfs_extlen_t len) | |
36 | { | |
ef5a83b7 DW |
37 | if (mp->m_rtxblklog >= 0) |
38 | return len & mp->m_rtxblkmask; | |
39 | ||
68db60bf DW |
40 | return len % mp->m_sb.sb_rextsize; |
41 | } | |
42 | ||
2c2b981b DW |
43 | static inline xfs_rtxlen_t |
44 | xfs_extlen_to_rtxlen( | |
45 | struct xfs_mount *mp, | |
46 | xfs_extlen_t len) | |
47 | { | |
ef5a83b7 DW |
48 | if (mp->m_rtxblklog >= 0) |
49 | return len >> mp->m_rtxblklog; | |
50 | ||
2c2b981b DW |
51 | return len / mp->m_sb.sb_rextsize; |
52 | } | |
53 | ||
5dc3a80d DW |
54 | /* Convert an rt block number into an rt extent number. */ |
55 | static inline xfs_rtxnum_t | |
56 | xfs_rtb_to_rtx( | |
57 | struct xfs_mount *mp, | |
58 | xfs_rtblock_t rtbno) | |
59 | { | |
ef5a83b7 DW |
60 | if (likely(mp->m_rtxblklog >= 0)) |
61 | return rtbno >> mp->m_rtxblklog; | |
62 | ||
5dc3a80d DW |
63 | return div_u64(rtbno, mp->m_sb.sb_rextsize); |
64 | } | |
65 | ||
66 | /* Return the offset of an rt block number within an rt extent. */ | |
67 | static inline xfs_extlen_t | |
68 | xfs_rtb_to_rtxoff( | |
69 | struct xfs_mount *mp, | |
70 | xfs_rtblock_t rtbno) | |
71 | { | |
ef5a83b7 DW |
72 | if (likely(mp->m_rtxblklog >= 0)) |
73 | return rtbno & mp->m_rtxblkmask; | |
74 | ||
5dc3a80d DW |
75 | return do_div(rtbno, mp->m_sb.sb_rextsize); |
76 | } | |
77 | ||
78 | /* | |
79 | * Crack an rt block number into an rt extent number and an offset within that | |
80 | * rt extent. Returns the rt extent number directly and the offset in @off. | |
81 | */ | |
82 | static inline xfs_rtxnum_t | |
83 | xfs_rtb_to_rtxrem( | |
84 | struct xfs_mount *mp, | |
85 | xfs_rtblock_t rtbno, | |
86 | xfs_extlen_t *off) | |
87 | { | |
ef5a83b7 DW |
88 | if (likely(mp->m_rtxblklog >= 0)) { |
89 | *off = rtbno & mp->m_rtxblkmask; | |
90 | return rtbno >> mp->m_rtxblklog; | |
91 | } | |
92 | ||
5dc3a80d DW |
93 | return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, off); |
94 | } | |
95 | ||
05564124 DW |
96 | /* |
97 | * Convert an rt block number into an rt extent number, rounding up to the next | |
98 | * rt extent if the rt block is not aligned to an rt extent boundary. | |
99 | */ | |
100 | static inline xfs_rtxnum_t | |
101 | xfs_rtb_to_rtxup( | |
102 | struct xfs_mount *mp, | |
103 | xfs_rtblock_t rtbno) | |
104 | { | |
ef5a83b7 DW |
105 | if (likely(mp->m_rtxblklog >= 0)) { |
106 | if (rtbno & mp->m_rtxblkmask) | |
107 | return (rtbno >> mp->m_rtxblklog) + 1; | |
108 | return rtbno >> mp->m_rtxblklog; | |
109 | } | |
110 | ||
05564124 DW |
111 | if (do_div(rtbno, mp->m_sb.sb_rextsize)) |
112 | rtbno++; | |
113 | return rtbno; | |
114 | } | |
115 | ||
5f57f730 DW |
116 | /* Round this rtblock up to the nearest rt extent size. */ |
117 | static inline xfs_rtblock_t | |
118 | xfs_rtb_roundup_rtx( | |
119 | struct xfs_mount *mp, | |
120 | xfs_rtblock_t rtbno) | |
121 | { | |
122 | return roundup_64(rtbno, mp->m_sb.sb_rextsize); | |
123 | } | |
124 | ||
125 | /* Round this rtblock down to the nearest rt extent size. */ | |
126 | static inline xfs_rtblock_t | |
127 | xfs_rtb_rounddown_rtx( | |
128 | struct xfs_mount *mp, | |
129 | xfs_rtblock_t rtbno) | |
130 | { | |
131 | return rounddown_64(rtbno, mp->m_sb.sb_rextsize); | |
132 | } | |
133 | ||
90d98a6a DW |
134 | /* Convert an rt extent number to a file block offset in the rt bitmap file. */ |
135 | static inline xfs_fileoff_t | |
136 | xfs_rtx_to_rbmblock( | |
137 | struct xfs_mount *mp, | |
138 | xfs_rtxnum_t rtx) | |
139 | { | |
140 | return rtx >> mp->m_blkbit_log; | |
141 | } | |
142 | ||
143 | /* Convert an rt extent number to a word offset within an rt bitmap block. */ | |
144 | static inline unsigned int | |
145 | xfs_rtx_to_rbmword( | |
146 | struct xfs_mount *mp, | |
147 | xfs_rtxnum_t rtx) | |
148 | { | |
add3cdda | 149 | return (rtx >> XFS_NBWORDLOG) & (mp->m_blockwsize - 1); |
90d98a6a DW |
150 | } |
151 | ||
152 | /* Convert a file block offset in the rt bitmap file to an rt extent number. */ | |
153 | static inline xfs_rtxnum_t | |
154 | xfs_rbmblock_to_rtx( | |
155 | struct xfs_mount *mp, | |
156 | xfs_fileoff_t rbmoff) | |
157 | { | |
158 | return rbmoff << mp->m_blkbit_log; | |
159 | } | |
160 | ||
a9948626 DW |
161 | /* Return a pointer to a bitmap word within a rt bitmap block. */ |
162 | static inline xfs_rtword_t * | |
163 | xfs_rbmblock_wordptr( | |
164 | struct xfs_buf *bp, | |
165 | unsigned int index) | |
166 | { | |
167 | xfs_rtword_t *words = bp->b_addr; | |
168 | ||
169 | return words + index; | |
170 | } | |
171 | ||
097b4b7b DW |
172 | /* |
173 | * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t | |
174 | * offset within the rt summary file. | |
175 | */ | |
176 | static inline xfs_rtsumoff_t | |
177 | xfs_rtsumoffs( | |
178 | struct xfs_mount *mp, | |
179 | int log2_len, | |
180 | xfs_fileoff_t rbmoff) | |
181 | { | |
182 | return log2_len * mp->m_sb.sb_rbmblocks + rbmoff; | |
183 | } | |
184 | ||
185 | /* | |
186 | * Convert an xfs_suminfo_t offset to a file block offset within the rt summary | |
187 | * file. | |
188 | */ | |
189 | static inline xfs_fileoff_t | |
190 | xfs_rtsumoffs_to_block( | |
191 | struct xfs_mount *mp, | |
192 | xfs_rtsumoff_t rsumoff) | |
193 | { | |
194 | return XFS_B_TO_FSBT(mp, rsumoff * sizeof(xfs_suminfo_t)); | |
195 | } | |
196 | ||
197 | /* | |
198 | * Convert an xfs_suminfo_t offset to an info word offset within an rt summary | |
199 | * block. | |
200 | */ | |
201 | static inline unsigned int | |
202 | xfs_rtsumoffs_to_infoword( | |
203 | struct xfs_mount *mp, | |
204 | xfs_rtsumoff_t rsumoff) | |
205 | { | |
206 | unsigned int mask = mp->m_blockmask >> XFS_SUMINFOLOG; | |
207 | ||
208 | return rsumoff & mask; | |
209 | } | |
210 | ||
211 | /* Return a pointer to a summary info word within a rt summary block. */ | |
212 | static inline xfs_suminfo_t * | |
213 | xfs_rsumblock_infoptr( | |
214 | struct xfs_buf *bp, | |
215 | unsigned int index) | |
216 | { | |
217 | xfs_suminfo_t *info = bp->b_addr; | |
218 | ||
219 | return info + index; | |
220 | } | |
221 | ||
13928113 | 222 | /* |
2d5f216b | 223 | * Functions for walking free space rtextents in the realtime bitmap. |
13928113 DW |
224 | */ |
225 | struct xfs_rtalloc_rec { | |
2d5f216b | 226 | xfs_rtxnum_t ar_startext; |
f29c3e74 | 227 | xfs_rtbxlen_t ar_extcount; |
13928113 DW |
228 | }; |
229 | ||
230 | typedef int (*xfs_rtalloc_query_range_fn)( | |
231 | struct xfs_mount *mp, | |
232 | struct xfs_trans *tp, | |
233 | const struct xfs_rtalloc_rec *rec, | |
234 | void *priv); | |
235 | ||
236 | #ifdef CONFIG_XFS_RT | |
237 | int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp, | |
03f4de33 | 238 | xfs_fileoff_t block, int issum, struct xfs_buf **bpp); |
13928113 | 239 | int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp, |
2d5f216b DW |
240 | xfs_rtxnum_t start, xfs_rtxlen_t len, int val, |
241 | xfs_rtxnum_t *new, int *stat); | |
13928113 | 242 | int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp, |
2d5f216b DW |
243 | xfs_rtxnum_t start, xfs_rtxnum_t limit, |
244 | xfs_rtxnum_t *rtblock); | |
13928113 | 245 | int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp, |
2d5f216b DW |
246 | xfs_rtxnum_t start, xfs_rtxnum_t limit, |
247 | xfs_rtxnum_t *rtblock); | |
13928113 | 248 | int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp, |
2d5f216b | 249 | xfs_rtxnum_t start, xfs_rtxlen_t len, int val); |
13928113 | 250 | int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp, |
03f4de33 DW |
251 | int log, xfs_fileoff_t bbno, int delta, |
252 | struct xfs_buf **rbpp, xfs_fileoff_t *rsb, | |
13928113 DW |
253 | xfs_suminfo_t *sum); |
254 | int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log, | |
03f4de33 DW |
255 | xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp, |
256 | xfs_fileoff_t *rsb); | |
13928113 | 257 | int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp, |
2d5f216b | 258 | xfs_rtxnum_t start, xfs_rtxlen_t len, |
03f4de33 | 259 | struct xfs_buf **rbpp, xfs_fileoff_t *rsb); |
13928113 DW |
260 | int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, |
261 | const struct xfs_rtalloc_rec *low_rec, | |
262 | const struct xfs_rtalloc_rec *high_rec, | |
263 | xfs_rtalloc_query_range_fn fn, void *priv); | |
264 | int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp, | |
265 | xfs_rtalloc_query_range_fn fn, | |
266 | void *priv); | |
13928113 | 267 | int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp, |
2d5f216b | 268 | xfs_rtxnum_t start, xfs_rtxlen_t len, |
13928113 DW |
269 | bool *is_free); |
270 | /* | |
271 | * Free an extent in the realtime subvolume. Length is expressed in | |
272 | * realtime extents, as is the block number. | |
273 | */ | |
274 | int /* error */ | |
275 | xfs_rtfree_extent( | |
276 | struct xfs_trans *tp, /* transaction pointer */ | |
2d5f216b | 277 | xfs_rtxnum_t start, /* starting rtext number to free */ |
a684c538 | 278 | xfs_rtxlen_t len); /* length of extent freed */ |
13928113 DW |
279 | |
280 | /* Same as above, but in units of rt blocks. */ | |
281 | int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, | |
282 | xfs_filblks_t rtlen); | |
d0448fe7 DW |
283 | |
284 | xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t | |
285 | rtextents); | |
286 | unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp, | |
287 | xfs_rtbxlen_t rtextents); | |
13928113 DW |
288 | #else /* CONFIG_XFS_RT */ |
289 | # define xfs_rtfree_extent(t,b,l) (-ENOSYS) | |
290 | # define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) | |
291 | # define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS) | |
292 | # define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) | |
293 | # define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS) | |
294 | # define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) | |
d0448fe7 DW |
295 | static inline xfs_filblks_t |
296 | xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) | |
297 | { | |
298 | /* shut up gcc */ | |
299 | return 0; | |
300 | } | |
301 | # define xfs_rtbitmap_wordcount(mp, r) (0) | |
13928113 DW |
302 | #endif /* CONFIG_XFS_RT */ |
303 | ||
304 | #endif /* __XFS_RTBITMAP_H__ */ |