Commit 75efa57d authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: add online scrub for superblock counters



Teach online scrub how to check the filesystem summary counters.  We use
the incore delalloc block counter along with the incore AG headers to
compute expected values for fdblocks, icount, and ifree, and then check
that the percpu counter is within a certain threshold of the expected
value.  This is done to avoid having to freeze or otherwise lock the
filesystem, which means that we're only checking that the counters are
fairly close, not that they're exactly correct.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
parent 94079285
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -143,6 +143,7 @@ xfs-y += $(addprefix scrub/, \
				   common.o \
				   dabtree.o \
				   dir.o \
				   fscounters.o \
				   health.o \
				   ialloc.o \
				   inode.o \
+2 −1
Original line number Diff line number Diff line
@@ -578,9 +578,10 @@ struct xfs_scrub_metadata {
#define XFS_SCRUB_TYPE_UQUOTA	21	/* user quotas */
#define XFS_SCRUB_TYPE_GQUOTA	22	/* group quotas */
#define XFS_SCRUB_TYPE_PQUOTA	23	/* project quotas */
#define XFS_SCRUB_TYPE_FSCOUNTERS 24	/* fs summary counters */

/* Number of scrub subcommands. */
#define XFS_SCRUB_TYPE_NR	24
#define XFS_SCRUB_TYPE_NR	25

/* i: Repair this metadata. */
#define XFS_SCRUB_IFLAG_REPAIR		(1 << 0)
+1 −1
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ xfs_verify_rtbno(
}

/* Calculate the range of valid icount values. */
static void
void
xfs_icount_range(
	struct xfs_mount	*mp,
	unsigned long long	*min,
+2 −0
Original line number Diff line number Diff line
@@ -191,5 +191,7 @@ bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino);
bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno);
bool xfs_verify_icount(struct xfs_mount *mp, unsigned long long icount);
bool xfs_verify_dablk(struct xfs_mount *mp, xfs_fileoff_t off);
void xfs_icount_range(struct xfs_mount *mp, unsigned long long *min,
		unsigned long long *max);

#endif	/* __XFS_TYPES_H__ */
+9 −0
Original line number Diff line number Diff line
@@ -209,6 +209,15 @@ xchk_ino_set_preen(
	trace_xchk_ino_preen(sc, ino, __return_address);
}

/* Record something being wrong with the filesystem primary superblock. */
void
xchk_set_corrupt(
	struct xfs_scrub	*sc)
{
	sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
	trace_xchk_fs_error(sc, 0, __return_address);
}

/* Record a corrupt block. */
void
xchk_block_set_corrupt(
Loading