xref: /linux/fs/xfs/scrub/agheader.c (revision 546b928da0427b0d6c663cbb992bd7bfa9ac7971)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2017-2023 Oracle.  All Rights Reserved.
4  * Author: Darrick J. Wong <djwong@kernel.org>
5  */
6 #include "xfs_platform.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_trans_resv.h"
11 #include "xfs_mount.h"
12 #include "xfs_btree.h"
13 #include "xfs_sb.h"
14 #include "xfs_alloc.h"
15 #include "xfs_ialloc.h"
16 #include "xfs_rmap.h"
17 #include "xfs_ag.h"
18 #include "xfs_inode.h"
19 #include "scrub/scrub.h"
20 #include "scrub/common.h"
21 #include "scrub/bitmap.h"
22 #include "scrub/agino_bitmap.h"
23 
24 int
xchk_setup_agheader(struct xfs_scrub * sc)25 xchk_setup_agheader(
26 	struct xfs_scrub	*sc)
27 {
28 	if (xchk_need_intent_drain(sc))
29 		xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN);
30 	return xchk_setup_fs(sc);
31 }
32 
33 /* Superblock */
34 
35 /* Cross-reference with the other btrees. */
36 STATIC void
xchk_superblock_xref(struct xfs_scrub * sc,struct xfs_buf * bp)37 xchk_superblock_xref(
38 	struct xfs_scrub	*sc,
39 	struct xfs_buf		*bp)
40 {
41 	struct xfs_mount	*mp = sc->mp;
42 	xfs_agnumber_t		agno = sc->sm->sm_agno;
43 	xfs_agblock_t		agbno;
44 	int			error;
45 
46 	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
47 		return;
48 
49 	agbno = XFS_SB_BLOCK(mp);
50 
51 	error = xchk_ag_init_existing(sc, agno, &sc->sa);
52 	if (!xchk_xref_process_error(sc, agno, agbno, &error))
53 		return;
54 
55 	xchk_xref_is_used_space(sc, agbno, 1);
56 	xchk_xref_is_not_inode_chunk(sc, agbno, 1);
57 	xchk_xref_is_only_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
58 	xchk_xref_is_not_shared(sc, agbno, 1);
59 	xchk_xref_is_not_cow_staging(sc, agbno, 1);
60 
61 	/* scrub teardown will take care of sc->sa for us */
62 }
63 
64 /*
65  * Calculate the ondisk superblock size in bytes given the feature set of the
66  * mounted filesystem (aka the primary sb).  This is subtlely different from
67  * the logic in xfs_repair, which computes the size of a secondary sb given the
68  * featureset listed in the secondary sb.
69  */
70 STATIC size_t
xchk_superblock_ondisk_size(struct xfs_mount * mp)71 xchk_superblock_ondisk_size(
72 	struct xfs_mount	*mp)
73 {
74 	if (xfs_has_zoned(mp))
75 		return offsetofend(struct xfs_dsb, sb_rtreserved);
76 	if (xfs_has_metadir(mp))
77 		return offsetofend(struct xfs_dsb, sb_pad);
78 	if (xfs_has_metauuid(mp))
79 		return offsetofend(struct xfs_dsb, sb_meta_uuid);
80 	if (xfs_has_crc(mp))
81 		return offsetofend(struct xfs_dsb, sb_lsn);
82 	if (xfs_sb_version_hasmorebits(&mp->m_sb))
83 		return offsetofend(struct xfs_dsb, sb_bad_features2);
84 	if (xfs_has_logv2(mp))
85 		return offsetofend(struct xfs_dsb, sb_logsunit);
86 	if (xfs_has_sector(mp))
87 		return offsetofend(struct xfs_dsb, sb_logsectsize);
88 	/* only support dirv2 or more recent */
89 	return offsetofend(struct xfs_dsb, sb_dirblklog);
90 }
91 
92 /*
93  * Scrub the filesystem superblock.
94  *
95  * Note: We do /not/ attempt to check AG 0's superblock.  Mount is
96  * responsible for validating all the geometry information in sb 0, so
97  * if the filesystem is capable of initiating online scrub, then clearly
98  * sb 0 is ok and we can use its information to check everything else.
99  */
100 int
xchk_superblock(struct xfs_scrub * sc)101 xchk_superblock(
102 	struct xfs_scrub	*sc)
103 {
104 	struct xfs_mount	*mp = sc->mp;
105 	struct xfs_buf		*bp;
106 	struct xfs_dsb		*sb;
107 	struct xfs_perag	*pag;
108 	size_t			sblen;
109 	xfs_agnumber_t		agno;
110 	uint32_t		v2_ok;
111 	__be32			features_mask;
112 	int			error;
113 	__be16			vernum_mask;
114 
115 	agno = sc->sm->sm_agno;
116 	if (agno == 0)
117 		return 0;
118 
119 	/*
120 	 * Grab an active reference to the perag structure.  If we can't get
121 	 * it, we're racing with something that's tearing down the AG, so
122 	 * signal that the AG no longer exists.
123 	 */
124 	pag = xfs_perag_get(mp, agno);
125 	if (!pag)
126 		return -ENOENT;
127 
128 	error = xfs_sb_read_secondary(mp, sc->tp, agno, &bp);
129 	/*
130 	 * The superblock verifier can return several different error codes
131 	 * if it thinks the superblock doesn't look right.  For a mount these
132 	 * would all get bounced back to userspace, but if we're here then the
133 	 * fs mounted successfully, which means that this secondary superblock
134 	 * is simply incorrect.  Treat all these codes the same way we treat
135 	 * any corruption.
136 	 */
137 	switch (error) {
138 	case -EINVAL:	/* also -EWRONGFS */
139 	case -ENOSYS:
140 	case -EFBIG:
141 		error = -EFSCORRUPTED;
142 		fallthrough;
143 	default:
144 		break;
145 	}
146 	if (!xchk_process_error(sc, agno, XFS_SB_BLOCK(mp), &error))
147 		goto out_pag;
148 
149 	sb = bp->b_addr;
150 
151 	/*
152 	 * Verify the geometries match.  Fields that are permanently
153 	 * set by mkfs are checked; fields that can be updated later
154 	 * (and are not propagated to backup superblocks) are preen
155 	 * checked.
156 	 */
157 	if (sb->sb_blocksize != cpu_to_be32(mp->m_sb.sb_blocksize))
158 		xchk_block_set_corrupt(sc, bp);
159 
160 	if (sb->sb_dblocks != cpu_to_be64(mp->m_sb.sb_dblocks))
161 		xchk_block_set_corrupt(sc, bp);
162 
163 	if (sb->sb_rblocks != cpu_to_be64(mp->m_sb.sb_rblocks))
164 		xchk_block_set_corrupt(sc, bp);
165 
166 	if (sb->sb_rextents != cpu_to_be64(mp->m_sb.sb_rextents))
167 		xchk_block_set_corrupt(sc, bp);
168 
169 	if (!uuid_equal(&sb->sb_uuid, &mp->m_sb.sb_uuid))
170 		xchk_block_set_preen(sc, bp);
171 
172 	if (sb->sb_logstart != cpu_to_be64(mp->m_sb.sb_logstart))
173 		xchk_block_set_corrupt(sc, bp);
174 
175 	if (sb->sb_rootino != cpu_to_be64(mp->m_sb.sb_rootino))
176 		xchk_block_set_preen(sc, bp);
177 
178 	if (xfs_has_metadir(sc->mp)) {
179 		if (sb->sb_rbmino != cpu_to_be64(0))
180 			xchk_block_set_corrupt(sc, bp);
181 
182 		if (sb->sb_rsumino != cpu_to_be64(0))
183 			xchk_block_set_corrupt(sc, bp);
184 	} else {
185 		if (sb->sb_rbmino != cpu_to_be64(mp->m_sb.sb_rbmino))
186 			xchk_block_set_preen(sc, bp);
187 
188 		if (sb->sb_rsumino != cpu_to_be64(mp->m_sb.sb_rsumino))
189 			xchk_block_set_preen(sc, bp);
190 	}
191 
192 	if (sb->sb_rextsize != cpu_to_be32(mp->m_sb.sb_rextsize))
193 		xchk_block_set_corrupt(sc, bp);
194 
195 	if (sb->sb_agblocks != cpu_to_be32(mp->m_sb.sb_agblocks))
196 		xchk_block_set_corrupt(sc, bp);
197 
198 	if (sb->sb_agcount != cpu_to_be32(mp->m_sb.sb_agcount))
199 		xchk_block_set_corrupt(sc, bp);
200 
201 	if (sb->sb_rbmblocks != cpu_to_be32(mp->m_sb.sb_rbmblocks))
202 		xchk_block_set_corrupt(sc, bp);
203 
204 	if (sb->sb_logblocks != cpu_to_be32(mp->m_sb.sb_logblocks))
205 		xchk_block_set_corrupt(sc, bp);
206 
207 	/* Check sb_versionnum bits that are set at mkfs time. */
208 	vernum_mask = cpu_to_be16(XFS_SB_VERSION_NUMBITS |
209 				  XFS_SB_VERSION_ALIGNBIT |
210 				  XFS_SB_VERSION_DALIGNBIT |
211 				  XFS_SB_VERSION_SHAREDBIT |
212 				  XFS_SB_VERSION_LOGV2BIT |
213 				  XFS_SB_VERSION_SECTORBIT |
214 				  XFS_SB_VERSION_EXTFLGBIT |
215 				  XFS_SB_VERSION_DIRV2BIT);
216 	if ((sb->sb_versionnum & vernum_mask) !=
217 	    (cpu_to_be16(mp->m_sb.sb_versionnum) & vernum_mask))
218 		xchk_block_set_corrupt(sc, bp);
219 
220 	/* Check sb_versionnum bits that can be set after mkfs time. */
221 	vernum_mask = cpu_to_be16(XFS_SB_VERSION_ATTRBIT |
222 				  XFS_SB_VERSION_NLINKBIT |
223 				  XFS_SB_VERSION_QUOTABIT);
224 	if ((sb->sb_versionnum & vernum_mask) !=
225 	    (cpu_to_be16(mp->m_sb.sb_versionnum) & vernum_mask))
226 		xchk_block_set_preen(sc, bp);
227 
228 	if (sb->sb_sectsize != cpu_to_be16(mp->m_sb.sb_sectsize))
229 		xchk_block_set_corrupt(sc, bp);
230 
231 	if (sb->sb_inodesize != cpu_to_be16(mp->m_sb.sb_inodesize))
232 		xchk_block_set_corrupt(sc, bp);
233 
234 	if (sb->sb_inopblock != cpu_to_be16(mp->m_sb.sb_inopblock))
235 		xchk_block_set_corrupt(sc, bp);
236 
237 	if (memcmp(sb->sb_fname, mp->m_sb.sb_fname, sizeof(sb->sb_fname)))
238 		xchk_block_set_preen(sc, bp);
239 
240 	if (sb->sb_blocklog != mp->m_sb.sb_blocklog)
241 		xchk_block_set_corrupt(sc, bp);
242 
243 	if (sb->sb_sectlog != mp->m_sb.sb_sectlog)
244 		xchk_block_set_corrupt(sc, bp);
245 
246 	if (sb->sb_inodelog != mp->m_sb.sb_inodelog)
247 		xchk_block_set_corrupt(sc, bp);
248 
249 	if (sb->sb_inopblog != mp->m_sb.sb_inopblog)
250 		xchk_block_set_corrupt(sc, bp);
251 
252 	if (sb->sb_agblklog != mp->m_sb.sb_agblklog)
253 		xchk_block_set_corrupt(sc, bp);
254 
255 	if (sb->sb_rextslog != mp->m_sb.sb_rextslog)
256 		xchk_block_set_corrupt(sc, bp);
257 
258 	if (sb->sb_imax_pct != mp->m_sb.sb_imax_pct)
259 		xchk_block_set_preen(sc, bp);
260 
261 	/*
262 	 * Skip the summary counters since we track them in memory anyway.
263 	 * sb_icount, sb_ifree, sb_fdblocks, sb_frexents
264 	 */
265 
266 	if (xfs_has_metadir(mp)) {
267 		if (sb->sb_uquotino != cpu_to_be64(0))
268 			xchk_block_set_corrupt(sc, bp);
269 
270 		if (sb->sb_gquotino != cpu_to_be64(0))
271 			xchk_block_set_corrupt(sc, bp);
272 	} else {
273 		if (sb->sb_uquotino != cpu_to_be64(mp->m_sb.sb_uquotino))
274 			xchk_block_set_preen(sc, bp);
275 
276 		if (sb->sb_gquotino != cpu_to_be64(mp->m_sb.sb_gquotino))
277 			xchk_block_set_preen(sc, bp);
278 	}
279 
280 	/*
281 	 * Skip the quota flags since repair will force quotacheck.
282 	 * sb_qflags
283 	 */
284 
285 	if (sb->sb_flags != mp->m_sb.sb_flags)
286 		xchk_block_set_corrupt(sc, bp);
287 
288 	if (sb->sb_shared_vn != mp->m_sb.sb_shared_vn)
289 		xchk_block_set_corrupt(sc, bp);
290 
291 	if (sb->sb_inoalignmt != cpu_to_be32(mp->m_sb.sb_inoalignmt))
292 		xchk_block_set_corrupt(sc, bp);
293 
294 	if (sb->sb_unit != cpu_to_be32(mp->m_sb.sb_unit))
295 		xchk_block_set_preen(sc, bp);
296 
297 	if (sb->sb_width != cpu_to_be32(mp->m_sb.sb_width))
298 		xchk_block_set_preen(sc, bp);
299 
300 	if (sb->sb_dirblklog != mp->m_sb.sb_dirblklog)
301 		xchk_block_set_corrupt(sc, bp);
302 
303 	if (sb->sb_logsectlog != mp->m_sb.sb_logsectlog)
304 		xchk_block_set_corrupt(sc, bp);
305 
306 	if (sb->sb_logsectsize != cpu_to_be16(mp->m_sb.sb_logsectsize))
307 		xchk_block_set_corrupt(sc, bp);
308 
309 	if (sb->sb_logsunit != cpu_to_be32(mp->m_sb.sb_logsunit))
310 		xchk_block_set_corrupt(sc, bp);
311 
312 	/* Do we see any invalid bits in sb_features2? */
313 	if (!xfs_sb_version_hasmorebits(&mp->m_sb)) {
314 		if (sb->sb_features2 != 0)
315 			xchk_block_set_corrupt(sc, bp);
316 	} else {
317 		v2_ok = XFS_SB_VERSION2_OKBITS;
318 		if (xfs_sb_is_v5(&mp->m_sb))
319 			v2_ok |= XFS_SB_VERSION2_CRCBIT;
320 
321 		if (!!(sb->sb_features2 & cpu_to_be32(~v2_ok)))
322 			xchk_block_set_corrupt(sc, bp);
323 
324 		if (sb->sb_features2 != sb->sb_bad_features2)
325 			xchk_block_set_preen(sc, bp);
326 	}
327 
328 	/* Check sb_features2 flags that are set at mkfs time. */
329 	features_mask = cpu_to_be32(XFS_SB_VERSION2_LAZYSBCOUNTBIT |
330 				    XFS_SB_VERSION2_PROJID32BIT |
331 				    XFS_SB_VERSION2_CRCBIT |
332 				    XFS_SB_VERSION2_FTYPE);
333 	if ((sb->sb_features2 & features_mask) !=
334 	    (cpu_to_be32(mp->m_sb.sb_features2) & features_mask))
335 		xchk_block_set_corrupt(sc, bp);
336 
337 	/* Check sb_features2 flags that can be set after mkfs time. */
338 	features_mask = cpu_to_be32(XFS_SB_VERSION2_ATTR2BIT);
339 	if ((sb->sb_features2 & features_mask) !=
340 	    (cpu_to_be32(mp->m_sb.sb_features2) & features_mask))
341 		xchk_block_set_preen(sc, bp);
342 
343 	if (!xfs_has_crc(mp)) {
344 		/* all v5 fields must be zero */
345 		if (memchr_inv(&sb->sb_features_compat, 0,
346 				sizeof(struct xfs_dsb) -
347 				offsetof(struct xfs_dsb, sb_features_compat)))
348 			xchk_block_set_corrupt(sc, bp);
349 	} else {
350 		/* compat features must match */
351 		if (sb->sb_features_compat !=
352 				cpu_to_be32(mp->m_sb.sb_features_compat))
353 			xchk_block_set_corrupt(sc, bp);
354 
355 		/* ro compat features must match */
356 		if (sb->sb_features_ro_compat !=
357 				cpu_to_be32(mp->m_sb.sb_features_ro_compat))
358 			xchk_block_set_corrupt(sc, bp);
359 
360 		/*
361 		 * NEEDSREPAIR is ignored on a secondary super, so we should
362 		 * clear it when we find it, though it's not a corruption.
363 		 */
364 		features_mask = cpu_to_be32(XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR);
365 		if ((cpu_to_be32(mp->m_sb.sb_features_incompat) ^
366 				sb->sb_features_incompat) & features_mask)
367 			xchk_block_set_preen(sc, bp);
368 
369 		/* all other incompat features must match */
370 		if ((cpu_to_be32(mp->m_sb.sb_features_incompat) ^
371 				sb->sb_features_incompat) & ~features_mask)
372 			xchk_block_set_corrupt(sc, bp);
373 
374 		/*
375 		 * log incompat features protect newer log record types from
376 		 * older log recovery code.  Log recovery doesn't check the
377 		 * secondary supers, so we can clear these if needed.
378 		 */
379 		if (sb->sb_features_log_incompat)
380 			xchk_block_set_preen(sc, bp);
381 
382 		/* Don't care about sb_crc */
383 
384 		if (sb->sb_spino_align != cpu_to_be32(mp->m_sb.sb_spino_align))
385 			xchk_block_set_corrupt(sc, bp);
386 
387 		if (xfs_has_metadir(mp)) {
388 			if (sb->sb_pquotino != cpu_to_be64(0))
389 				xchk_block_set_corrupt(sc, bp);
390 		} else {
391 			if (sb->sb_pquotino != cpu_to_be64(mp->m_sb.sb_pquotino))
392 				xchk_block_set_preen(sc, bp);
393 		}
394 
395 		/* Don't care about sb_lsn */
396 	}
397 
398 	if (xfs_has_metauuid(mp)) {
399 		/* The metadata UUID must be the same for all supers */
400 		if (!uuid_equal(&sb->sb_meta_uuid, &mp->m_sb.sb_meta_uuid))
401 			xchk_block_set_corrupt(sc, bp);
402 	}
403 
404 	if (xfs_has_metadir(mp)) {
405 		if (sb->sb_metadirino != cpu_to_be64(mp->m_sb.sb_metadirino))
406 			xchk_block_set_preen(sc, bp);
407 
408 		if (sb->sb_rgcount != cpu_to_be32(mp->m_sb.sb_rgcount))
409 			xchk_block_set_corrupt(sc, bp);
410 
411 		if (sb->sb_rgextents != cpu_to_be32(mp->m_sb.sb_rgextents))
412 			xchk_block_set_corrupt(sc, bp);
413 
414 		if (sb->sb_rgblklog != mp->m_sb.sb_rgblklog)
415 			xchk_block_set_corrupt(sc, bp);
416 
417 		if (memchr_inv(sb->sb_pad, 0, sizeof(sb->sb_pad)))
418 			xchk_block_set_corrupt(sc, bp);
419 	}
420 
421 	if (xfs_has_zoned(mp)) {
422 		if (sb->sb_rtstart != cpu_to_be64(mp->m_sb.sb_rtstart))
423 			xchk_block_set_corrupt(sc, bp);
424 		if (sb->sb_rtreserved != cpu_to_be64(mp->m_sb.sb_rtreserved))
425 			xchk_block_set_corrupt(sc, bp);
426 	}
427 
428 	/* Everything else must be zero. */
429 	sblen = xchk_superblock_ondisk_size(mp);
430 	if (memchr_inv((char *)sb + sblen, 0, BBTOB(bp->b_length) - sblen))
431 		xchk_block_set_corrupt(sc, bp);
432 
433 	xchk_superblock_xref(sc, bp);
434 out_pag:
435 	xfs_perag_put(pag);
436 	return error;
437 }
438 
439 /* AGF */
440 
441 /* Tally freespace record lengths. */
442 STATIC int
xchk_agf_record_bno_lengths(struct xfs_btree_cur * cur,const struct xfs_alloc_rec_incore * rec,void * priv)443 xchk_agf_record_bno_lengths(
444 	struct xfs_btree_cur		*cur,
445 	const struct xfs_alloc_rec_incore *rec,
446 	void				*priv)
447 {
448 	xfs_extlen_t			*blocks = priv;
449 
450 	(*blocks) += rec->ar_blockcount;
451 	return 0;
452 }
453 
454 /* Check agf_freeblks */
455 static inline void
xchk_agf_xref_freeblks(struct xfs_scrub * sc)456 xchk_agf_xref_freeblks(
457 	struct xfs_scrub	*sc)
458 {
459 	struct xfs_agf		*agf = sc->sa.agf_bp->b_addr;
460 	xfs_extlen_t		blocks = 0;
461 	int			error;
462 
463 	if (!sc->sa.bno_cur)
464 		return;
465 
466 	error = xfs_alloc_query_all(sc->sa.bno_cur,
467 			xchk_agf_record_bno_lengths, &blocks);
468 	if (!xchk_should_check_xref(sc, &error, &sc->sa.bno_cur))
469 		return;
470 	if (blocks != be32_to_cpu(agf->agf_freeblks))
471 		xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp);
472 }
473 
474 /* Cross reference the AGF with the cntbt (freespace by length btree) */
475 static inline void
xchk_agf_xref_cntbt(struct xfs_scrub * sc)476 xchk_agf_xref_cntbt(
477 	struct xfs_scrub	*sc)
478 {
479 	struct xfs_agf		*agf = sc->sa.agf_bp->b_addr;
480 	xfs_agblock_t		agbno;
481 	xfs_extlen_t		blocks;
482 	int			have;
483 	int			error;
484 
485 	if (!sc->sa.cnt_cur)
486 		return;
487 
488 	/* Any freespace at all? */
489 	error = xfs_alloc_lookup_le(sc->sa.cnt_cur, 0, -1U, &have);
490 	if (!xchk_should_check_xref(sc, &error, &sc->sa.cnt_cur))
491 		return;
492 	if (!have) {
493 		if (agf->agf_freeblks != cpu_to_be32(0))
494 			xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp);
495 		return;
496 	}
497 
498 	/* Check agf_longest */
499 	error = xfs_alloc_get_rec(sc->sa.cnt_cur, &agbno, &blocks, &have);
500 	if (!xchk_should_check_xref(sc, &error, &sc->sa.cnt_cur))
501 		return;
502 	if (!have || blocks != be32_to_cpu(agf->agf_longest))
503 		xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp);
504 }
505 
506 /* Check the btree block counts in the AGF against the btrees. */
507 STATIC void
xchk_agf_xref_btreeblks(struct xfs_scrub * sc)508 xchk_agf_xref_btreeblks(
509 	struct xfs_scrub	*sc)
510 {
511 	struct xfs_agf		*agf = sc->sa.agf_bp->b_addr;
512 	struct xfs_mount	*mp = sc->mp;
513 	xfs_filblks_t		blocks;
514 	xfs_agblock_t		btreeblks;
515 	int			error;
516 
517 	/* agf_btreeblks didn't exist before lazysbcount */
518 	if (!xfs_has_lazysbcount(sc->mp))
519 		return;
520 
521 	/* Check agf_rmap_blocks; set up for agf_btreeblks check */
522 	if (sc->sa.rmap_cur) {
523 		error = xfs_btree_count_blocks(sc->sa.rmap_cur, &blocks);
524 		if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
525 			return;
526 		btreeblks = blocks - 1;
527 		if (blocks != be32_to_cpu(agf->agf_rmap_blocks))
528 			xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp);
529 	} else {
530 		btreeblks = 0;
531 	}
532 
533 	/*
534 	 * No rmap cursor; we can't xref if we have the rmapbt feature.
535 	 * We also can't do it if we're missing the free space btree cursors.
536 	 */
537 	if ((xfs_has_rmapbt(mp) && !sc->sa.rmap_cur) ||
538 	    !sc->sa.bno_cur || !sc->sa.cnt_cur)
539 		return;
540 
541 	/* Check agf_btreeblks */
542 	error = xfs_btree_count_blocks(sc->sa.bno_cur, &blocks);
543 	if (!xchk_should_check_xref(sc, &error, &sc->sa.bno_cur))
544 		return;
545 	btreeblks += blocks - 1;
546 
547 	error = xfs_btree_count_blocks(sc->sa.cnt_cur, &blocks);
548 	if (!xchk_should_check_xref(sc, &error, &sc->sa.cnt_cur))
549 		return;
550 	btreeblks += blocks - 1;
551 
552 	if (btreeblks != be32_to_cpu(agf->agf_btreeblks))
553 		xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp);
554 }
555 
556 /* Check agf_refcount_blocks against tree size */
557 static inline void
xchk_agf_xref_refcblks(struct xfs_scrub * sc)558 xchk_agf_xref_refcblks(
559 	struct xfs_scrub	*sc)
560 {
561 	struct xfs_agf		*agf = sc->sa.agf_bp->b_addr;
562 	xfs_filblks_t		blocks;
563 	int			error;
564 
565 	if (!sc->sa.refc_cur)
566 		return;
567 
568 	error = xfs_btree_count_blocks(sc->sa.refc_cur, &blocks);
569 	if (!xchk_should_check_xref(sc, &error, &sc->sa.refc_cur))
570 		return;
571 	if (blocks != be32_to_cpu(agf->agf_refcount_blocks))
572 		xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp);
573 }
574 
575 /* Cross-reference with the other btrees. */
576 STATIC void
xchk_agf_xref(struct xfs_scrub * sc)577 xchk_agf_xref(
578 	struct xfs_scrub	*sc)
579 {
580 	struct xfs_mount	*mp = sc->mp;
581 	xfs_agblock_t		agbno;
582 
583 	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
584 		return;
585 
586 	agbno = XFS_AGF_BLOCK(mp);
587 
588 	xchk_ag_btcur_init(sc, &sc->sa);
589 
590 	xchk_xref_is_used_space(sc, agbno, 1);
591 	xchk_agf_xref_freeblks(sc);
592 	xchk_agf_xref_cntbt(sc);
593 	xchk_xref_is_not_inode_chunk(sc, agbno, 1);
594 	xchk_xref_is_only_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
595 	xchk_agf_xref_btreeblks(sc);
596 	xchk_xref_is_not_shared(sc, agbno, 1);
597 	xchk_xref_is_not_cow_staging(sc, agbno, 1);
598 	xchk_agf_xref_refcblks(sc);
599 
600 	/* scrub teardown will take care of sc->sa for us */
601 }
602 
603 /* Scrub the AGF. */
604 int
xchk_agf(struct xfs_scrub * sc)605 xchk_agf(
606 	struct xfs_scrub	*sc)
607 {
608 	struct xfs_mount	*mp = sc->mp;
609 	struct xfs_agf		*agf;
610 	struct xfs_perag	*pag;
611 	xfs_agnumber_t		agno = sc->sm->sm_agno;
612 	xfs_agblock_t		agbno;
613 	xfs_agblock_t		eoag;
614 	xfs_agblock_t		agfl_first;
615 	xfs_agblock_t		agfl_last;
616 	xfs_agblock_t		agfl_count;
617 	xfs_agblock_t		fl_count;
618 	int			level;
619 	int			error = 0;
620 
621 	error = xchk_ag_read_headers(sc, agno, &sc->sa);
622 	if (!xchk_process_error(sc, agno, XFS_AGF_BLOCK(sc->mp), &error))
623 		goto out;
624 	xchk_buffer_recheck(sc, sc->sa.agf_bp);
625 
626 	agf = sc->sa.agf_bp->b_addr;
627 	pag = sc->sa.pag;
628 
629 	/* Check the AG length */
630 	eoag = be32_to_cpu(agf->agf_length);
631 	if (eoag != pag_group(pag)->xg_block_count)
632 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
633 
634 	/* Check the AGF btree roots and levels */
635 	agbno = be32_to_cpu(agf->agf_bno_root);
636 	if (!xfs_verify_agbno(pag, agbno))
637 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
638 
639 	agbno = be32_to_cpu(agf->agf_cnt_root);
640 	if (!xfs_verify_agbno(pag, agbno))
641 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
642 
643 	level = be32_to_cpu(agf->agf_bno_level);
644 	if (level <= 0 || level > mp->m_alloc_maxlevels)
645 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
646 
647 	level = be32_to_cpu(agf->agf_cnt_level);
648 	if (level <= 0 || level > mp->m_alloc_maxlevels)
649 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
650 
651 	if (xfs_has_rmapbt(mp)) {
652 		agbno = be32_to_cpu(agf->agf_rmap_root);
653 		if (!xfs_verify_agbno(pag, agbno))
654 			xchk_block_set_corrupt(sc, sc->sa.agf_bp);
655 
656 		level = be32_to_cpu(agf->agf_rmap_level);
657 		if (level <= 0 || level > mp->m_rmap_maxlevels)
658 			xchk_block_set_corrupt(sc, sc->sa.agf_bp);
659 	}
660 
661 	if (xfs_has_reflink(mp)) {
662 		agbno = be32_to_cpu(agf->agf_refcount_root);
663 		if (!xfs_verify_agbno(pag, agbno))
664 			xchk_block_set_corrupt(sc, sc->sa.agf_bp);
665 
666 		level = be32_to_cpu(agf->agf_refcount_level);
667 		if (level <= 0 || level > mp->m_refc_maxlevels)
668 			xchk_block_set_corrupt(sc, sc->sa.agf_bp);
669 	}
670 
671 	/* Check the AGFL counters */
672 	agfl_first = be32_to_cpu(agf->agf_flfirst);
673 	agfl_last = be32_to_cpu(agf->agf_fllast);
674 	agfl_count = be32_to_cpu(agf->agf_flcount);
675 	if (agfl_last > agfl_first)
676 		fl_count = agfl_last - agfl_first + 1;
677 	else
678 		fl_count = xfs_agfl_size(mp) - agfl_first + agfl_last + 1;
679 	if (agfl_count != 0 && fl_count != agfl_count)
680 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
681 
682 	/* Do the incore counters match? */
683 	if (pag->pagf_freeblks != be32_to_cpu(agf->agf_freeblks))
684 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
685 	if (pag->pagf_flcount != be32_to_cpu(agf->agf_flcount))
686 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
687 	if (xfs_has_lazysbcount(sc->mp) &&
688 	    pag->pagf_btreeblks != be32_to_cpu(agf->agf_btreeblks))
689 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
690 
691 	xchk_agf_xref(sc);
692 out:
693 	return error;
694 }
695 
696 /* AGFL */
697 
698 struct xchk_agfl_info {
699 	/* Number of AGFL entries that the AGF claims are in use. */
700 	unsigned int		agflcount;
701 
702 	/* Number of AGFL entries that we found. */
703 	unsigned int		nr_entries;
704 
705 	/* Buffer to hold AGFL entries for extent checking. */
706 	xfs_agblock_t		*entries;
707 
708 	struct xfs_buf		*agfl_bp;
709 	struct xfs_scrub	*sc;
710 };
711 
712 /* Cross-reference with the other btrees. */
713 STATIC void
xchk_agfl_block_xref(struct xfs_scrub * sc,xfs_agblock_t agbno)714 xchk_agfl_block_xref(
715 	struct xfs_scrub	*sc,
716 	xfs_agblock_t		agbno)
717 {
718 	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
719 		return;
720 
721 	xchk_xref_is_used_space(sc, agbno, 1);
722 	xchk_xref_is_not_inode_chunk(sc, agbno, 1);
723 	xchk_xref_is_only_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_AG);
724 	xchk_xref_is_not_shared(sc, agbno, 1);
725 	xchk_xref_is_not_cow_staging(sc, agbno, 1);
726 }
727 
728 /* Scrub an AGFL block. */
729 STATIC int
xchk_agfl_block(struct xfs_mount * mp,xfs_agblock_t agbno,void * priv)730 xchk_agfl_block(
731 	struct xfs_mount	*mp,
732 	xfs_agblock_t		agbno,
733 	void			*priv)
734 {
735 	struct xchk_agfl_info	*sai = priv;
736 	struct xfs_scrub	*sc = sai->sc;
737 
738 	if (xfs_verify_agbno(sc->sa.pag, agbno) &&
739 	    sai->nr_entries < sai->agflcount)
740 		sai->entries[sai->nr_entries++] = agbno;
741 	else
742 		xchk_block_set_corrupt(sc, sai->agfl_bp);
743 
744 	xchk_agfl_block_xref(sc, agbno);
745 
746 	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
747 		return -ECANCELED;
748 
749 	return 0;
750 }
751 
752 static int
xchk_agblock_cmp(const void * pa,const void * pb)753 xchk_agblock_cmp(
754 	const void		*pa,
755 	const void		*pb)
756 {
757 	const xfs_agblock_t	*a = pa;
758 	const xfs_agblock_t	*b = pb;
759 
760 	return (int)*a - (int)*b;
761 }
762 
763 /* Cross-reference with the other btrees. */
764 STATIC void
xchk_agfl_xref(struct xfs_scrub * sc)765 xchk_agfl_xref(
766 	struct xfs_scrub	*sc)
767 {
768 	struct xfs_mount	*mp = sc->mp;
769 	xfs_agblock_t		agbno;
770 
771 	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
772 		return;
773 
774 	agbno = XFS_AGFL_BLOCK(mp);
775 
776 	xchk_ag_btcur_init(sc, &sc->sa);
777 
778 	xchk_xref_is_used_space(sc, agbno, 1);
779 	xchk_xref_is_not_inode_chunk(sc, agbno, 1);
780 	xchk_xref_is_only_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
781 	xchk_xref_is_not_shared(sc, agbno, 1);
782 	xchk_xref_is_not_cow_staging(sc, agbno, 1);
783 
784 	/*
785 	 * Scrub teardown will take care of sc->sa for us.  Leave sc->sa
786 	 * active so that the agfl block xref can use it too.
787 	 */
788 }
789 
790 /* Scrub the AGFL. */
791 int
xchk_agfl(struct xfs_scrub * sc)792 xchk_agfl(
793 	struct xfs_scrub	*sc)
794 {
795 	struct xchk_agfl_info	sai = {
796 		.sc		= sc,
797 	};
798 	struct xfs_agf		*agf;
799 	xfs_agnumber_t		agno = sc->sm->sm_agno;
800 	unsigned int		i;
801 	int			error;
802 
803 	/* Lock the AGF and AGI so that nobody can touch this AG. */
804 	error = xchk_ag_read_headers(sc, agno, &sc->sa);
805 	if (!xchk_process_error(sc, agno, XFS_AGFL_BLOCK(sc->mp), &error))
806 		return error;
807 	if (!sc->sa.agf_bp)
808 		return -EFSCORRUPTED;
809 
810 	/* Try to read the AGFL, and verify its structure if we get it. */
811 	error = xfs_alloc_read_agfl(sc->sa.pag, sc->tp, &sai.agfl_bp);
812 	if (!xchk_process_error(sc, agno, XFS_AGFL_BLOCK(sc->mp), &error))
813 		return error;
814 	xchk_buffer_recheck(sc, sai.agfl_bp);
815 
816 	xchk_agfl_xref(sc);
817 
818 	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
819 		goto out;
820 
821 	/* Allocate buffer to ensure uniqueness of AGFL entries. */
822 	agf = sc->sa.agf_bp->b_addr;
823 	sai.agflcount = be32_to_cpu(agf->agf_flcount);
824 	if (sai.agflcount > xfs_agfl_size(sc->mp)) {
825 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
826 		goto out;
827 	}
828 	sai.entries = kvzalloc_objs(xfs_agblock_t, sai.agflcount,
829 				    XCHK_GFP_FLAGS);
830 	if (!sai.entries) {
831 		error = -ENOMEM;
832 		goto out;
833 	}
834 
835 	/* Check the blocks in the AGFL. */
836 	error = xfs_agfl_walk(sc->mp, sc->sa.agf_bp->b_addr, sai.agfl_bp,
837 			xchk_agfl_block, &sai);
838 	if (error == -ECANCELED) {
839 		error = 0;
840 		goto out_free;
841 	}
842 	if (error)
843 		goto out_free;
844 
845 	if (sai.agflcount != sai.nr_entries) {
846 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
847 		goto out_free;
848 	}
849 
850 	/* Sort entries, check for duplicates. */
851 	sort(sai.entries, sai.nr_entries, sizeof(sai.entries[0]),
852 			xchk_agblock_cmp, NULL);
853 	for (i = 1; i < sai.nr_entries; i++) {
854 		if (sai.entries[i] == sai.entries[i - 1]) {
855 			xchk_block_set_corrupt(sc, sc->sa.agf_bp);
856 			break;
857 		}
858 	}
859 
860 out_free:
861 	kvfree(sai.entries);
862 out:
863 	return error;
864 }
865 
866 /* AGI */
867 
868 /* Check agi_count/agi_freecount */
869 static inline void
xchk_agi_xref_icounts(struct xfs_scrub * sc)870 xchk_agi_xref_icounts(
871 	struct xfs_scrub	*sc)
872 {
873 	struct xfs_agi		*agi = sc->sa.agi_bp->b_addr;
874 	xfs_agino_t		icount;
875 	xfs_agino_t		freecount;
876 	int			error;
877 
878 	if (!sc->sa.ino_cur)
879 		return;
880 
881 	error = xfs_ialloc_count_inodes(sc->sa.ino_cur, &icount, &freecount);
882 	if (!xchk_should_check_xref(sc, &error, &sc->sa.ino_cur))
883 		return;
884 	if (be32_to_cpu(agi->agi_count) != icount ||
885 	    be32_to_cpu(agi->agi_freecount) != freecount)
886 		xchk_block_xref_set_corrupt(sc, sc->sa.agi_bp);
887 }
888 
889 /* Check agi_[fi]blocks against tree size */
890 static inline void
xchk_agi_xref_fiblocks(struct xfs_scrub * sc)891 xchk_agi_xref_fiblocks(
892 	struct xfs_scrub	*sc)
893 {
894 	struct xfs_agi		*agi = sc->sa.agi_bp->b_addr;
895 	xfs_filblks_t		blocks;
896 	int			error = 0;
897 
898 	if (!xfs_has_inobtcounts(sc->mp))
899 		return;
900 
901 	if (sc->sa.ino_cur) {
902 		error = xfs_btree_count_blocks(sc->sa.ino_cur, &blocks);
903 		if (!xchk_should_check_xref(sc, &error, &sc->sa.ino_cur))
904 			return;
905 		if (blocks != be32_to_cpu(agi->agi_iblocks))
906 			xchk_block_xref_set_corrupt(sc, sc->sa.agi_bp);
907 	}
908 
909 	if (sc->sa.fino_cur) {
910 		error = xfs_btree_count_blocks(sc->sa.fino_cur, &blocks);
911 		if (!xchk_should_check_xref(sc, &error, &sc->sa.fino_cur))
912 			return;
913 		if (blocks != be32_to_cpu(agi->agi_fblocks))
914 			xchk_block_xref_set_corrupt(sc, sc->sa.agi_bp);
915 	}
916 }
917 
918 /* Cross-reference with the other btrees. */
919 STATIC void
xchk_agi_xref(struct xfs_scrub * sc)920 xchk_agi_xref(
921 	struct xfs_scrub	*sc)
922 {
923 	struct xfs_mount	*mp = sc->mp;
924 	xfs_agblock_t		agbno;
925 
926 	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
927 		return;
928 
929 	agbno = XFS_AGI_BLOCK(mp);
930 
931 	xchk_ag_btcur_init(sc, &sc->sa);
932 
933 	xchk_xref_is_used_space(sc, agbno, 1);
934 	xchk_xref_is_not_inode_chunk(sc, agbno, 1);
935 	xchk_agi_xref_icounts(sc);
936 	xchk_xref_is_only_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
937 	xchk_xref_is_not_shared(sc, agbno, 1);
938 	xchk_xref_is_not_cow_staging(sc, agbno, 1);
939 	xchk_agi_xref_fiblocks(sc);
940 
941 	/* scrub teardown will take care of sc->sa for us */
942 }
943 
944 /*
945  * Walk the incore unlinked list for a particular AGI bucket to construct
946  * the unlinked inode bitmap for later reconstruction of the unlinked list.
947  * Returns 1 if we should keep checking, 0 to stop checking, or a negative
948  * errno.
949  */
950 static int
xchk_iunlink_bucket(struct xfs_scrub * sc,unsigned int bucket,xfs_agino_t agino)951 xchk_iunlink_bucket(
952 	struct xfs_scrub		*sc,
953 	unsigned int			bucket,
954 	xfs_agino_t			agino)
955 {
956 	struct xagino_bitmap		seen;
957 	int				ret;
958 
959 	xagino_bitmap_init(&seen);
960 
961 	while (agino != NULLAGINO) {
962 		struct xfs_inode	*ip;
963 		unsigned int		len = 1;
964 
965 		if (agino % XFS_AGI_UNLINKED_BUCKETS != bucket) {
966 			xchk_block_set_corrupt(sc, sc->sa.agi_bp);
967 			goto bad;
968 		}
969 
970 		if (xagino_bitmap_test(&seen, agino, &len)) {
971 			xchk_block_set_corrupt(sc, sc->sa.agi_bp);
972 			goto bad;
973 		}
974 
975 		ip = xfs_iunlink_lookup(sc->sa.pag, agino);
976 		if (!ip) {
977 			xchk_block_set_corrupt(sc, sc->sa.agi_bp);
978 			goto bad;
979 		}
980 
981 		if (!xfs_inode_on_unlinked_list(ip)) {
982 			xchk_block_set_corrupt(sc, sc->sa.agi_bp);
983 			goto bad;
984 		}
985 
986 		ret = xagino_bitmap_set(&seen, agino, 1);
987 		if (ret)
988 			goto out_bitmap;
989 
990 		agino = ip->i_next_unlinked;
991 	}
992 	ret = 1;
993 
994 out_bitmap:
995 	xagino_bitmap_destroy(&seen);
996 	return ret;
997 bad:
998 	ret = 0;
999 	goto out_bitmap;
1000 }
1001 
1002 /*
1003  * Check the unlinked buckets for links to bad inodes.  We hold the AGI, so
1004  * there cannot be any threads updating unlinked list pointers in this AG.
1005  */
1006 STATIC int
xchk_iunlink(struct xfs_scrub * sc,struct xfs_agi * agi)1007 xchk_iunlink(
1008 	struct xfs_scrub	*sc,
1009 	struct xfs_agi		*agi)
1010 {
1011 	unsigned int		i;
1012 
1013 	for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
1014 		int		ret;
1015 
1016 		ret = xchk_iunlink_bucket(sc, i,
1017 				be32_to_cpu(agi->agi_unlinked[i]));
1018 		if (ret < 1)
1019 			return ret;
1020 	}
1021 
1022 	return 0;
1023 }
1024 
1025 /* Scrub the AGI. */
1026 int
xchk_agi(struct xfs_scrub * sc)1027 xchk_agi(
1028 	struct xfs_scrub	*sc)
1029 {
1030 	struct xfs_mount	*mp = sc->mp;
1031 	struct xfs_agi		*agi;
1032 	struct xfs_perag	*pag;
1033 	struct xfs_ino_geometry	*igeo = M_IGEO(sc->mp);
1034 	xfs_agnumber_t		agno = sc->sm->sm_agno;
1035 	xfs_agblock_t		agbno;
1036 	xfs_agblock_t		eoag;
1037 	xfs_agino_t		agino;
1038 	xfs_agino_t		first_agino;
1039 	xfs_agino_t		last_agino;
1040 	xfs_agino_t		icount;
1041 	int			i;
1042 	int			level;
1043 	int			error = 0;
1044 
1045 	error = xchk_ag_read_headers(sc, agno, &sc->sa);
1046 	if (!xchk_process_error(sc, agno, XFS_AGI_BLOCK(sc->mp), &error))
1047 		goto out;
1048 	xchk_buffer_recheck(sc, sc->sa.agi_bp);
1049 
1050 	agi = sc->sa.agi_bp->b_addr;
1051 	pag = sc->sa.pag;
1052 
1053 	/* Check the AG length */
1054 	eoag = be32_to_cpu(agi->agi_length);
1055 	if (eoag != pag_group(pag)->xg_block_count)
1056 		xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1057 
1058 	/* Check btree roots and levels */
1059 	agbno = be32_to_cpu(agi->agi_root);
1060 	if (!xfs_verify_agbno(pag, agbno))
1061 		xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1062 
1063 	level = be32_to_cpu(agi->agi_level);
1064 	if (level <= 0 || level > igeo->inobt_maxlevels)
1065 		xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1066 
1067 	if (xfs_has_finobt(mp)) {
1068 		agbno = be32_to_cpu(agi->agi_free_root);
1069 		if (!xfs_verify_agbno(pag, agbno))
1070 			xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1071 
1072 		level = be32_to_cpu(agi->agi_free_level);
1073 		if (level <= 0 || level > igeo->inobt_maxlevels)
1074 			xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1075 	}
1076 
1077 	/* Check inode counters */
1078 	xfs_agino_range(mp, agno, &first_agino, &last_agino);
1079 	icount = be32_to_cpu(agi->agi_count);
1080 	if (icount > last_agino - first_agino + 1 ||
1081 	    icount < be32_to_cpu(agi->agi_freecount))
1082 		xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1083 
1084 	/* Check inode pointers */
1085 	agino = be32_to_cpu(agi->agi_newino);
1086 	if (!xfs_verify_agino_or_null(pag, agino))
1087 		xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1088 
1089 	agino = be32_to_cpu(agi->agi_dirino);
1090 	if (!xfs_verify_agino_or_null(pag, agino))
1091 		xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1092 
1093 	/* Check unlinked inode buckets */
1094 	for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
1095 		agino = be32_to_cpu(agi->agi_unlinked[i]);
1096 		if (!xfs_verify_agino_or_null(pag, agino))
1097 			xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1098 	}
1099 
1100 	if (agi->agi_pad32 != cpu_to_be32(0))
1101 		xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1102 
1103 	/* Do the incore counters match? */
1104 	if (pag->pagi_count != be32_to_cpu(agi->agi_count))
1105 		xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1106 	if (pag->pagi_freecount != be32_to_cpu(agi->agi_freecount))
1107 		xchk_block_set_corrupt(sc, sc->sa.agi_bp);
1108 
1109 	error = xchk_iunlink(sc, agi);
1110 	if (error)
1111 		goto out;
1112 
1113 	xchk_agi_xref(sc);
1114 out:
1115 	return error;
1116 }
1117