linux/fs/xfs/scrub/parent.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2017-2023 Oracle.  All Rights Reserved.
 * Author: Darrick J. Wong <[email protected]>
 */
#include "xfs.h"
#include "xfs_fs.h"
#include "xfs_shared.h"
#include "xfs_format.h"
#include "xfs_trans_resv.h"
#include "xfs_mount.h"
#include "xfs_log_format.h"
#include "xfs_trans.h"
#include "xfs_inode.h"
#include "xfs_icache.h"
#include "xfs_dir2.h"
#include "xfs_dir2_priv.h"
#include "xfs_attr.h"
#include "xfs_parent.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/readdir.h"
#include "scrub/tempfile.h"
#include "scrub/repair.h"
#include "scrub/listxattr.h"
#include "scrub/xfile.h"
#include "scrub/xfarray.h"
#include "scrub/xfblob.h"
#include "scrub/trace.h"

/* Set us up to scrub parents. */
int
xchk_setup_parent(
	struct xfs_scrub	*sc)
{}

/* Parent pointers */

/* Look for an entry in a parent pointing to this inode. */

struct xchk_parent_ctx {};

/* Look for a single entry in a directory pointing to an inode. */
STATIC int
xchk_parent_actor(
	struct xfs_scrub	*sc,
	struct xfs_inode	*dp,
	xfs_dir2_dataptr_t	dapos,
	const struct xfs_name	*name,
	xfs_ino_t		ino,
	void			*priv)
{}

/*
 * Try to lock a parent directory for checking dirents.  Returns the inode
 * flags for the locks we now hold, or zero if we failed.
 */
STATIC unsigned int
xchk_parent_ilock_dir(
	struct xfs_inode	*dp)
{}

/*
 * Given the inode number of the alleged parent of the inode being scrubbed,
 * try to validate that the parent has exactly one directory entry pointing
 * back to the inode being scrubbed.  Returns -EAGAIN if we need to revalidate
 * the dotdot entry.
 */
STATIC int
xchk_parent_validate(
	struct xfs_scrub	*sc,
	xfs_ino_t		parent_ino)
{}

/*
 * Checking of Parent Pointers
 * ===========================
 *
 * On filesystems with directory parent pointers, we check the referential
 * integrity by visiting each parent pointer of a child file and checking that
 * the directory referenced by the pointer actually has a dirent pointing
 * forward to the child file.
 */

/* Deferred parent pointer entry that we saved for later. */
struct xchk_pptr {};

struct xchk_pptrs {};

/* Does this parent pointer match the dotdot entry? */
STATIC int
xchk_parent_scan_dotdot(
	struct xfs_scrub		*sc,
	struct xfs_inode		*ip,
	unsigned int			attr_flags,
	const unsigned char		*name,
	unsigned int			namelen,
	const void			*value,
	unsigned int			valuelen,
	void				*priv)
{}

/* Look up the dotdot entry so that we can check it as we walk the pptrs. */
STATIC int
xchk_parent_pptr_and_dotdot(
	struct xchk_pptrs	*pp)
{}

/*
 * Try to lock a parent directory for checking dirents.  Returns the inode
 * flags for the locks we now hold, or zero if we failed.
 */
STATIC unsigned int
xchk_parent_lock_dir(
	struct xfs_scrub	*sc,
	struct xfs_inode	*dp)
{}

/* Check the forward link (dirent) associated with this parent pointer. */
STATIC int
xchk_parent_dirent(
	struct xchk_pptrs	*pp,
	const struct xfs_name	*xname,
	struct xfs_inode	*dp)
{}

/* Try to grab a parent directory. */
STATIC int
xchk_parent_iget(
	struct xchk_pptrs	*pp,
	const struct xfs_parent_rec	*pptr,
	struct xfs_inode	**dpp)
{}

/*
 * Walk an xattr of a file.  If this xattr is a parent pointer, follow it up
 * to a parent directory and check that the parent has a dirent pointing back
 * to us.
 */
STATIC int
xchk_parent_scan_attr(
	struct xfs_scrub	*sc,
	struct xfs_inode	*ip,
	unsigned int		attr_flags,
	const unsigned char	*name,
	unsigned int		namelen,
	const void		*value,
	unsigned int		valuelen,
	void			*priv)
{}

/*
 * Revalidate a parent pointer that we collected in the past but couldn't check
 * because of lock contention.  Returns 0 if the parent pointer is still valid,
 * -ENOENT if it has gone away on us, or a negative errno.
 */
STATIC int
xchk_parent_revalidate_pptr(
	struct xchk_pptrs		*pp,
	const struct xfs_name		*xname,
	struct xfs_parent_rec		*pptr)
{}

/*
 * Check a parent pointer the slow way, which means we cycle locks a bunch
 * and put up with revalidation until we get it done.
 */
STATIC int
xchk_parent_slow_pptr(
	struct xchk_pptrs	*pp,
	const struct xfs_name	*xname,
	struct xfs_parent_rec	*pptr)
{}

/* Check all the parent pointers that we deferred the first time around. */
STATIC int
xchk_parent_finish_slow_pptrs(
	struct xchk_pptrs	*pp)
{}

/* Count the number of parent pointers. */
STATIC int
xchk_parent_count_pptr(
	struct xfs_scrub		*sc,
	struct xfs_inode		*ip,
	unsigned int			attr_flags,
	const unsigned char		*name,
	unsigned int			namelen,
	const void			*value,
	unsigned int			valuelen,
	void				*priv)
{}

/*
 * Compare the number of parent pointers to the link count.  For
 * non-directories these should be the same.  For unlinked directories the
 * count should be zero; for linked directories, it should be nonzero.
 */
STATIC int
xchk_parent_count_pptrs(
	struct xchk_pptrs	*pp)
{}

/* Check parent pointers of a file. */
STATIC int
xchk_parent_pptr(
	struct xfs_scrub	*sc)
{}

/* Scrub a parent pointer. */
int
xchk_parent(
	struct xfs_scrub	*sc)
{}

/*
 * Decide if this file's extended attributes (and therefore its parent
 * pointers) have been zapped to satisfy the inode and ifork verifiers.
 * Checking and repairing should be postponed until the extended attribute
 * structure is fixed.
 */
bool
xchk_pptr_looks_zapped(
	struct xfs_inode	*ip)
{}