File Index
Files and directories
Sign in
FILE

xfs_types.c

File preview with syntax highlighting.

linux-6.19.14/fs/xfs/libxfs/xfs_types.c 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#include "xfs_rtbitmap.h"
 16#include "xfs_rtgroup.h"
 17
 18
 19/*
 20 * Verify that an AG block number pointer neither points outside the AG
 21 * nor points at static metadata.
 22 */
 23static inline bool
 24xfs_verify_agno_agbno(
 25	struct xfs_mount	*mp,
 26	xfs_agnumber_t		agno,
 27	xfs_agblock_t		agbno)
 28{
 29	xfs_agblock_t		eoag;
 30
 31	eoag = xfs_ag_block_count(mp, agno);
 32	if (agbno >= eoag)
 33		return false;
 34	if (agbno <= XFS_AGFL_BLOCK(mp))
 35		return false;
 36	return true;
 37}
 38
 39/*
 40 * Verify that an FS block number pointer neither points outside the
 41 * filesystem nor points at static AG metadata.
 42 */
 43inline bool
 44xfs_verify_fsbno(
 45	struct xfs_mount	*mp,
 46	xfs_fsblock_t		fsbno)
 47{
 48	xfs_agnumber_t		agno = XFS_FSB_TO_AGNO(mp, fsbno);
 49
 50	if (agno >= mp->m_sb.sb_agcount)
 51		return false;
 52	return xfs_verify_agno_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno));
 53}
 54
 55/*
 56 * Verify that a data device extent is fully contained inside the filesystem,
 57 * does not cross an AG boundary, and does not point at static metadata.
 58 */
 59bool
 60xfs_verify_fsbext(
 61	struct xfs_mount	*mp,
 62	xfs_fsblock_t		fsbno,
 63	xfs_fsblock_t		len)
 64{
 65	if (fsbno + len <= fsbno)
 66		return false;
 67
 68	if (!xfs_verify_fsbno(mp, fsbno))
 69		return false;
 70
 71	if (!xfs_verify_fsbno(mp, fsbno + len - 1))
 72		return false;
 73
 74	return  XFS_FSB_TO_AGNO(mp, fsbno) ==
 75		XFS_FSB_TO_AGNO(mp, fsbno + len - 1);
 76}
 77
 78/*
 79 * Verify that an AG inode number pointer neither points outside the AG
 80 * nor points at static metadata.
 81 */
 82static inline bool
 83xfs_verify_agno_agino(
 84	struct xfs_mount	*mp,
 85	xfs_agnumber_t		agno,
 86	xfs_agino_t		agino)
 87{
 88	xfs_agino_t		first;
 89	xfs_agino_t		last;
 90
 91	xfs_agino_range(mp, agno, &first, &last);
 92	return agino >= first && agino <= last;
 93}
 94
 95/*
 96 * Verify that an FS inode number pointer neither points outside the
 97 * filesystem nor points at static AG metadata.
 98 */
 99inline bool
