linux/fs/xfs/scrub/orphanage.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2021-2024 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_ialloc.h"
#include "xfs_quota.h"
#include "xfs_trans_space.h"
#include "xfs_dir2.h"
#include "xfs_icache.h"
#include "xfs_bmap.h"
#include "xfs_bmap_btree.h"
#include "xfs_parent.h"
#include "xfs_attr_sf.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/repair.h"
#include "scrub/trace.h"
#include "scrub/orphanage.h"
#include "scrub/readdir.h"

#include <linux/namei.h>

/*
 * The Orphanage
 * =============
 *
 * If the directory tree is damaged, children of that directory become
 * inaccessible via that file path.  If a child has no other parents, the file
 * is said to be orphaned.  xfs_repair fixes this situation by creating a
 * orphanage directory (specifically, /lost+found) and creating a directory
 * entry pointing to the orphaned file.
 *
 * Online repair follows this tactic by creating a root-owned /lost+found
 * directory if one does not exist.  If an orphan is found, it will move that
 * files into orphanage.
 */

/* Make the orphanage owned by root. */
STATIC int
xrep_chown_orphanage(
	struct xfs_scrub	*sc,
	struct xfs_inode	*dp)
{}

#define ORPHANAGE

/* Create the orphanage directory, and set sc->orphanage to it. */
int
xrep_orphanage_create(
	struct xfs_scrub	*sc)
{}

void
xrep_orphanage_ilock(
	struct xfs_scrub	*sc,
	unsigned int		ilock_flags)
{}

bool
xrep_orphanage_ilock_nowait(
	struct xfs_scrub	*sc,
	unsigned int		ilock_flags)
{}

void
xrep_orphanage_iunlock(
	struct xfs_scrub	*sc,
	unsigned int		ilock_flags)
{}

/* Grab the IOLOCK of the orphanage and sc->ip. */
int
xrep_orphanage_iolock_two(
	struct xfs_scrub	*sc)
{}

/* Release the orphanage. */
void
xrep_orphanage_rele(
	struct xfs_scrub	*sc)
{}

/* Adoption moves a file into /lost+found */

/* Can the orphanage adopt @sc->ip? */
bool
xrep_orphanage_can_adopt(
	struct xfs_scrub	*sc)
{}

/*
 * Create a new transaction to send a child to the orphanage.
 *
 * Allocate a new transaction with sufficient disk space to handle the
 * adoption, take ILOCK_EXCL of the orphanage and sc->ip, joins them to the
 * transaction, and reserve quota to reparent the latter.  Caller must hold the
 * IOLOCK of the orphanage and sc->ip.
 */
int
xrep_adoption_trans_alloc(
	struct xfs_scrub	*sc,
	struct xrep_adoption	*adopt)
{}

/*
 * Compute the xfs_name for the directory entry that we're adding to the
 * orphanage.  Caller must hold ILOCKs of sc->ip and the orphanage and must not
 * reuse namebuf until the adoption completes or is dissolved.
 */
int
xrep_adoption_compute_name(
	struct xrep_adoption	*adopt,
	struct xfs_name		*xname)
{}

/*
 * Make sure the dcache does not have a positive dentry for the name we've
 * chosen.  The caller should have checked with the ondisk directory, so any
 * discrepancy is a sign that something is seriously wrong.
 */
static int
xrep_adoption_check_dcache(
	struct xrep_adoption	*adopt)
{}

/*
 * Invalidate all dentries for the name that was added to the orphanage
 * directory, and all dentries pointing to the child inode that was moved.
 *
 * There should not be any positive entries for the name, since we've
 * maintained our lock on the orphanage directory.
 */
static void
xrep_adoption_zap_dcache(
	struct xrep_adoption	*adopt)
{}

/*
 * If we have to add an attr fork ahead of a parent pointer update, how much
 * space should we ask for?
 */
static inline int
xrep_adoption_attr_sizeof(
	const struct xrep_adoption	*adopt)
{}

/*
 * Move the current file to the orphanage under the computed name.
 *
 * Returns with a dirty transaction so that the caller can handle any other
 * work, such as fixing up unlinked lists or resetting link counts.
 */
int
xrep_adoption_move(
	struct xrep_adoption	*adopt)
{}

/*
 * Roll to a clean scrub transaction so that we can release the orphanage,
 * even if xrep_adoption_move was not called.
 *
 * Commits all the work and deferred ops attached to an adoption request and
 * rolls to a clean scrub transaction.  On success, returns 0 with the scrub
 * context holding a clean transaction with no inodes joined.  On failure,
 * returns negative errno with no scrub transaction.  All inode locks are
 * still held after this function returns.
 */
int
xrep_adoption_trans_roll(
	struct xrep_adoption	*adopt)
{}