File Index
Files and directories
Sign in
FILE

agheader.c

File preview with syntax highlighting.

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