summaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_rtbitmap.h
blob: ecf5645dd67091e380cc0cd6b8f3efc0d0680f94 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 */
#ifndef __XFS_RTBITMAP_H__
#define	__XFS_RTBITMAP_H__

static inline xfs_rtblock_t
xfs_rtx_to_rtb(
	struct xfs_mount	*mp,
	xfs_rtxnum_t		rtx)
{
	return rtx * mp->m_sb.sb_rextsize;
}

static inline xfs_extlen_t
xfs_rtxlen_to_extlen(
	struct xfs_mount	*mp,
	xfs_rtxlen_t		rtxlen)
{
	return rtxlen * mp->m_sb.sb_rextsize;
}

/* Compute the misalignment between an extent length and a realtime extent .*/
static inline unsigned int
xfs_extlen_to_rtxmod(
	struct xfs_mount	*mp,
	xfs_extlen_t		len)
{
	return len % mp->m_sb.sb_rextsize;
}

static inline xfs_rtxlen_t
xfs_extlen_to_rtxlen(
	struct xfs_mount	*mp,
	xfs_extlen_t		len)
{
	return len / mp->m_sb.sb_rextsize;
}

/* Convert an rt block number into an rt extent number. */
static inline xfs_rtxnum_t
xfs_rtb_to_rtx(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	return div_u64(rtbno, mp->m_sb.sb_rextsize);
}

/* Return the offset of an rt block number within an rt extent. */
static inline xfs_extlen_t
xfs_rtb_to_rtxoff(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	return do_div(rtbno, mp->m_sb.sb_rextsize);
}

/*
 * Crack an rt block number into an rt extent number and an offset within that
 * rt extent.  Returns the rt extent number directly and the offset in @off.
 */
static inline xfs_rtxnum_t
xfs_rtb_to_rtxrem(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno,
	xfs_extlen_t		*off)
{
	return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, off);
}

/*
 * Convert an rt block number into an rt extent number, rounding up to the next
 * rt extent if the rt block is not aligned to an rt extent boundary.
 */
static inline xfs_rtxnum_t
xfs_rtb_to_rtxup(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	if (do_div(rtbno, mp->m_sb.sb_rextsize))
		rtbno++;
	return rtbno;
}

/* Round this rtblock up to the nearest rt extent size. */
static inline xfs_rtblock_t
xfs_rtb_roundup_rtx(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	return roundup_64(rtbno, mp->m_sb.sb_rextsize);
}

/* Round this rtblock down to the nearest rt extent size. */
static inline xfs_rtblock_t
xfs_rtb_rounddown_rtx(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	return rounddown_64(rtbno, mp->m_sb.sb_rextsize);
}

/*
 * Functions for walking free space rtextents in the realtime bitmap.
 */
struct xfs_rtalloc_rec {
	xfs_rtxnum_t		ar_startext;
	xfs_rtbxlen_t		ar_extcount;
};

typedef int (*xfs_rtalloc_query_range_fn)(
	struct xfs_mount		*mp,
	struct xfs_trans		*tp,
	const struct xfs_rtalloc_rec	*rec,
	void				*priv);

#ifdef CONFIG_XFS_RT
int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp,
		  xfs_fileoff_t block, int issum, struct xfs_buf **bpp);
int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp,
		      xfs_rtxnum_t start, xfs_rtxlen_t len, int val,
		      xfs_rtxnum_t *new, int *stat);
int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp,
		    xfs_rtxnum_t start, xfs_rtxnum_t limit,
		    xfs_rtxnum_t *rtblock);
int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp,
		    xfs_rtxnum_t start, xfs_rtxnum_t limit,
		    xfs_rtxnum_t *rtblock);
int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp,
		       xfs_rtxnum_t start, xfs_rtxlen_t len, int val);
int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp,
			     int log, xfs_fileoff_t bbno, int delta,
			     struct xfs_buf **rbpp, xfs_fileoff_t *rsb,
			     xfs_suminfo_t *sum);
int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
			 xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp,
			 xfs_fileoff_t *rsb);
int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp,
		     xfs_rtxnum_t start, xfs_rtxlen_t len,
		     struct xfs_buf **rbpp, xfs_fileoff_t *rsb);
int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp,
		const struct xfs_rtalloc_rec *low_rec,
		const struct xfs_rtalloc_rec *high_rec,
		xfs_rtalloc_query_range_fn fn, void *priv);
int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp,
			  xfs_rtalloc_query_range_fn fn,
			  void *priv);
int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp,
			       xfs_rtxnum_t start, xfs_rtxlen_t len,
			       bool *is_free);
/*
 * Free an extent in the realtime subvolume.  Length is expressed in
 * realtime extents, as is the block number.
 */
int					/* error */
xfs_rtfree_extent(
	struct xfs_trans	*tp,	/* transaction pointer */
	xfs_rtxnum_t		start,	/* starting rtext number to free */
	xfs_rtxlen_t		len);	/* length of extent freed */

/* Same as above, but in units of rt blocks. */
int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno,
		xfs_filblks_t rtlen);
#else /* CONFIG_XFS_RT */
# define xfs_rtfree_extent(t,b,l)			(-ENOSYS)
# define xfs_rtfree_blocks(t,rb,rl)			(-ENOSYS)
# define xfs_rtalloc_query_range(m,t,l,h,f,p)		(-ENOSYS)
# define xfs_rtalloc_query_all(m,t,f,p)			(-ENOSYS)
# define xfs_rtbuf_get(m,t,b,i,p)			(-ENOSYS)
# define xfs_rtalloc_extent_is_free(m,t,s,l,i)		(-ENOSYS)
#endif /* CONFIG_XFS_RT */

#endif /* __XFS_RTBITMAP_H__ */