fs/xfs/scrub/rtsummary.c

Source file repositories/reference/linux-study-clean/fs/xfs/scrub/rtsummary.c

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/rtsummary.c
Extension
.c
Size
9277 bytes
Lines
370
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (nmap != 1 || !xfs_bmap_is_written_extent(&map)) {
			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off);
			return 0;
		}

		off += map.br_blockcount;
	}

	for (off = 0; off < endoff; off++) {
		union xfs_suminfo_raw	*ondisk_info;

		/* Read a block's worth of ondisk rtsummary file. */
		error = xfs_rtsummary_read_buf(&rts->args, off);
		if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error))
			return error;

		/* Read a block's worth of computed rtsummary file. */
		error = xfsum_copyout(sc, sumoff, rts->words, mp->m_blockwsize);
		if (error) {
			xfs_rtbuf_cache_relse(&rts->args);
			return error;
		}

		ondisk_info = xfs_rsumblock_infoptr(&rts->args, 0);
		if (memcmp(ondisk_info, rts->words,
					mp->m_blockwsize << XFS_WORDLOG) != 0) {
			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off);
			xfs_rtbuf_cache_relse(&rts->args);
			return error;
		}

		xfs_rtbuf_cache_relse(&rts->args);
		sumoff += mp->m_blockwsize;
	}

	return 0;
}

/* Scrub the realtime summary. */
int
xchk_rtsummary(
	struct xfs_scrub	*sc)
{
	struct xfs_mount	*mp = sc->mp;
	struct xfs_rtgroup	*rtg = sc->sr.rtg;
	struct xfs_inode	*rbmip = rtg_bitmap(rtg);
	struct xfs_inode	*rsumip = rtg_summary(rtg);
	struct xchk_rtsummary	*rts = sc->buf;
	int			error;

	/* Is sb_rextents correct? */
	if (mp->m_sb.sb_rextents != rts->rextents) {
		xchk_ip_set_corrupt(sc, rbmip);
		return 0;
	}

	/* Is m_rsumlevels correct? */
	if (mp->m_rsumlevels != rts->rsumlevels) {
		xchk_ip_set_corrupt(sc, rsumip);
		return 0;
	}

	/* Is m_rsumsize correct? */
	if (mp->m_rsumblocks != rts->rsumblocks) {
		xchk_ip_set_corrupt(sc, rsumip);
		return 0;
	}

	/* The summary file length must be aligned to an fsblock. */
	if (rsumip->i_disk_size & mp->m_blockmask) {
		xchk_ip_set_corrupt(sc, rsumip);
		return 0;
	}

	/*
	 * Is the summary file itself large enough to handle the rt volume?
	 * growfsrt expands the summary file before updating sb_rextents, so
	 * the file can be larger than rsumsize.
	 */
	if (rsumip->i_disk_size < XFS_FSB_TO_B(mp, rts->rsumblocks)) {
		xchk_ip_set_corrupt(sc, rsumip);
		return 0;
	}

	/* Invoke the fork scrubber. */
	error = xchk_metadata_inode_forks(sc);
	if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
		return error;

	/* Construct the new summary file from the rtbitmap. */

Annotation

Implementation Notes