fs/xfs/scrub/orphanage.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/orphanage.c
Extension
.c
Size
16664 bytes
Lines
632
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 (xrep_orphanage_ilock_nowait(sc, XFS_IOLOCK_EXCL)) {
			if (xchk_ilock_nowait(sc, XFS_IOLOCK_EXCL))
				break;
			xrep_orphanage_iunlock(sc, XFS_IOLOCK_EXCL);
		}
		delay(1);
	}

	return 0;
}

/* Release the orphanage. */
void
xrep_orphanage_rele(
	struct xfs_scrub	*sc)
{
	if (!sc->orphanage)
		return;

	if (sc->orphanage_ilock_flags)
		xfs_iunlock(sc->orphanage, sc->orphanage_ilock_flags);

	xchk_irele(sc, sc->orphanage);
	sc->orphanage = NULL;
}

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

/* Can the orphanage adopt @sc->ip? */
bool
xrep_orphanage_can_adopt(
	struct xfs_scrub	*sc)
{
	ASSERT(sc->ip != NULL);

	if (!sc->orphanage)
		return false;
	if (sc->ip == sc->orphanage)
		return false;
	if (xchk_inode_is_sb_rooted(sc->ip))
		return false;
	if (xfs_is_internal_inode(sc->ip))
		return false;
	return true;
}

/*
 * 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)
{
	struct xfs_mount	*mp = sc->mp;
	unsigned int		child_blkres = 0;
	int			error;

	ASSERT(sc->tp == NULL);
	ASSERT(sc->ip != NULL);
	ASSERT(sc->orphanage != NULL);
	ASSERT(sc->ilock_flags & XFS_IOLOCK_EXCL);
	ASSERT(sc->orphanage_ilock_flags & XFS_IOLOCK_EXCL);
	ASSERT(!(sc->ilock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)));
	ASSERT(!(sc->orphanage_ilock_flags &
				(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)));

	/* Compute the worst case space reservation that we need. */
	adopt->sc = sc;
	adopt->orphanage_blkres = xfs_link_space_res(mp, MAXNAMELEN);
	if (S_ISDIR(VFS_I(sc->ip)->i_mode))
		child_blkres = xfs_rename_space_res(mp, 0, false,
						    xfs_name_dotdot.len, false);
	if (xfs_has_parent(mp))
		child_blkres += XFS_ADDAFORK_SPACE_RES(mp);
	adopt->child_blkres = child_blkres;

	/*
	 * Allocate a transaction to link the child into the parent, along with
	 * enough disk space to handle expansion of both the orphanage and the
	 * dotdot entry of a child directory.
	 */
	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_link,
			adopt->orphanage_blkres + adopt->child_blkres, 0, 0,
			&sc->tp);

Annotation

Implementation Notes