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