fs/xfs/scrub/dirtree.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/dirtree.c
Extension
.c
Size
26551 bytes
Lines
1009
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 (ret < 0) {
			dl->aborted = true;
			break;
		}
		if (ret == 1) {
			dl->stale = true;
			break;
		}
	}

out_unlock:
	mutex_unlock(&dl->lock);
	return NOTIFY_DONE;
}

/* Delete all the collected path information. */
STATIC void
xchk_dirtree_reset(
	void			*buf)
{
	struct xchk_dirtree	*dl = buf;
	struct xchk_dirpath	*path, *n;

	ASSERT(dl->sc->ilock_flags & XFS_ILOCK_EXCL);

	xchk_dirtree_for_each_path_safe(dl, path, n) {
		list_del_init(&path->list);
		xino_bitmap_destroy(&path->seen_inodes);
		kfree(path);
	}
	dl->nr_paths = 0;

	xfarray_truncate(dl->path_steps);
	xfblob_truncate(dl->path_names);

	dl->stale = false;
}

/*
 * Load the name/pptr from the first step in this path into @dl->pptr_rec and
 * @dl->xname.
 */
STATIC int
xchk_dirtree_load_path(
	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 error;

	error = xfblob_loadname(dl->path_names, step.name_cookie, &dl->xname,
			step.name_len);
	if (error)
		return error;

	dl->pptr_rec = step.pptr_rec; /* struct copy */
	return 0;
}

/*
 * For each parent pointer of this subdir, trace a path upwards towards the
 * root directory and record what we find.  Returns 0 for success;
 * -EFSCORRUPTED if walking the parent pointers of @sc->ip failed, -ELNRNG if a
 * path was too deep; -ENOSR if there were too many parent pointers; or
 * a negative errno.
 */
int
xchk_dirtree_find_paths_to_root(
	struct xchk_dirtree	*dl)
{
	struct xfs_scrub	*sc = dl->sc;
	struct xchk_dirpath	*path;
	int			error = 0;

	do {
		if (xchk_should_terminate(sc, &error))
			return error;

		xchk_dirtree_reset(dl);

		/*
		 * If the extended attributes look as though they has been
		 * zapped by the inode record repair code, we cannot scan for
		 * parent pointers.
		 */
		if (xchk_pptr_looks_zapped(sc->ip)) {

Annotation

Implementation Notes