100xfs_verify_ino(
101	struct xfs_mount	*mp,
102	xfs_ino_t		ino)
103{
104	xfs_agnumber_t		agno = XFS_INO_TO_AGNO(mp, ino);
105	xfs_agino_t		agino = XFS_INO_TO_AGINO(mp, ino);
106
107	if (agno >= mp->m_sb.sb_agcount)
108		return false;
109	if (XFS_AGINO_TO_INO(mp, agno, agino) != ino)
110		return false;
111	return xfs_verify_agno_agino(mp, agno, agino);
112}
113
114/* Is this an internal inode number? */
115inline bool
116xfs_is_sb_inum(
117	struct xfs_mount	*mp,
118	xfs_ino_t		ino)
119{
120	return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
121		(xfs_has_quota(mp) &&
122		 xfs_is_quota_inode(&mp->m_sb, ino));
123}
124
125/*
126 * Verify that a directory entry's inode number doesn't point at an internal
127 * inode, empty space, or static AG metadata.
128 */
129bool
130xfs_verify_dir_ino(
131	struct xfs_mount	*mp,
132	xfs_ino_t		ino)
133{
134	if (xfs_is_sb_inum(mp, ino))
135		return false;
136	return xfs_verify_ino(mp, ino);
137}
138
139/*
140 * Verify that a realtime block number pointer neither points outside the
141 * allocatable areas of the rtgroup nor off the end of the realtime
142 * device.
143 */
144inline bool
145xfs_verify_rtbno(
146	struct xfs_mount	*mp,
147	xfs_rtblock_t		rtbno)
148{
149	if (xfs_has_rtgroups(mp)) {
150		xfs_rgnumber_t	rgno = xfs_rtb_to_rgno(mp, rtbno);
151		xfs_rtxnum_t	rtx = xfs_rtb_to_rtx(mp, rtbno);
152
153		if (rgno >= mp->m_sb.sb_rgcount)
154			return false;
155		if (rtx >= xfs_rtgroup_extents(mp, rgno))
156			return false;
157		if (xfs_has_rtsb(mp) && rgno == 0 && rtx == 0)
158			return false;
159		return true;
160	}
161
162	return rtbno < mp->m_sb.sb_rblocks;
163}
164
165/*
166 * Verify that an allocated realtime device extent neither points outside
167 * allocatable areas of the rtgroup, across an rtgroup boundary, nor off the
168 * end of the realtime device.
169 */
170bool
171xfs_verify_rtbext(
172	struct xfs_mount	*mp,
173	xfs_rtblock_t		rtbno,
174	xfs_filblks_t		len)
175{
176	if (rtbno + len <= rtbno)
177		return false;
178
179	if (!xfs_verify_rtbno(mp, rtbno))
180		return false;
181
182	if (!xfs_verify_rtbno(mp, rtbno + len - 1))
183		return false;
184
185	if (xfs_has_rtgroups(mp) &&
186	    xfs_rtb_to_rgno(mp, rtbno) != xfs_rtb_to_rgno(mp, rtbno + len - 1))
187		return false;
188
189	return true;
190}
191
192/* Calculate the range of valid icount values. */
193inline void
194xfs_icount_range(
195	struct xfs_mount	*mp,
196	unsigned long long	*min,
197	unsigned long long	*max)
198{
199	unsigned long long	nr_inos = 0;
200	struct xfs_perag	*pag = NULL;
201
202	/* root, rtbitmap, rtsum all live in the first chunk */
203	*min = XFS_INODES_PER_CHUNK;
204
205	while ((pag = xfs_perag_next(mp, pag)))
206		nr_inos += pag->agino_max - pag->agino_min + 1;
207	*max = nr_inos;
208}
209
210/* Sanity-checking of inode counts. */
211bool
212xfs_verify_icount(
213	struct xfs_mount	*mp,
214	unsigned long long	icount)
215{
216	unsigned long long	min, max;
217
218	xfs_icount_range(mp, &min, &max);
219	return icount >= min && icount <= max;
220}
221
222/* Sanity-checking of dir/attr block offsets. */
223bool
224xfs_verify_dablk(
225	struct xfs_mount	*mp,
226	xfs_fileoff_t		dabno)
227{
228	xfs_dablk_t		max_dablk = -1U;
229
230	return dabno <= max_dablk;
231}
232
233/* Check that a file block offset does not exceed the maximum. */
234bool
235xfs_verify_fileoff(
236	struct xfs_mount	*mp,
237	xfs_fileoff_t		off)
238{
239	return off <= XFS_MAX_FILEOFF;
240}
241
242/* Check that a range of file block offsets do not exceed the maximum. */
243bool
244xfs_verify_fileext(
245	struct xfs_mount	*mp,
246	xfs_fileoff_t		off,
247	xfs_fileoff_t		len)
248{
249	if (off + len <= off)
250		return false;
251
252	if (!xfs_verify_fileoff(mp, off))
253		return false;
254
255	return xfs_verify_fileoff(mp, off + len - 1);
256}
~/ Read-only file preview.