Skip to content

Commit

Permalink
xfs: add online scrub for superblock counters
Browse files Browse the repository at this point in the history
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: Darrick J. Wong <[email protected]>
Reviewed-by: Dave Chinner <[email protected]>
Reviewed-by: Brian Foster <[email protected]>
  • Loading branch information
djwong committed Apr 30, 2019
1 parent 9407928 commit 75efa57
Show file tree
Hide file tree
Showing 11 changed files with 461 additions and 3 deletions.
1 change: 1 addition & 0 deletions fs/xfs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ xfs-y += $(addprefix scrub/, \
common.o \
dabtree.o \
dir.o \
fscounters.o \
health.o \
ialloc.o \
inode.o \
Expand Down
3 changes: 2 additions & 1 deletion fs/xfs/libxfs/xfs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion fs/xfs/libxfs/xfs_types.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions fs/xfs/libxfs/xfs_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 9 additions & 0 deletions fs/xfs/scrub/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 2 additions & 0 deletions fs/xfs/scrub/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ void xchk_block_set_preen(struct xfs_scrub *sc,
struct xfs_buf *bp);
void xchk_ino_set_preen(struct xfs_scrub *sc, xfs_ino_t ino);

void xchk_set_corrupt(struct xfs_scrub *sc);
void xchk_block_set_corrupt(struct xfs_scrub *sc,
struct xfs_buf *bp);
void xchk_ino_set_corrupt(struct xfs_scrub *sc, xfs_ino_t ino);
Expand Down Expand Up @@ -105,6 +106,7 @@ xchk_setup_quota(struct xfs_scrub *sc, struct xfs_inode *ip)
return -ENOENT;
}
#endif
int xchk_setup_fscounters(struct xfs_scrub *sc, struct xfs_inode *ip);

void xchk_ag_free(struct xfs_scrub *sc, struct xchk_ag *sa);
int xchk_ag_init(struct xfs_scrub *sc, xfs_agnumber_t agno,
Expand Down
Loading

0 comments on commit 75efa57

Please sign in to comment.