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