diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2020-10-25 17:14:29 -0700 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2020-10-26 18:32:11 -0700 |
commit | e4b5d9d6fd2f37df6e16dc8a5966e0bd133d4bd4 (patch) | |
tree | ff08ba41e6eafeda47f1e625bb59f5528aa0ce05 | |
parent | 29af45e5fae69346e6a081020ddc8f2fb5ff3612 (diff) |
xfs: online checking of the free rt extent countscrub-fixes_2020-10-26
Teach the summary count checker to count the number of free realtime
extents and compare that to the superblock copy.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r-- | fs/xfs/scrub/fscounters.c | 50 | ||||
-rw-r--r-- | fs/xfs/scrub/scrub.h | 1 |
2 files changed, 51 insertions, 0 deletions
diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index ec2064ed3c30..e9114c4a62b4 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -13,6 +13,8 @@ #include "xfs_alloc.h" #include "xfs_ialloc.h" #include "xfs_health.h" +#include "xfs_rtalloc.h" +#include "xfs_inode.h" #include "scrub/scrub.h" #include "scrub/common.h" #include "scrub/trace.h" @@ -240,6 +242,49 @@ retry: return 0; } +static int +xchk_fscount_add_frextent( + struct xfs_trans *tp, + struct xfs_rtalloc_rec *rec, + void *priv) +{ + struct xchk_fscounters *fsc = priv; + + fsc->frextents += rec->ar_extcount; + return 0; +} + +/* + * Calculate what the superblock free realtime extent count should be given the + * realtime bitmap. + */ +STATIC int +xchk_fscount_check_frextents( + struct xfs_scrub *sc, + struct xchk_fscounters *fsc) +{ + struct xfs_mount *mp = sc->mp; + int error; + + if (!xfs_sb_version_hasrealtime(&mp->m_sb)) + return 0; + + fsc->frextents = 0; + xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_EXCL); + error = xfs_rtalloc_query_all(sc->tp, xchk_fscount_add_frextent, fsc); + if (error) + goto out_unlock; + + spin_lock(&mp->m_sb_lock); + if (fsc->frextents != mp->m_sb.sb_frextents) + xchk_set_corrupt(sc); + spin_unlock(&mp->m_sb_lock); + +out_unlock: + xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_EXCL); + return error; +} + /* * Is the @counter reasonably close to the @expected value? * @@ -351,5 +396,10 @@ xchk_fscounters( fsc->fdblocks)) xchk_set_corrupt(sc); + /* Check the free extents counter for rt volumes. */ + error = xchk_fscount_check_frextents(sc, fsc); + if (!xchk_process_error(sc, 0, XFS_SB_BLOCK(mp), &error)) + return error; + return 0; } diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h index ad1ceb44a628..5ad442c166e8 100644 --- a/fs/xfs/scrub/scrub.h +++ b/fs/xfs/scrub/scrub.h @@ -157,6 +157,7 @@ struct xchk_fscounters { uint64_t icount; uint64_t ifree; uint64_t fdblocks; + uint64_t frextents; unsigned long long icount_min; unsigned long long icount_max; }; |