xfs: check inode core when scrubbing metadata files

Metadata files (e.g. realtime bitmaps and quota files) do not show up in
the bulkstat output, which means that scrub-by-handle does not work;
they can only be checked through a specific scrub type.  Therefore, each
scrub type calls xchk_metadata_inode_forks to check the metadata for
whatever's in the file.

Unfortunately, that function doesn't actually check the inode record
itself.  Refactor the function a bit to make that happen.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
Darrick J. Wong 2022-11-16 16:08:03 -08:00
parent bd5ab5f987
commit f36b954a1f

View File

@ -781,6 +781,33 @@ xchk_buffer_recheck(
trace_xchk_block_error(sc, xfs_buf_daddr(bp), fa); trace_xchk_block_error(sc, xfs_buf_daddr(bp), fa);
} }
static inline int
xchk_metadata_inode_subtype(
struct xfs_scrub *sc,
unsigned int scrub_type)
{
__u32 smtype = sc->sm->sm_type;
int error;
sc->sm->sm_type = scrub_type;
switch (scrub_type) {
case XFS_SCRUB_TYPE_INODE:
error = xchk_inode(sc);
break;
case XFS_SCRUB_TYPE_BMBTD:
error = xchk_bmap_data(sc);
break;
default:
ASSERT(0);
error = -EFSCORRUPTED;
break;
}
sc->sm->sm_type = smtype;
return error;
}
/* /*
* Scrub the attr/data forks of a metadata inode. The metadata inode must be * Scrub the attr/data forks of a metadata inode. The metadata inode must be
* pointed to by sc->ip and the ILOCK must be held. * pointed to by sc->ip and the ILOCK must be held.
@ -789,13 +816,17 @@ int
xchk_metadata_inode_forks( xchk_metadata_inode_forks(
struct xfs_scrub *sc) struct xfs_scrub *sc)
{ {
__u32 smtype;
bool shared; bool shared;
int error; int error;
if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
return 0; return 0;
/* Check the inode record. */
error = xchk_metadata_inode_subtype(sc, XFS_SCRUB_TYPE_INODE);
if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
return error;
/* Metadata inodes don't live on the rt device. */ /* Metadata inodes don't live on the rt device. */
if (sc->ip->i_diflags & XFS_DIFLAG_REALTIME) { if (sc->ip->i_diflags & XFS_DIFLAG_REALTIME) {
xchk_ino_set_corrupt(sc, sc->ip->i_ino); xchk_ino_set_corrupt(sc, sc->ip->i_ino);
@ -815,10 +846,7 @@ xchk_metadata_inode_forks(
} }
/* Invoke the data fork scrubber. */ /* Invoke the data fork scrubber. */
smtype = sc->sm->sm_type; error = xchk_metadata_inode_subtype(sc, XFS_SCRUB_TYPE_BMBTD);
sc->sm->sm_type = XFS_SCRUB_TYPE_BMBTD;
error = xchk_bmap_data(sc);
sc->sm->sm_type = smtype;
if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
return error; return error;
@ -833,7 +861,7 @@ xchk_metadata_inode_forks(
xchk_ino_set_corrupt(sc, sc->ip->i_ino); xchk_ino_set_corrupt(sc, sc->ip->i_ino);
} }
return error; return 0;
} }
/* /*