fs/xfs/scrub/bmap_repair.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/bmap_repair.c
Extension
.c
Size
24974 bytes
Lines
993
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

struct xrep_bmap {
	/* Old bmbt blocks */
	struct xfsb_bitmap	old_bmbt_blocks;

	/* New fork. */
	struct xrep_newbt	new_bmapbt;

	/* List of new bmap records. */
	struct xfarray		*bmap_records;

	struct xfs_scrub	*sc;

	/* How many blocks did we find allocated to this file? */
	xfs_rfsblock_t		nblocks;

	/* How many bmbt blocks did we find for this fork? */
	xfs_rfsblock_t		old_bmbt_block_count;

	/* get_records()'s position in the free space record array. */
	xfarray_idx_t		array_cur;

	/* How many real (non-hole, non-delalloc) mappings do we have? */
	uint64_t		real_mappings;

	/* Which fork are we fixing? */
	int			whichfork;

	/* What d the REFLINK flag be set when the repair is over? */
	enum reflink_scan_state	reflink_scan;

	/* Do we allow unwritten extents? */
	bool			allow_unwritten;
};

/* Is this space extent shared?  Flag the inode if it is. */
STATIC int
xrep_bmap_discover_shared(
	struct xrep_bmap	*rb,
	xfs_fsblock_t		startblock,
	xfs_filblks_t		blockcount)
{
	struct xfs_scrub	*sc = rb->sc;
	struct xfs_btree_cur	*cur;
	xfs_agblock_t		agbno;
	xfs_agblock_t		fbno;
	xfs_extlen_t		flen;
	int			error;

	if (XFS_IS_REALTIME_INODE(sc->ip)) {
		agbno = xfs_rtb_to_rgbno(sc->mp, startblock);
		cur = sc->sr.refc_cur;
	} else {
		agbno = XFS_FSB_TO_AGBNO(sc->mp, startblock);
		cur = sc->sa.refc_cur;
	}
	error = xfs_refcount_find_shared(cur, agbno, blockcount, &fbno, &flen,
			false);
	if (error)
		return error;

	if (fbno != NULLAGBLOCK)
		rb->reflink_scan = RLS_SET_IFLAG;

	return 0;
}

/* Remember this reverse-mapping as a series of bmap records. */
STATIC int
xrep_bmap_from_rmap(
	struct xrep_bmap	*rb,
	xfs_fileoff_t		startoff,
	xfs_fsblock_t		startblock,
	xfs_filblks_t		blockcount,
	bool			unwritten)
{
	struct xfs_bmbt_irec	irec = {
		.br_startoff	= startoff,
		.br_startblock	= startblock,
		.br_state	= unwritten ? XFS_EXT_UNWRITTEN : XFS_EXT_NORM,
	};
	struct xfs_bmbt_rec	rbe;
	struct xfs_scrub	*sc = rb->sc;
	int			error = 0;

	/*
	 * If we're repairing the data fork of a non-reflinked regular file on
	 * a reflink filesystem, we need to figure out if this space extent is
	 * shared.
	 */
	if (rb->reflink_scan == RLS_UNKNOWN && !unwritten) {

Annotation

Implementation Notes