fs/xfs/scrub/dabtree.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/dabtree.c
Extension
.c
Size
15091 bytes
Lines
629
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 (level == 0) {
			if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) {
				xchk_da_set_corrupt(ds, level);
				goto out_freebp;
			}
			ds->tree_level = nodehdr.level;
		} else {
			if (ds->tree_level != nodehdr.level) {
				xchk_da_set_corrupt(ds, level);
				goto out_freebp;
			}
		}

		if (xfs_has_crc(ip->i_mount)) {
			struct xfs_da3_node_hdr *nodehdr3 = blk->bp->b_addr;

			if (nodehdr3->__pad32)
				xchk_da_set_preen(ds, level);
		}
		break;
	default:
		xchk_da_set_corrupt(ds, level);
		goto out_freebp;
	}

	fa = xfs_da3_header_check(blk->bp, dargs->owner);
	if (fa) {
		xchk_da_set_corrupt(ds, level);
		goto out_freebp;
	}

	/*
	 * If we've been handed a block that is below the dabtree root, does
	 * its hashval match what the parent block expected to see?
	 */
	if (level > 0) {
		struct xfs_da_node_entry	*key;

		key = xchk_da_btree_node_entry(ds, level - 1);
		if (be32_to_cpu(key->hashval) != blk->hashval) {
			xchk_da_set_corrupt(ds, level);
			goto out_freebp;
		}
	}

out:
	return error;
out_freebp:
	xfs_trans_brelse(dargs->trans, blk->bp);
	blk->bp = NULL;
out_nobuf:
	blk->blkno = 0;
	return error;
}

/* Visit all nodes and leaves of a da btree. */
int
xchk_da_btree(
	struct xfs_scrub		*sc,
	int				whichfork,
	xchk_da_btree_rec_fn		scrub_fn,
	void				*private)
{
	struct xchk_da_btree		*ds;
	struct xfs_mount		*mp = sc->mp;
	struct xfs_da_state_blk		*blks;
	struct xfs_da_node_entry	*key;
	xfs_dablk_t			blkno;
	int				level;
	int				error;

	/* Skip short format data structures; no btree to scan. */
	if (!xfs_ifork_has_extents(xfs_ifork_ptr(sc->ip, whichfork)))
		return 0;

	/* Set up initial da state. */
	ds = kzalloc_obj(struct xchk_da_btree, XCHK_GFP_FLAGS);
	if (!ds)
		return -ENOMEM;
	ds->dargs.dp = sc->ip;
	ds->dargs.whichfork = whichfork;
	ds->dargs.trans = sc->tp;
	ds->dargs.op_flags = XFS_DA_OP_OKNOENT;
	ds->dargs.owner = I_INO(sc->ip);
	ds->state = xfs_da_state_alloc(&ds->dargs);
	ds->sc = sc;
	ds->private = private;
	if (whichfork == XFS_ATTR_FORK) {
		ds->dargs.geo = mp->m_attr_geo;
		ds->lowest = 0;

Annotation

Implementation Notes