fs/xfs/scrub/btree.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/btree.c
Extension
.c
Size
21263 bytes
Lines
808
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

struct check_owner {
	struct list_head	list;
	xfs_daddr_t		daddr;
	int			level;
};

/*
 * Make sure this btree block isn't in the free list and that there's
 * an rmap record for it.
 */
STATIC int
xchk_btree_check_block_owner(
	struct xchk_btree	*bs,
	int			level,
	xfs_daddr_t		daddr)
{
	xfs_agnumber_t		agno;
	xfs_agblock_t		agbno;
	bool			is_bnobt, is_rmapbt;
	bool			init_sa;
	int			error = 0;

	if (!bs->cur)
		return 0;

	is_bnobt = xfs_btree_is_bno(bs->cur->bc_ops);
	is_rmapbt = xfs_btree_is_rmap(bs->cur->bc_ops);
	agno = xfs_daddr_to_agno(bs->cur->bc_mp, daddr);
	agbno = xfs_daddr_to_agbno(bs->cur->bc_mp, daddr);

	/*
	 * If the btree being examined is not itself a per-AG btree, initialize
	 * sc->sa so that we can check for the presence of an ownership record
	 * in the rmap btree for the AG containing the block.
	 */
	init_sa = bs->cur->bc_ops->type != XFS_BTREE_TYPE_AG;
	if (init_sa) {
		error = xchk_ag_init_existing(bs->sc, agno, &bs->sc->sa);
		if (!xchk_btree_xref_process_error(bs->sc, bs->cur,
				level, &error))
			goto out_free;
	}

	xchk_xref_is_used_space(bs->sc, agbno, 1);
	/*
	 * The bnobt scrubber aliases bs->cur to bs->sc->sa.bno_cur, so we
	 * have to nullify it (to shut down further block owner checks) if
	 * self-xref encounters problems.
	 */
	if (!bs->sc->sa.bno_cur && is_bnobt)
		bs->cur = NULL;

	xchk_xref_is_only_owned_by(bs->sc, agbno, 1, bs->oinfo);
	if (!bs->sc->sa.rmap_cur && is_rmapbt)
		bs->cur = NULL;

out_free:
	if (init_sa)
		xchk_ag_free(bs->sc, &bs->sc->sa);

	return error;
}

/* Check the owner of a btree block. */
STATIC int
xchk_btree_check_owner(
	struct xchk_btree	*bs,
	int			level,
	struct xfs_buf		*bp)
{
	struct xfs_btree_cur	*cur = bs->cur;

	/*
	 * In theory, xfs_btree_get_block should only give us a null buffer
	 * pointer for the root of a root-in-inode btree type, but we need
	 * to check defensively here in case the cursor state is also screwed
	 * up.
	 */
	if (bp == NULL) {
		if (cur->bc_ops->type != XFS_BTREE_TYPE_INODE)
			xchk_btree_set_corrupt(bs->sc, bs->cur, level);
		return 0;
	}

	/*
	 * We want to cross-reference each btree block with the bnobt
	 * and the rmapbt.  We cannot cross-reference the bnobt or
	 * rmapbt while scanning the bnobt or rmapbt, respectively,
	 * because we cannot alter the cursor and we'd prefer not to
	 * duplicate cursors.  Therefore, save the buffer daddr for

Annotation

Implementation Notes