fs/xfs/scrub/rtbitmap.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/rtbitmap.c
Extension
.c
Size
7561 bytes
Lines
300
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);
			break;
		}

		off += map.br_blockcount;
	}

	return error;
}

/* Scrub this group's realtime bitmap. */
int
xchk_rtbitmap(
	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 xchk_rtbitmap	*rtb = sc->buf;
	xfs_rgblock_t		last_rgbno;
	int			error;

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

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

	/*
	 * Is sb_rbmblocks large enough to handle the current rt volume?  In no
	 * case can we exceed 4bn bitmap blocks since the super field is a u32.
	 */
	if (rtb->rbmblocks > U32_MAX) {
		xchk_ip_set_corrupt(sc, rbmip);
		return 0;
	}
	if (mp->m_sb.sb_rbmblocks != rtb->rbmblocks) {
		xchk_ip_set_corrupt(sc, rbmip);
		return 0;
	}

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

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

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

	error = xchk_rtbitmap_check_extents(sc);
	if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
		return error;

	rtb->next_free_rgbno = 0;
	error = xfs_rtalloc_query_all(rtg, sc->tp, xchk_rtbitmap_rec, rtb);
	if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
		return error;

	/*
	 * Check that the are rmappings for all rt extents between the end of
	 * the last free extent we saw and the last possible extent in the rt
	 * group.
	 */
	last_rgbno = rtg->rtg_extents * mp->m_sb.sb_rextsize - 1;
	if (rtb->next_free_rgbno < last_rgbno)
		xchk_xref_has_rt_owner(sc, rtb->next_free_rgbno,
				last_rgbno - rtb->next_free_rgbno);
	return 0;
}

Annotation

Implementation Notes