xref: /openbmc/linux/fs/xfs/libxfs/xfs_types.c (revision 31e67366)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
4  * Copyright (C) 2017 Oracle.
5  * All Rights Reserved.
6  */
7 #include "xfs.h"
8 #include "xfs_fs.h"
9 #include "xfs_format.h"
10 #include "xfs_shared.h"
11 #include "xfs_trans_resv.h"
12 #include "xfs_bit.h"
13 #include "xfs_mount.h"
14 
15 /* Find the size of the AG, in blocks. */
16 xfs_agblock_t
17 xfs_ag_block_count(
18 	struct xfs_mount	*mp,
19 	xfs_agnumber_t		agno)
20 {
21 	ASSERT(agno < mp->m_sb.sb_agcount);
22 
23 	if (agno < mp->m_sb.sb_agcount - 1)
24 		return mp->m_sb.sb_agblocks;
25 	return mp->m_sb.sb_dblocks - (agno * mp->m_sb.sb_agblocks);
26 }
27 
28 /*
29  * Verify that an AG block number pointer neither points outside the AG
30  * nor points at static metadata.
31  */
32 bool
33 xfs_verify_agbno(
34 	struct xfs_mount	*mp,
35 	xfs_agnumber_t		agno,
36 	xfs_agblock_t		agbno)
37 {
38 	xfs_agblock_t		eoag;
39 
40 	eoag = xfs_ag_block_count(mp, agno);
41 	if (agbno >= eoag)
42 		return false;
43 	if (agbno <= XFS_AGFL_BLOCK(mp))
44 		return false;
45 	return true;
46 }
47 
48 /*
49  * Verify that an FS block number pointer neither points outside the
50  * filesystem nor points at static AG metadata.
51  */
52 bool
53 xfs_verify_fsbno(
54 	struct xfs_mount	*mp,
55 	xfs_fsblock_t		fsbno)
56 {
57 	xfs_agnumber_t		agno = XFS_FSB_TO_AGNO(mp, fsbno);
58 
59 	if (agno >= mp->m_sb.sb_agcount)
60 		return false;
61 	return xfs_verify_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno));
62 }
63 
64 /*
65  * Verify that a data device extent is fully contained inside the filesystem,
66  * does not cross an AG boundary, and does not point at static metadata.
67  */
68 bool
69 xfs_verify_fsbext(
70 	struct xfs_mount	*mp,
71 	xfs_fsblock_t		fsbno,
72 	xfs_fsblock_t		len)
73 {
74 	if (fsbno + len <= fsbno)
75 		return false;
76 
77 	if (!xfs_verify_fsbno(mp, fsbno))
78 		return false;
79 
80 	if (!xfs_verify_fsbno(mp, fsbno + len - 1))
81 		return false;
82 
83 	return  XFS_FSB_TO_AGNO(mp, fsbno) ==
84 		XFS_FSB_TO_AGNO(mp, fsbno + len - 1);
85 }
86 
87 /* Calculate the first and last possible inode number in an AG. */
88 void
89 xfs_agino_range(
90 	struct xfs_mount	*mp,
91 	xfs_agnumber_t		agno,
92 	xfs_agino_t		*first,
93 	xfs_agino_t		*last)
94 {
95 	xfs_agblock_t		bno;
96 	xfs_agblock_t		eoag;
97 
98 	eoag = xfs_ag_block_count(mp, agno);
99 
100 	/*
101 	 * Calculate the first inode, which will be in the first
102 	 * cluster-aligned block after the AGFL.
103 	 */
104 	bno = round_up(XFS_AGFL_BLOCK(mp) + 1, M_IGEO(mp)->cluster_align);
105 	*first = XFS_AGB_TO_AGINO(mp, bno);
106 
107 	/*
108 	 * Calculate the last inode, which will be at the end of the
109 	 * last (aligned) cluster that can be allocated in the AG.
110 	 */
111 	bno = round_down(eoag, M_IGEO(mp)->cluster_align);
112 	*last = XFS_AGB_TO_AGINO(mp, bno) - 1;
113 }
114 
115 /*
116  * Verify that an AG inode number pointer neither points outside the AG
117  * nor points at static metadata.
118  */
119 bool
120 xfs_verify_agino(
121 	struct xfs_mount	*mp,
122 	xfs_agnumber_t		agno,
123 	xfs_agino_t		agino)
124 {
125 	xfs_agino_t		first;
126 	xfs_agino_t		last;
127 
128 	xfs_agino_range(mp, agno, &first, &last);
129 	return agino >= first && agino <= last;
130 }
131 
132 /*
133  * Verify that an AG inode number pointer neither points outside the AG
134  * nor points at static metadata, or is NULLAGINO.
135  */
136 bool
137 xfs_verify_agino_or_null(
138 	struct xfs_mount	*mp,
139 	xfs_agnumber_t		agno,
140 	xfs_agino_t		agino)
141 {
142 	return agino == NULLAGINO || xfs_verify_agino(mp, agno, agino);
143 }
144 
145 /*
146  * Verify that an FS inode number pointer neither points outside the
147  * filesystem nor points at static AG metadata.
148  */
149 bool
150 xfs_verify_ino(
151 	struct xfs_mount	*mp,
152 	xfs_ino_t		ino)
153 {
154 	xfs_agnumber_t		agno = XFS_INO_TO_AGNO(mp, ino);
155 	xfs_agino_t		agino = XFS_INO_TO_AGINO(mp, ino);
156 
157 	if (agno >= mp->m_sb.sb_agcount)
158 		return false;
159 	if (XFS_AGINO_TO_INO(mp, agno, agino) != ino)
160 		return false;
161 	return xfs_verify_agino(mp, agno, agino);
162 }
163 
164 /* Is this an internal inode number? */
165 bool
166 xfs_internal_inum(
167 	struct xfs_mount	*mp,
168 	xfs_ino_t		ino)
169 {
170 	return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
171 		(xfs_sb_version_hasquota(&mp->m_sb) &&
172 		 xfs_is_quota_inode(&mp->m_sb, ino));
173 }
174 
175 /*
176  * Verify that a directory entry's inode number doesn't point at an internal
177  * inode, empty space, or static AG metadata.
178  */
179 bool
180 xfs_verify_dir_ino(
181 	struct xfs_mount	*mp,
182 	xfs_ino_t		ino)
183 {
184 	if (xfs_internal_inum(mp, ino))
185 		return false;
186 	return xfs_verify_ino(mp, ino);
187 }
188 
189 /*
190  * Verify that an realtime block number pointer doesn't point off the
191  * end of the realtime device.
192  */
193 bool
194 xfs_verify_rtbno(
195 	struct xfs_mount	*mp,
196 	xfs_rtblock_t		rtbno)
197 {
198 	return rtbno < mp->m_sb.sb_rblocks;
199 }
200 
201 /* Verify that a realtime device extent is fully contained inside the volume. */
202 bool
203 xfs_verify_rtext(
204 	struct xfs_mount	*mp,
205 	xfs_rtblock_t		rtbno,
206 	xfs_rtblock_t		len)
207 {
208 	if (rtbno + len <= rtbno)
209 		return false;
210 
211 	if (!xfs_verify_rtbno(mp, rtbno))
212 		return false;
213 
214 	return xfs_verify_rtbno(mp, rtbno + len - 1);
215 }
216 
217 /* Calculate the range of valid icount values. */
218 void
219 xfs_icount_range(
220 	struct xfs_mount	*mp,
221 	unsigned long long	*min,
222 	unsigned long long	*max)
223 {
224 	unsigned long long	nr_inos = 0;
225 	xfs_agnumber_t		agno;
226 
227 	/* root, rtbitmap, rtsum all live in the first chunk */
228 	*min = XFS_INODES_PER_CHUNK;
229 
230 	for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
231 		xfs_agino_t	first, last;
232 
233 		xfs_agino_range(mp, agno, &first, &last);
234 		nr_inos += last - first + 1;
235 	}
236 	*max = nr_inos;
237 }
238 
239 /* Sanity-checking of inode counts. */
240 bool
241 xfs_verify_icount(
242 	struct xfs_mount	*mp,
243 	unsigned long long	icount)
244 {
245 	unsigned long long	min, max;
246 
247 	xfs_icount_range(mp, &min, &max);
248 	return icount >= min && icount <= max;
249 }
250 
251 /* Sanity-checking of dir/attr block offsets. */
252 bool
253 xfs_verify_dablk(
254 	struct xfs_mount	*mp,
255 	xfs_fileoff_t		dabno)
256 {
257 	xfs_dablk_t		max_dablk = -1U;
258 
259 	return dabno <= max_dablk;
260 }
261 
262 /* Check that a file block offset does not exceed the maximum. */
263 bool
264 xfs_verify_fileoff(
265 	struct xfs_mount	*mp,
266 	xfs_fileoff_t		off)
267 {
268 	return off <= XFS_MAX_FILEOFF;
269 }
270 
271 /* Check that a range of file block offsets do not exceed the maximum. */
272 bool
273 xfs_verify_fileext(
274 	struct xfs_mount	*mp,
275 	xfs_fileoff_t		off,
276 	xfs_fileoff_t		len)
277 {
278 	if (off + len <= off)
279 		return false;
280 
281 	if (!xfs_verify_fileoff(mp, off))
282 		return false;
283 
284 	return xfs_verify_fileoff(mp, off + len - 1);
285 }
286