xfs: create helpers for rtbitmap block/wordcount computations
[linux-block.git] / fs / xfs / libxfs / xfs_rtbitmap.h
CommitLineData
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
9static inline xfs_rtblock_t
10xfs_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
20static inline xfs_extlen_t
21xfs_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 .*/
32static inline unsigned int
33xfs_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
43static inline xfs_rtxlen_t
44xfs_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. */
55static inline xfs_rtxnum_t
56xfs_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. */
67static inline xfs_extlen_t
68xfs_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 */
82static inline xfs_rtxnum_t
83xfs_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 */
100static inline xfs_rtxnum_t
101xfs_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. */
117static inline xfs_rtblock_t
118xfs_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. */
126static inline xfs_rtblock_t
127xfs_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. */
135static inline xfs_fileoff_t
136xfs_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. */
144static inline unsigned int
145xfs_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. */
153static inline xfs_rtxnum_t
154xfs_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. */
162static inline xfs_rtword_t *
163xfs_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 */
176static inline xfs_rtsumoff_t
177xfs_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 */
189static inline xfs_fileoff_t
190xfs_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 */
201static inline unsigned int
202xfs_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. */
212static inline xfs_suminfo_t *
213xfs_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 */
225struct xfs_rtalloc_rec {
2d5f216b 226 xfs_rtxnum_t ar_startext;
f29c3e74 227 xfs_rtbxlen_t ar_extcount;
13928113
DW
228};
229
230typedef 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
237int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp,
03f4de33 238 xfs_fileoff_t block, int issum, struct xfs_buf **bpp);
13928113 239int 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 242int 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 245int 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 248int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp,
2d5f216b 249 xfs_rtxnum_t start, xfs_rtxlen_t len, int val);
13928113 250int 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);
254int 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 257int 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
260int 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);
264int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp,
265 xfs_rtalloc_query_range_fn fn,
266 void *priv);
13928113 267int 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 */
274int /* error */
275xfs_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. */
281int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno,
282 xfs_filblks_t rtlen);
d0448fe7
DW
283
284xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t
285 rtextents);
286unsigned 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
295static inline xfs_filblks_t
296xfs_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__ */