xfs: report AG health via AG geometry ioctl
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 12 Apr 2019 14:41:18 +0000 (07:41 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Mon, 15 Apr 2019 01:15:57 +0000 (18:15 -0700)
Use the AG geometry info ioctl to report health status too.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_fs.h
fs/xfs/libxfs/xfs_health.h
fs/xfs/xfs_health.c

index 1c0f2a6..b0c89f5 100644 (file)
@@ -20,6 +20,7 @@
 #include "xfs_rmap.h"
 #include "xfs_ag.h"
 #include "xfs_ag_resv.h"
+#include "xfs_health.h"
 
 static struct xfs_buf *
 xfs_get_aghdr_buf(
@@ -505,6 +506,7 @@ xfs_ag_get_geometry(
                   pag->pagf_btreeblks -
                   xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE);
        ageo->ag_freeblks = freeblks;
+       xfs_ag_geom_health(pag, ageo);
 
        /* Release resources. */
        xfs_perag_put(pag);
index 6b8956d..35d60f8 100644 (file)
@@ -285,9 +285,21 @@ struct xfs_ag_geometry {
        uint32_t        ag_freeblks;    /* o: free space */
        uint32_t        ag_icount;      /* o: inodes allocated */
        uint32_t        ag_ifree;       /* o: inodes free */
+       uint32_t        ag_sick;        /* o: sick things in ag */
+       uint32_t        ag_checked;     /* o: checked metadata in ag */
        uint32_t        ag_reserved32;  /* o: zero */
-       uint64_t        ag_reserved[13];/* o: zero */
+       uint64_t        ag_reserved[12];/* o: zero */
 };
+#define XFS_AG_GEOM_SICK_SB    (1 << 0)  /* superblock */
+#define XFS_AG_GEOM_SICK_AGF   (1 << 1)  /* AGF header */
+#define XFS_AG_GEOM_SICK_AGFL  (1 << 2)  /* AGFL header */
+#define XFS_AG_GEOM_SICK_AGI   (1 << 3)  /* AGI header */
+#define XFS_AG_GEOM_SICK_BNOBT (1 << 4)  /* free space by block */
+#define XFS_AG_GEOM_SICK_CNTBT (1 << 5)  /* free space by length */
+#define XFS_AG_GEOM_SICK_INOBT (1 << 6)  /* inode index */
+#define XFS_AG_GEOM_SICK_FINOBT        (1 << 7)  /* free inode index */
+#define XFS_AG_GEOM_SICK_RMAPBT        (1 << 8)  /* reverse mappings */
+#define XFS_AG_GEOM_SICK_REFCNTBT (1 << 9)  /* reference counts */
 
 /*
  * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT
index 3fffdcc..e392457 100644 (file)
@@ -184,5 +184,6 @@ xfs_inode_is_healthy(struct xfs_inode *ip)
 }
 
 void xfs_fsop_geom_health(struct xfs_mount *mp, struct xfs_fsop_geom *geo);
+void xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
 
 #endif /* __XFS_HEALTH_H__ */
index d137b8f..5431c40 100644 (file)
@@ -320,3 +320,39 @@ xfs_fsop_geom_health(
        for (m = rt_map; m->sick_mask; m++)
                xfgeo_health_tick(geo, sick, checked, m);
 }
+
+static const struct ioctl_sick_map ag_map[] = {
+       { XFS_SICK_AG_SB,       XFS_AG_GEOM_SICK_SB },
+       { XFS_SICK_AG_AGF,      XFS_AG_GEOM_SICK_AGF },
+       { XFS_SICK_AG_AGFL,     XFS_AG_GEOM_SICK_AGFL },
+       { XFS_SICK_AG_AGI,      XFS_AG_GEOM_SICK_AGI },
+       { XFS_SICK_AG_BNOBT,    XFS_AG_GEOM_SICK_BNOBT },
+       { XFS_SICK_AG_CNTBT,    XFS_AG_GEOM_SICK_CNTBT },
+       { XFS_SICK_AG_INOBT,    XFS_AG_GEOM_SICK_INOBT },
+       { XFS_SICK_AG_FINOBT,   XFS_AG_GEOM_SICK_FINOBT },
+       { XFS_SICK_AG_RMAPBT,   XFS_AG_GEOM_SICK_RMAPBT },
+       { XFS_SICK_AG_REFCNTBT, XFS_AG_GEOM_SICK_REFCNTBT },
+       { 0, 0 },
+};
+
+/* Fill out ag geometry health info. */
+void
+xfs_ag_geom_health(
+       struct xfs_perag                *pag,
+       struct xfs_ag_geometry          *ageo)
+{
+       const struct ioctl_sick_map     *m;
+       unsigned int                    sick;
+       unsigned int                    checked;
+
+       ageo->ag_sick = 0;
+       ageo->ag_checked = 0;
+
+       xfs_ag_measure_sickness(pag, &sick, &checked);
+       for (m = ag_map; m->sick_mask; m++) {
+               if (checked & m->sick_mask)
+                       ageo->ag_checked |= m->ioctl_mask;
+               if (sick & m->sick_mask)
+                       ageo->ag_sick |= m->ioctl_mask;
+       }
+}