fs/xfs/scrub/quota.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/quota.c
Extension
.c
Size
8845 bytes
Lines
346
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 xchk_quota_info {
	struct xfs_scrub	*sc;
	xfs_dqid_t		last_id;
};

/* There's a written block backing this dquot, right? */
STATIC int
xchk_quota_item_bmap(
	struct xfs_scrub	*sc,
	struct xfs_dquot	*dq,
	xfs_fileoff_t		offset)
{
	struct xfs_bmbt_irec	irec;
	struct xfs_mount	*mp = sc->mp;
	int			nmaps = 1;
	int			error;

	if (!xfs_verify_fileoff(mp, offset)) {
		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
		return 0;
	}

	if (dq->q_fileoffset != offset) {
		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
		return 0;
	}

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

	if (nmaps != 1) {
		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
		return 0;
	}

	if (!xfs_verify_fsbno(mp, irec.br_startblock))
		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
	if (XFS_FSB_TO_DADDR(mp, irec.br_startblock) != dq->q_blkno)
		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
	if (!xfs_bmap_is_written_extent(&irec))
		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);

	return 0;
}

/* Complain if a quota timer is incorrectly set. */
static inline void
xchk_quota_item_timer(
	struct xfs_scrub		*sc,
	xfs_fileoff_t			offset,
	const struct xfs_dquot_res	*res)
{
	if ((res->softlimit && res->count > res->softlimit) ||
	    (res->hardlimit && res->count > res->hardlimit)) {
		if (!res->timer)
			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
	} else {
		if (res->timer)
			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
	}
}

/* Scrub the fields in an individual quota item. */
STATIC int
xchk_quota_item(
	struct xchk_quota_info	*sqi,
	struct xfs_dquot	*dq)
{
	struct xfs_scrub	*sc = sqi->sc;
	struct xfs_mount	*mp = sc->mp;
	struct xfs_quotainfo	*qi = mp->m_quotainfo;
	xfs_fileoff_t		offset;
	xfs_ino_t		fs_icount;
	int			error = 0;

	if (xchk_should_terminate(sc, &error))
		return error;

	/*
	 * We want to validate the bmap record for the storage backing this
	 * dquot, so we need to lock the dquot and the quota file.  For quota
	 * operations, the locking order is first the ILOCK and then the dquot.
	 */
	xchk_ilock(sc, XFS_ILOCK_SHARED);
	mutex_lock(&dq->q_qlock);

	/*
	 * Except for the root dquot, the actual dquot we got must either have
	 * the same or higher id as we saw before.

Annotation

Implementation Notes