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