[PATCH 27/41] xfs_repair: check metadata inode flag

Darrick J. Wong
2024-12-06T23:46:41Z

From: Darrick J. Wong <djwong@kernel.org>

Check whether or not the metadata inode flag is set appropriately.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
repair/dinode.c | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)

diff --git a/repair/dinode.c b/repair/dinode.c
index 12a12f00672776..f21a4dd387331b 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -2331,6 +2331,26 @@ _("Bad extent size hint %u on inode %" PRIu64 ", "),
}
}

+static inline bool
+should_have_metadir_iflag(
+ struct xfs_mount *mp,
+ xfs_ino_t ino)
+{
+ if (ino == mp->m_sb.sb_metadirino)
+ return true;
+ if (ino == mp->m_sb.sb_rbmino)
+ return true;
+ if (ino == mp->m_sb.sb_rsumino)
+ return true;
+ if (ino == mp->m_sb.sb_uquotino)
+ return true;
+ if (ino == mp->m_sb.sb_gquotino)
+ return true;
+ if (ino == mp->m_sb.sb_pquotino)
+ return true;
+ return false;
+}
+
/*
* returns 0 if the inode is ok, 1 if the inode is corrupt
* check_dups can be set to 1 *only* when called by the
@@ -2680,6 +2700,27 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"),
}
}

+ if (flags2 & XFS_DIFLAG2_METADATA) {
+ xfs_failaddr_t fa;
+
+ fa = libxfs_dinode_verify_metadir(mp, dino, di_mode,
+ be16_to_cpu(dino->di_flags), flags2);
+ if (fa) {
+ if (!uncertain)
+ do_warn(
+ _("inode %" PRIu64 " is incorrectly marked as metadata\n"),
+ lino);
+ goto clear_bad_out;
+ }
+ } else if (xfs_has_metadir(mp) &&
+ should_have_metadir_iflag(mp, lino)) {
+ if (!uncertain)
+ do_warn(
+ _("inode %" PRIu64 " should be marked as metadata\n"),
+ lino);
+ goto clear_bad_out;
+ }
+
if ((flags2 & XFS_DIFLAG2_REFLINK) &&
!xfs_has_reflink(mp)) {
if (!uncertain) {