fs/xfs/scrub/reap.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/reap.c
Extension
.c
Size
47714 bytes
Lines
1695
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 xreap_state {
	struct xfs_scrub		*sc;

	union {
		struct {
			/*
			 * For AG blocks, this is reverse mapping owner and
			 * metadata reservation type.
			 */
			const struct xfs_owner_info	*oinfo;
			enum xfs_ag_resv_type		resv;
		};
		struct {
			/* For file blocks, this is the inode and fork. */
			struct xfs_inode		*ip;
			int				whichfork;
		};
	};

	/* Number of invalidated buffers logged to the current transaction. */
	unsigned int			nr_binval;

	/* Maximum number of buffers we can invalidate in a single tx. */
	unsigned int			max_binval;

	/* Number of deferred reaps attached to the current transaction. */
	unsigned int			nr_deferred;

	/* Maximum number of intents we can reap in a single transaction. */
	unsigned int			max_deferred;
};

/* Put a block back on the AGFL. */
STATIC int
xreap_put_freelist(
	struct xfs_scrub	*sc,
	xfs_agblock_t		agbno)
{
	struct xfs_buf		*agfl_bp;
	int			error;

	/* Make sure there's space on the freelist. */
	error = xrep_fix_freelist(sc, 0);
	if (error)
		return error;

	/*
	 * Since we're "freeing" a lost block onto the AGFL, we have to
	 * create an rmap for the block prior to merging it or else other
	 * parts will break.
	 */
	error = xfs_rmap_alloc(sc->tp, sc->sa.agf_bp, sc->sa.pag, agbno, 1,
			&XFS_RMAP_OINFO_AG);
	if (error)
		return error;

	/* Put the block on the AGFL. */
	error = xfs_alloc_read_agfl(sc->sa.pag, sc->tp, &agfl_bp);
	if (error)
		return error;

	error = xfs_alloc_put_freelist(sc->sa.pag, sc->tp, sc->sa.agf_bp,
			agfl_bp, agbno, 0);
	if (error)
		return error;
	xfs_extent_busy_insert(sc->tp, pag_group(sc->sa.pag), agbno, 1,
			XFS_EXTENT_BUSY_SKIP_DISCARD);

	return 0;
}

/* Are there any uncommitted reap operations? */
static inline bool xreap_is_dirty(const struct xreap_state *rs)
{
	return rs->nr_binval > 0 || rs->nr_deferred > 0;
}

/*
 * Decide if we need to roll the transaction to clear out the the log
 * reservation that we allocated to buffer invalidations.
 */
static inline bool xreap_want_binval_roll(const struct xreap_state *rs)
{
	return rs->nr_binval >= rs->max_binval;
}

/* Reset the buffer invalidation count after rolling. */
static inline void xreap_binval_reset(struct xreap_state *rs)
{
	rs->nr_binval = 0;

Annotation

Implementation Notes