fs/xfs/scrub/newbt.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/newbt.c
Extension
.c
Size
15391 bytes
Lines
612
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 (agno != pag_agno(sc->sa.pag)) {
			ASSERT(agno == pag_agno(sc->sa.pag));
			return -EFSCORRUPTED;
		}

		trace_xrep_newbt_alloc_ag_blocks(sc->sa.pag,
				XFS_FSB_TO_AGBNO(mp, args.fsbno), args.len,
				xnr->oinfo.oi_owner);

		error = xrep_newbt_add_blocks(xnr, sc->sa.pag, &args);
		if (error)
			return error;

		nr_blocks -= args.len;
		xnr->alloc_hint = args.fsbno + args.len;

		error = xrep_defer_finish(sc);
		if (error)
			return error;
	}

	return 0;
}

/* Don't let our allocation hint take us beyond EOFS */
static inline void
xrep_newbt_validate_file_alloc_hint(
	struct xrep_newbt	*xnr)
{
	struct xfs_scrub	*sc = xnr->sc;

	if (xfs_verify_fsbno(sc->mp, xnr->alloc_hint))
		return;

	xnr->alloc_hint = XFS_AGB_TO_FSB(sc->mp, 0, XFS_AGFL_BLOCK(sc->mp) + 1);
}

/* Allocate disk space for our new file-based btree. */
STATIC int
xrep_newbt_alloc_file_blocks(
	struct xrep_newbt	*xnr,
	uint64_t		nr_blocks)
{
	struct xfs_scrub	*sc = xnr->sc;
	struct xfs_mount	*mp = sc->mp;
	int			error = 0;

	ASSERT(xnr->resv != XFS_AG_RESV_METAFILE);

	while (nr_blocks > 0) {
		struct xfs_alloc_arg	args = {
			.tp		= sc->tp,
			.mp		= mp,
			.oinfo		= xnr->oinfo,
			.minlen		= 1,
			.maxlen		= nr_blocks,
			.prod		= 1,
			.resv		= xnr->resv,
		};
		struct xfs_perag	*pag;
		xfs_agnumber_t		agno;

		xrep_newbt_validate_file_alloc_hint(xnr);

		if (xnr->alloc_vextent)
			error = xnr->alloc_vextent(sc, &args, xnr->alloc_hint);
		else
			error = xfs_alloc_vextent_start_ag(&args,
					xnr->alloc_hint);
		if (error)
			return error;
		if (args.fsbno == NULLFSBLOCK)
			return -ENOSPC;

		agno = XFS_FSB_TO_AGNO(mp, args.fsbno);

		pag = xfs_perag_get(mp, agno);
		if (!pag) {
			ASSERT(0);
			return -EFSCORRUPTED;
		}

		trace_xrep_newbt_alloc_file_blocks(pag,
				XFS_FSB_TO_AGBNO(mp, args.fsbno), args.len,
				xnr->oinfo.oi_owner);

		error = xrep_newbt_add_blocks(xnr, pag, &args);
		xfs_perag_put(pag);
		if (error)
			return error;

Annotation

Implementation Notes