fs/xfs/scrub/quota_repair.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/quota_repair.c
Extension
.c
Size
14388 bytes
Lines
567
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_quota_info {
	struct xfs_scrub	*sc;
	bool			need_quotacheck;
};

/*
 * Allocate a new block into a sparse hole in the quota file backing this
 * dquot, initialize the block, and commit the whole mess.
 */
STATIC int
xrep_quota_item_fill_bmap_hole(
	struct xfs_scrub	*sc,
	struct xfs_dquot	*dq,
	struct xfs_bmbt_irec	*irec)
{
	struct xfs_buf		*bp;
	struct xfs_mount	*mp = sc->mp;
	int			nmaps = 1;
	int			error;

	xfs_trans_ijoin(sc->tp, sc->ip, 0);

	/* Map a block into the file. */
	error = xfs_trans_reserve_more(sc->tp, XFS_QM_DQALLOC_SPACE_RES(mp),
			0);
	if (error)
		return error;

	error = xfs_bmapi_write(sc->tp, sc->ip, dq->q_fileoffset,
			XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, 0,
			irec, &nmaps);
	if (error)
		return error;

	dq->q_blkno = XFS_FSB_TO_DADDR(mp, irec->br_startblock);

	trace_xrep_dquot_item_fill_bmap_hole(sc->mp, dq->q_type, dq->q_id);

	/* Initialize the new block. */
	error = xfs_trans_get_buf(sc->tp, mp->m_ddev_targp, dq->q_blkno,
			mp->m_quotainfo->qi_dqchunklen, 0, &bp);
	if (error)
		return error;
	bp->b_ops = &xfs_dquot_buf_ops;

	xfs_qm_init_dquot_blk(sc->tp, dq->q_id, dq->q_type, bp);
	xfs_buf_set_ref(bp, XFS_DQUOT_REF);

	/*
	 * Finish the mapping transactions and roll one more time to
	 * disconnect sc->ip from sc->tp.
	 */
	error = xrep_defer_finish(sc);
	if (error)
		return error;
	return xfs_trans_roll(&sc->tp);
}

/* Make sure there's a written block backing this dquot */
STATIC int
xrep_quota_item_bmap(
	struct xfs_scrub	*sc,
	struct xfs_dquot	*dq,
	bool			*dirty)
{
	struct xfs_bmbt_irec	irec;
	struct xfs_mount	*mp = sc->mp;
	struct xfs_quotainfo	*qi = mp->m_quotainfo;
	xfs_fileoff_t		offset = dq->q_id / qi->qi_dqperchunk;
	int			nmaps = 1;
	int			error;

	/* The computed file offset should always be valid. */
	if (!xfs_verify_fileoff(mp, offset)) {
		ASSERT(xfs_verify_fileoff(mp, offset));
		return -EFSCORRUPTED;
	}
	dq->q_fileoffset = offset;

	error = xfs_bmapi_read(sc->ip, offset, 1, &irec, &nmaps, 0);
	if (error)
		return error;

	if (nmaps < 1 || !xfs_bmap_is_real_extent(&irec)) {
		/* Hole/delalloc extent; allocate a real block. */
		error = xrep_quota_item_fill_bmap_hole(sc, dq, &irec);
		if (error)
			return error;
	} else if (irec.br_state != XFS_EXT_NORM) {
		/* Unwritten extent, which we already took care of? */

Annotation

Implementation Notes