fs/xfs/scrub/dirtree_repair.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/dirtree_repair.c
Extension
.c
Size
19379 bytes
Lines
822
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

switch (path->outcome) {
		case XCHK_DIRPATH_CORRUPT:
		case XCHK_DIRPATH_LOOP:
			oc->suspect--;
			oc->bad++;
			xrep_dirpath_set_outcome(dl, path, XCHK_DIRPATH_DELETE);
			break;
		case XCHK_DIRPATH_OK:
			oc->good--;
			oc->bad++;
			xrep_dirpath_set_outcome(dl, path, XCHK_DIRPATH_DELETE);
			break;
		default:
			break;
		}
	}

	ASSERT(oc->suspect == 0);
	ASSERT(oc->good == 0);
}

/* Since this is the surviving path, set the dotdot entry to this value. */
STATIC void
xrep_dirpath_retain_parent(
	struct xchk_dirtree		*dl,
	struct xchk_dirpath		*path)
{
	struct xchk_dirpath_step	step;
	int				error;

	error = xfarray_load(dl->path_steps, path->first_step, &step);
	if (error)
		return;

	dl->parent_ino = be64_to_cpu(step.pptr_rec.p_ino);
}

/* Find the one surviving path so we know how to set dotdot. */
STATIC void
xrep_dirtree_find_surviving_path(
	struct xchk_dirtree		*dl,
	struct xchk_dirtree_outcomes	*oc)
{
	struct xchk_dirpath		*path;
	bool				foundit = false;

	xchk_dirtree_for_each_path(dl, path) {
		switch (path->outcome) {
		case XCHK_DIRPATH_CORRUPT:
		case XCHK_DIRPATH_LOOP:
		case XCHK_DIRPATH_OK:
			if (!foundit) {
				xrep_dirpath_retain_parent(dl, path);
				foundit = true;
				continue;
			}
			ASSERT(foundit == false);
			break;
		default:
			break;
		}
	}

	ASSERT(oc->suspect + oc->good == 1);
}

/* Delete all paths except for the one good one. */
STATIC void
xrep_dirtree_keep_one_good_path(
	struct xchk_dirtree		*dl,
	struct xchk_dirtree_outcomes	*oc)
{
	struct xchk_dirpath		*path;
	bool				foundit = false;

	xchk_dirtree_for_each_path(dl, path) {
		switch (path->outcome) {
		case XCHK_DIRPATH_CORRUPT:
		case XCHK_DIRPATH_LOOP:
			oc->suspect--;
			oc->bad++;
			xrep_dirpath_set_outcome(dl, path, XCHK_DIRPATH_DELETE);
			break;
		case XCHK_DIRPATH_OK:
			if (!foundit) {
				xrep_dirpath_retain_parent(dl, path);
				foundit = true;
				continue;
			}
			oc->good--;

Annotation

Implementation Notes