]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: record health problems with the metadata directory
authorDarrick J. Wong <djwong@kernel.org>
Wed, 7 Aug 2024 22:54:18 +0000 (15:54 -0700)
committerChristoph Hellwig <hch@lst.de>
Sun, 22 Sep 2024 06:07:19 +0000 (08:07 +0200)
Make a report to the health monitoring subsystem any time we encounter
something in the metadata directory tree that looks like corruption.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_fs.h
fs/xfs/libxfs/xfs_health.h
fs/xfs/libxfs/xfs_metadir.c
fs/xfs/xfs_health.c
fs/xfs/xfs_icache.c
fs/xfs/xfs_inode.c

index b652225cd682567071cc1357345df81740c854ea..8142618abbae5d6ef1c18d26e6c913040b99716e 100644 (file)
@@ -198,6 +198,7 @@ struct xfs_fsop_geom {
 #define XFS_FSOP_GEOM_SICK_RT_SUMMARY  (1 << 5)  /* realtime summary */
 #define XFS_FSOP_GEOM_SICK_QUOTACHECK  (1 << 6)  /* quota counts */
 #define XFS_FSOP_GEOM_SICK_NLINKS      (1 << 7)  /* inode link counts */
+#define XFS_FSOP_GEOM_SICK_METADIR     (1 << 8)  /* metadata directory */
 
 /* Output for XFS_FS_COUNTS */
 typedef struct xfs_fsop_counts {
index 9443b703d837a9361b39d8035a4be168acf4440c..b8846d35a6adbdd6dd3ea11779d8c292a18bf701 100644 (file)
@@ -62,6 +62,7 @@ struct xfs_da_args;
 #define XFS_SICK_FS_PQUOTA     (1 << 3)  /* project quota */
 #define XFS_SICK_FS_QUOTACHECK (1 << 4)  /* quota counts */
 #define XFS_SICK_FS_NLINKS     (1 << 5)  /* inode link counts */
+#define XFS_SICK_FS_METADIR    (1 << 6)  /* metadata directory tree */
 
 /* Observable health issues for realtime volume metadata. */
 #define XFS_SICK_RT_BITMAP     (1 << 0)  /* realtime bitmap */
@@ -105,7 +106,8 @@ struct xfs_da_args;
                                 XFS_SICK_FS_GQUOTA | \
                                 XFS_SICK_FS_PQUOTA | \
                                 XFS_SICK_FS_QUOTACHECK | \
-                                XFS_SICK_FS_NLINKS)
+                                XFS_SICK_FS_NLINKS | \
+                                XFS_SICK_FS_METADIR)
 
 #define XFS_SICK_RT_PRIMARY    (XFS_SICK_RT_BITMAP | \
                                 XFS_SICK_RT_SUMMARY)
index 0a61316b4f520f8fb343b6b9ca003b86a55a14af..bae7377c0f228caa59138d02eff0a442f49f1d56 100644 (file)
@@ -28,6 +28,7 @@
 #include "xfs_dir2.h"
 #include "xfs_dir2_priv.h"
 #include "xfs_parent.h"
+#include "xfs_health.h"
 
 /*
  * Metadata Directory Tree
@@ -94,8 +95,10 @@ xfs_metadir_lookup(
        };
        int                     error;
 
-       if (!S_ISDIR(VFS_I(dp)->i_mode))
+       if (!S_ISDIR(VFS_I(dp)->i_mode)) {
+               xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
                return -EFSCORRUPTED;
+       }
        if (xfs_is_shutdown(mp))
                return -EIO;
 
@@ -103,10 +106,14 @@ xfs_metadir_lookup(
        if (error)
                return error;
 
-       if (!xfs_verify_ino(mp, args.inumber))
+       if (!xfs_verify_ino(mp, args.inumber)) {
+               xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
                return -EFSCORRUPTED;
-       if (xname->type != XFS_DIR3_FT_UNKNOWN && xname->type != args.filetype)
+       }
+       if (xname->type != XFS_DIR3_FT_UNKNOWN && xname->type != args.filetype) {
+               xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
                return -EFSCORRUPTED;
+       }
 
        trace_xfs_metadir_lookup(dp, xname, args.inumber);
        *ino = args.inumber;
index ef1c48dc5a52a04efe7d09f453af991c92d60eef..b149b9cf3402f1c4038dc18029f14b3ccb2c79da 100644 (file)
@@ -380,6 +380,7 @@ static const struct ioctl_sick_map fs_map[] = {
        { XFS_SICK_FS_PQUOTA,   XFS_FSOP_GEOM_SICK_PQUOTA },
        { XFS_SICK_FS_QUOTACHECK, XFS_FSOP_GEOM_SICK_QUOTACHECK },
        { XFS_SICK_FS_NLINKS,   XFS_FSOP_GEOM_SICK_NLINKS },
+       { XFS_SICK_FS_METADIR,  XFS_FSOP_GEOM_SICK_METADIR },
        { 0, 0 },
 };
 
index 4eee17aa11199deb26e89298709535df12c37c8b..2ee5877196cac3a2c11f07c84b8ebc5b3255f1bc 100644 (file)
@@ -875,6 +875,7 @@ bad_rele:
 whine:
        xfs_err(mp, "metadata inode 0x%llx type %u is corrupt", ino,
                        metafile_type);
+       xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
        return -EFSCORRUPTED;
 }
 
index 4c6cda2a8a89916492ca2eba892e830c00aad7f2..0bcd44eccc34329c34bc8a8e2b75929655f8ea35 100644 (file)
@@ -560,6 +560,7 @@ xfs_lookup(
         * a metadata file.
         */
        if (XFS_IS_CORRUPT(dp->i_mount, xfs_is_metadir_inode(*ipp))) {
+               xfs_fs_mark_sick(dp->i_mount, XFS_SICK_FS_METADIR);
                error = -EFSCORRUPTED;
                goto out_irele;
        }