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