From: Darrick J. Wong <[email protected]>

Set up a metadata health event hook so that we can send events to
userspace as we collect information.

Signed-off-by: Darrick J. Wong <[email protected]>
---
 fs/xfs/xfs_healthmon.c |  403 ++++++++++++++++++++++++++++++++++++++++++++++++
 fs/xfs/xfs_healthmon.h |   31 ++++
 fs/xfs/xfs_trace.h     |  102 ++++++++++++
 3 files changed, 532 insertions(+), 4 deletions(-)


diff --git a/fs/xfs/xfs_healthmon.c b/fs/xfs/xfs_healthmon.c
index b215ded0fda8b..d3b548a63f0b9 100644
--- a/fs/xfs/xfs_healthmon.c
+++ b/fs/xfs/xfs_healthmon.c
@@ -19,6 +19,7 @@
 #include "xfs_quota_defs.h"
 #include "xfs_rtgroup.h"
 #include "xfs_fsops.h"
+#include "xfs_health.h"
 #include "xfs_healthmon.h"
 
 /*
@@ -72,6 +73,86 @@
  *
  * "reasons" are a list of strings describing why the filesystem went down.
  * They correspond to the SHUTDOWN_* flags.
+ *
+ * Metadata Health Events
+ * ----------------------
+ *
+ * {
+ *     "type": "sick" | "corrupt" | "healthy",
+ *     "domain": "fs" | "realtime" | "ag" | "inode" | "rtgroup",
+ *     "structures": [structure string list...],
+ *
+ *     "group": integer,      (if domain is "ag" or "rtgroup")
+ *
+ *     "inode": integer,      (if domain is "inode")
+ *     "generation": integer, (if domain is "inode")
+ *
+ *     "time_ns": integer
+ * }
+ *
+ * "sick" means that metadata corruption was discovered during a runtime
+ * operation.
+ *
+ * "corrupt" means that corruption was discovered during an xfs_scrub run.
+ *
+ * "healthy" means that a metadata object was found to be ok by xfs_scrub.
+ *
+ * The domain item indicates where in the filesystem to find the metadata
+ * object(s) that are the target of the event.
+ *
+ * "fs" means whole-filesystem metadata.  Structures are as follows:
+ *
+ *     "fscounters": summary counters
+ *     "usrquota":   user quota records
+ *     "grpquota":   group quota records
+ *     "prjquota":   project quota records
+ *     "quotacheck": quota counters
+ *     "nlinks":     file link counts
+ *     "metadir":    metadata directory
+ *     "metapath":   metadata inode paths
+ *
+ * "realtime" means realtime volume metadata:
+ *
+ *     "bitmap":     realtime bitmap file
+ *     "summary":    realtime free space summary file
+ *
+ * "ag" means allocation group metadata on the data device:
+ *
+ *     "super":      superblock
+ *     "agf":        group space header
+ *     "agfl":       per-group free block list
+ *     "agi":        group inode header
+ *     "bnobt":      free space by position btree
+ *     "cntbt":      free space by length btree
+ *     "inobt":      inode btree
+ *     "finobt":     free inode btree
+ *     "rmapbt":     reverse mapping btree
+ *     "refcountbt": reference count btree
+ *     "inodes":     problems were recorded for this group's inodes, but the
+ *                   inodes themselves had to be reclaimed
+ *
+ * "inode" means inode metadata:
+ *
+ *     "core":       inode record
+ *     "bmapbtd":    data fork
+ *     "bmapbta":    attr fork
+ *     "bmapbtc":    cow fork
+ *     "directory":  directory entries and index
+ *     "xattr":      extended attributes and index
+ *     "symlink":    symbolic link target
+ *     "parent":     directory parent pointer
+ *     "bmapbtd_zapped":  these are set when an inode record repair had to drop
+ *     "bmapbtd_zapped"   the corresponding data structure to get the inode
+ *     "directory_zapped" back to a consistent state
+ *     "symlink_zapped"
+ *     "dirtree":    directory tree problems detected
+ *
+ * "rtgroup" means realtime group metadata for the realtime volume:
+ *
+ *     "super":      group superblock
+ *     "bitmap":     free space bitmap contents for this group
+ *     "rmapbt":     reverse mapping btree
+ *     "refcountbt": reference count btree
  */
 
 #define XFS_HEALTHMON_MAX_EVENTS \
@@ -98,6 +179,7 @@ struct xfs_healthmon {
 
        /* live update hooks */
        struct xfs_shutdown_hook        shook;
+       struct xfs_health_hook          hhook;
 
        /* filesystem mount, or NULL if we've unmounted */
        struct xfs_mount                *mp;
@@ -145,8 +227,10 @@ xfs_healthmon_exit(
        trace_xfs_healthmon_exit(hm->mp, hm->events, hm->lost_prev_event);
 
        if (hm->mp) {
+               xfs_health_hook_del(hm->mp, &hm->hhook);
                xfs_shutdown_hook_del(hm->mp, &hm->shook);
        }
+       xfs_health_hook_disable();
        xfs_shutdown_hook_disable();
        mutex_destroy(&hm->lock);
        xfs_healthmon_free_events(hm);
@@ -291,6 +375,157 @@ xfs_healthmon_shutdown_hook(
        return NOTIFY_DONE;
 }
 
+/* Compute the reporting mask. */
+static inline bool
+xfs_healthmon_event_mask(
+       struct xfs_healthmon                    *hm,
+       enum xfs_health_update_type             type,
+       const struct xfs_health_update_params   *hup,
+       unsigned int                            *mask)
+{
+       /* Always report unmounts. */
+       if (type == XFS_HEALTHUP_UNMOUNT)
+               return true;
+
+       /* If we want all events, return all events. */
+       if (hm->verbose) {
+               *mask = hup->new_mask;
+               return true;
+       }
+
+       switch (type) {
+       case XFS_HEALTHUP_SICK:
+               /* Always report runtime corruptions */
+               *mask = hup->new_mask;
+               break;
+       case XFS_HEALTHUP_CORRUPT:
+               /* Only report new fsck errors */
+               *mask = hup->new_mask & ~hup->old_mask;
+               break;
+       case XFS_HEALTHUP_HEALTHY:
+               /* Only report healthy metadata that got fixed */
+               *mask = hup->new_mask & hup->old_mask;
+               break;
+       case XFS_HEALTHUP_UNMOUNT:
+               /* This is here for static enum checking */
+               break;
+       }
+
+       /* If not in verbose mode, mask state has to change. */
+       return *mask != 0;
+}
+
+static inline enum xfs_healthmon_type
+health_update_to_type(
+       enum xfs_health_update_type     type)
+{
+       switch (type) {
+       case XFS_HEALTHUP_SICK:
+               return XFS_HEALTHMON_SICK;
+       case XFS_HEALTHUP_CORRUPT:
+               return XFS_HEALTHMON_CORRUPT;
+       case XFS_HEALTHUP_HEALTHY:
+               return XFS_HEALTHMON_HEALTHY;
+       case XFS_HEALTHUP_UNMOUNT:
+               /* static checking */
+               break;
+       }
+       return XFS_HEALTHMON_UNMOUNT;
+}
+
+static inline enum xfs_healthmon_domain
+health_update_to_domain(
+       enum xfs_health_update_domain   domain)
+{
+       switch (domain) {
+       case XFS_HEALTHUP_FS:
+               return XFS_HEALTHMON_FS;
+       case XFS_HEALTHUP_RT:
+               return XFS_HEALTHMON_RT;
+       case XFS_HEALTHUP_AG:
+               return XFS_HEALTHMON_AG;
+       case XFS_HEALTHUP_RTGROUP:
+               return XFS_HEALTHMON_RTGROUP;
+       case XFS_HEALTHUP_INODE:
+               /* static checking */
+               break;
+       }
+       return XFS_HEALTHMON_INODE;
+}
+
+/* Add a health event to the reporting queue. */
+STATIC int
+xfs_healthmon_metadata_hook(
+       struct notifier_block           *nb,
+       unsigned long                   action,
+       void                            *data)
+{
+       struct xfs_health_update_params *hup = data;
+       struct xfs_healthmon            *hm;
+       struct xfs_healthmon_event      *event;
+       enum xfs_health_update_type     type = action;
+       unsigned int                    mask = 0;
+       int                             error;
+
+       hm = container_of(nb, struct xfs_healthmon, hhook.health_hook.nb);
+
+       /* Decode event mask and skip events we don't care about. */
+       if (!xfs_healthmon_event_mask(hm, type, hup, &mask))
+               return NOTIFY_DONE;
+
+       mutex_lock(&hm->lock);
+
+       trace_xfs_healthmon_metadata_hook(hm->mp, action, hup, hm->events,
+                       hm->lost_prev_event);
+
+       error = xfs_healthmon_start_live_update(hm);
+       if (error)
+               goto out_unlock;
+
+       if (type == XFS_HEALTHUP_UNMOUNT) {
+               /*
+                * The filesystem is unmounting, so we must detach from the
+                * mount.  After this point, the healthmon thread has no
+                * connection to the mounted filesystem.
+                */
+               trace_xfs_healthmon_unmount(hm->mp, hm->events,
+                               hm->lost_prev_event);
+               hm->mp = NULL;
+               wake_up(&hm->wait);
+               goto out_unlock;
+       }
+
+       event = new_event(hm, health_update_to_type(type),
+                         health_update_to_domain(hup->domain));
+       if (!event)
+               goto out_unlock;
+
+       switch (event->domain) {
+       case XFS_HEALTHMON_FS:
+       case XFS_HEALTHMON_RT:
+               event->fsmask = mask;
+               break;
+       case XFS_HEALTHMON_AG:
+       case XFS_HEALTHMON_RTGROUP:
+               event->grpmask = mask;
+               event->group = hup->group;
+               break;
+       case XFS_HEALTHMON_INODE:
+               event->imask = mask;
+               event->ino = hup->ino;
+               event->gen = hup->gen;
+               break;
+       default:
+               ASSERT(0);
+               break;
+       }
+       xfs_healthmon_push(hm, event);
+
+out_unlock:
+       mutex_unlock(&hm->lock);
+       return NOTIFY_DONE;
+}
+
 /* Render the health update type as a string. */
 STATIC const char *
 xfs_healthmon_typestring(
@@ -299,6 +534,10 @@ xfs_healthmon_typestring(
        static const char *type_strings[] = {
                [XFS_HEALTHMON_LOST]            = "lost",
                [XFS_HEALTHMON_SHUTDOWN]        = "shutdown",
+               [XFS_HEALTHMON_UNMOUNT]         = "unmount",
+               [XFS_HEALTHMON_SICK]            = "sick",
+               [XFS_HEALTHMON_CORRUPT]         = "corrupt",
+               [XFS_HEALTHMON_HEALTHY]         = "healthy",
        };
 
        if (event->type >= ARRAY_SIZE(type_strings))
@@ -314,6 +553,11 @@ xfs_healthmon_domstring(
 {
        static const char *dom_strings[] = {
                [XFS_HEALTHMON_MOUNT]           = "mount",
+               [XFS_HEALTHMON_FS]              = "fs",
+               [XFS_HEALTHMON_RT]              = "realtime",
+               [XFS_HEALTHMON_AG]              = "ag",
+               [XFS_HEALTHMON_INODE]           = "inode",
+               [XFS_HEALTHMON_RTGROUP]         = "rtgroup",
        };
 
        if (event->domain >= ARRAY_SIZE(dom_strings))
@@ -339,6 +583,11 @@ xfs_healthmon_format_flags(
                if (!(p->mask & flags))
                        continue;
 
+               if (!p->str) {
+                       flags &= ~p->mask;
+                       continue;
+               }
+
                ret = stdio_redirect_printf(out, false, "%s\"%s\"",
                                first ? "" : ", ", p->str);
                if (ret < 0)
@@ -408,6 +657,132 @@ xfs_healthmon_format_shutdown(
                        event->flags);
 }
 
+/* Render fs sickness mask as a string set */
+static ssize_t
+xfs_healthmon_format_fs(
+       struct stdio_redirect           *out,
+       const struct xfs_healthmon_event *event)
+{
+       static const struct flag_string mask_strings[] = {
+               { XFS_SICK_FS_COUNTERS,         "fscounters" },
+               { XFS_SICK_FS_UQUOTA,           "usrquota" },
+               { XFS_SICK_FS_GQUOTA,           "grpquota" },
+               { XFS_SICK_FS_PQUOTA,           "prjquota" },
+               { XFS_SICK_FS_QUOTACHECK,       "quotacheck" },
+               { XFS_SICK_FS_NLINKS,           "nlinks" },
+               { XFS_SICK_FS_METADIR,          "metadir" },
+               { XFS_SICK_FS_METAPATH,         "metapath" },
+       };
+
+       return xfs_healthmon_format_mask(out, "structures", mask_strings,
+                       event->fsmask);
+}
+
+/* Render rt sickness mask as a string set */
+static ssize_t
+xfs_healthmon_format_rt(
+       struct stdio_redirect           *out,
+       const struct xfs_healthmon_event *event)
+{
+       static const struct flag_string mask_strings[] = {
+               { XFS_SICK_RT_BITMAP,           "bitmap" },
+               { XFS_SICK_RT_SUMMARY,          "summary" },
+       };
+
+       return xfs_healthmon_format_mask(out, "structures", mask_strings,
+                       event->fsmask);
+}
+
+/* Render rtgroup sickness mask as a string set */
+static ssize_t
+xfs_healthmon_format_rtgroup(
+       struct stdio_redirect           *out,
+       const struct xfs_healthmon_event *event)
+{
+       static const struct flag_string mask_strings[] = {
+               { XFS_SICK_RG_SUPER,            "super" },
+               { XFS_SICK_RG_BITMAP,           "bitmap" },
+               { XFS_SICK_RG_RMAPBT,           "rmapbt" },
+               { XFS_SICK_RG_REFCNTBT,         "refcountbt" },
+       };
+       ssize_t                         ret;
+
+       ret = xfs_healthmon_format_mask(out, "structures", mask_strings,
+                       event->grpmask);
+       if (ret < 0)
+               return ret;
+
+       return stdio_redirect_printf(out, false, "  \"group\":      %u,\n",
+                       event->group);
+}
+
+/* Render perag sickness mask as a string set */
+static ssize_t
+xfs_healthmon_format_ag(
+       struct stdio_redirect           *out,
+       const struct xfs_healthmon_event *event)
+{
+       static const struct flag_string mask_strings[] = {
+               { XFS_SICK_AG_SB,               "super" },
+               { XFS_SICK_AG_AGF,              "agf" },
+               { XFS_SICK_AG_AGFL,             "agfl" },
+               { XFS_SICK_AG_AGI,              "agi" },
+               { XFS_SICK_AG_BNOBT,            "bnobt" },
+               { XFS_SICK_AG_CNTBT,            "cntbt" },
+               { XFS_SICK_AG_INOBT,            "inobt" },
+               { XFS_SICK_AG_FINOBT,           "finobt" },
+               { XFS_SICK_AG_RMAPBT,           "rmapbt" },
+               { XFS_SICK_AG_REFCNTBT,         "refcountbt" },
+               { XFS_SICK_AG_INODES,           "inodes" },
+       };
+       ssize_t                         ret;
+
+       ret = xfs_healthmon_format_mask(out, "structures", mask_strings,
+                       event->grpmask);
+       if (ret < 0)
+               return ret;
+
+       return stdio_redirect_printf(out, false, "  \"group\":      %u,\n",
+                       event->group);
+}
+
+/* Render inode sickness mask as a string set */
+static ssize_t
+xfs_healthmon_format_inode(
+       struct stdio_redirect           *out,
+       const struct xfs_healthmon_event *event)
+{
+       static const struct flag_string mask_strings[] = {
+               { XFS_SICK_INO_CORE,            "core" },
+               { XFS_SICK_INO_BMBTD,           "bmapbtd" },
+               { XFS_SICK_INO_BMBTA,           "bmapbta" },
+               { XFS_SICK_INO_BMBTC,           "bmapbtc" },
+               { XFS_SICK_INO_DIR,             "directory" },
+               { XFS_SICK_INO_XATTR,           "xattr" },
+               { XFS_SICK_INO_SYMLINK,         "symlink" },
+               { XFS_SICK_INO_PARENT,          "parent" },
+               { XFS_SICK_INO_BMBTD_ZAPPED,    "bmapbtd_zapped" },
+               { XFS_SICK_INO_BMBTA_ZAPPED,    "bmapbtd_zapped" },
+               { XFS_SICK_INO_DIR_ZAPPED,      "directory_zapped" },
+               { XFS_SICK_INO_SYMLINK_ZAPPED,  "symlink_zapped" },
+               { XFS_SICK_INO_FORGET,          NULL, },
+               { XFS_SICK_INO_DIRTREE,         "dirtree" },
+       };
+       ssize_t                         ret;
+
+       ret = xfs_healthmon_format_mask(out, "structures", mask_strings,
+                       event->imask);
+       if (ret < 0)
+               return ret;
+
+       ret = stdio_redirect_printf(out, false, "  \"inode\":      %llu,\n",
+                       event->ino);
+       if (ret < 0)
+               return ret;
+       return stdio_redirect_printf(out, false, "  \"generation\": %u,\n",
+                       event->gen);
+}
+
 /* Format an event into json. */
 STATIC int
 xfs_healthmon_format(
@@ -446,6 +821,21 @@ xfs_healthmon_format(
        case XFS_HEALTHMON_MOUNT:
                /* empty */
                break;
+       case XFS_HEALTHMON_FS:
+               ret = xfs_healthmon_format_fs(out, event);
+               break;
+       case XFS_HEALTHMON_RT:
+               ret = xfs_healthmon_format_rt(out, event);
+               break;
+       case XFS_HEALTHMON_RTGROUP:
+               ret = xfs_healthmon_format_rtgroup(out, event);
+               break;
+       case XFS_HEALTHMON_AG:
+               ret = xfs_healthmon_format_ag(out, event);
+               break;
+       case XFS_HEALTHMON_INODE:
+               ret = xfs_healthmon_format_inode(out, event);
+               break;
        }
        if (ret < 0)
                return ret;
@@ -551,22 +941,31 @@ xfs_healthmon_create(
                hm->verbose = true;
 
        xfs_shutdown_hook_enable();
+       xfs_health_hook_enable();
 
        xfs_shutdown_hook_setup(&hm->shook, xfs_healthmon_shutdown_hook);
        ret = xfs_shutdown_hook_add(mp, &hm->shook);
        if (ret)
                goto out_hooks;
 
-       ret = run_thread_with_stdout(&hm->thread, &xfs_healthmon_ops);
-       if (ret < 0)
+       xfs_health_hook_setup(&hm->hhook, xfs_healthmon_metadata_hook);
+       ret = xfs_health_hook_add(mp, &hm->hhook);
+       if (ret)
                goto out_shutdown;
 
+       ret = run_thread_with_stdout(&hm->thread, &xfs_healthmon_ops);
+       if (ret < 0)
+               goto out_health;
+
        trace_xfs_healthmon_create(mp, hmo->flags, hmo->format);
 
        return ret;
+out_health:
+       xfs_health_hook_del(mp, &hm->hhook);
 out_shutdown:
        xfs_shutdown_hook_del(mp, &hm->shook);
 out_hooks:
+       xfs_health_hook_disable();
        xfs_shutdown_hook_disable();
        mutex_destroy(&hm->lock);
        xfs_healthmon_free_events(hm);
diff --git a/fs/xfs/xfs_healthmon.h b/fs/xfs/xfs_healthmon.h
index f67e2f1b8f947..e445a89decc57 100644
--- a/fs/xfs/xfs_healthmon.h
+++ b/fs/xfs/xfs_healthmon.h
@@ -11,10 +11,23 @@ enum xfs_healthmon_type {
 
        /* filesystem shutdown */
        XFS_HEALTHMON_SHUTDOWN,
+
+       /* metadata health events */
+       XFS_HEALTHMON_SICK,     /* runtime corruption observed */
+       XFS_HEALTHMON_CORRUPT,  /* fsck reported corruption */
+       XFS_HEALTHMON_HEALTHY,  /* fsck reported healthy structure */
+       XFS_HEALTHMON_UNMOUNT,  /* filesystem is unmounting */
 };
 
 enum xfs_healthmon_domain {
        XFS_HEALTHMON_MOUNT,    /* affects the whole fs */
+
+       /* metadata health events */
+       XFS_HEALTHMON_FS,       /* main filesystem metadata */
+       XFS_HEALTHMON_RT,       /* realtime metadata */
+       XFS_HEALTHMON_AG,       /* allocation group metadata */
+       XFS_HEALTHMON_INODE,    /* inode metadata */
+       XFS_HEALTHMON_RTGROUP,  /* realtime group metadata */
 };
 
 struct xfs_healthmon_event {
@@ -30,6 +43,24 @@ struct xfs_healthmon_event {
                struct {
                        unsigned int    flags;
                };
+               /* fs/rt metadata */
+               struct {
+                       /* XFS_SICK_* flags */
+                       unsigned int    fsmask;
+               };
+               /* ag/rtgroup metadata */
+               struct {
+                       /* XFS_SICK_* flags */
+                       unsigned int    grpmask;
+                       unsigned int    group;
+               };
+               /* inode metadata */
+               struct {
+                       /* XFS_SICK_INO_* flags */
+                       unsigned int    imask;
+                       uint32_t        gen;
+                       xfs_ino_t       ino;
+               };
        };
 };
 
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 54e3d6d549ec1..2f296ba1db822 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -5949,6 +5949,72 @@ TRACE_EVENT(xfs_healthmon_shutdown_hook,
                  __entry->lost_prev)
 );
 
+#define XFS_HEALTHUP_TYPE_STRINGS \
+       { XFS_HEALTHUP_UNMOUNT,         "unmount" }, \
+       { XFS_HEALTHUP_SICK,            "sick" }, \
+       { XFS_HEALTHUP_CORRUPT,         "corrupt" }, \
+       { XFS_HEALTHUP_HEALTHY,         "healthy" }
+
+#define XFS_HEALTHUP_DOMAIN_STRINGS \
+       { XFS_HEALTHUP_FS,              "fs" }, \
+       { XFS_HEALTHUP_RT,              "realtime" }, \
+       { XFS_HEALTHUP_AG,              "ag" }, \
+       { XFS_HEALTHUP_INODE,           "inode" }, \
+       { XFS_HEALTHUP_RTGROUP,         "rtgroup" }
+
+TRACE_DEFINE_ENUM(XFS_HEALTHUP_UNMOUNT);
+TRACE_DEFINE_ENUM(XFS_HEALTHUP_SICK);
+TRACE_DEFINE_ENUM(XFS_HEALTHUP_CORRUPT);
+TRACE_DEFINE_ENUM(XFS_HEALTHUP_HEALTHY);
+
+TRACE_DEFINE_ENUM(XFS_HEALTHUP_FS);
+TRACE_DEFINE_ENUM(XFS_HEALTHUP_RT);
+TRACE_DEFINE_ENUM(XFS_HEALTHUP_AG);
+TRACE_DEFINE_ENUM(XFS_HEALTHUP_INODE);
+TRACE_DEFINE_ENUM(XFS_HEALTHUP_RTGROUP);
+
+TRACE_EVENT(xfs_healthmon_metadata_hook,
+       TP_PROTO(const struct xfs_mount *mp, unsigned long type,
+                const struct xfs_health_update_params *update,
+                unsigned int events, bool lost_prev),
+       TP_ARGS(mp, type, update, events, lost_prev),
+       TP_STRUCT__entry(
+               __field(dev_t, dev)
+               __field(unsigned long, type)
+               __field(unsigned int, domain)
+               __field(unsigned int, old_mask)
+               __field(unsigned int, new_mask)
+               __field(unsigned long long, ino)
+               __field(unsigned int, gen)
+               __field(unsigned int, group)
+               __field(unsigned int, events)
+               __field(bool, lost_prev)
+       ),
+       TP_fast_assign(
+               __entry->dev = mp ? mp->m_super->s_dev : 0;
+               __entry->type = type;
+               __entry->domain = update->domain;
+               __entry->old_mask = update->old_mask;
+               __entry->new_mask = update->new_mask;
+               __entry->ino = update->ino;
+               __entry->gen = update->gen;
+               __entry->group = update->group;
+               __entry->events = events;
+               __entry->lost_prev = lost_prev;
+       ),
+       TP_printk("dev %d:%d type %s domain %s oldmask 0x%x newmask 0x%x ino 
0x%llx gen 0x%x group 0x%x events %u lost_prev? %d",
+                 MAJOR(__entry->dev), MINOR(__entry->dev),
+                 __print_symbolic(__entry->type, XFS_HEALTHUP_TYPE_STRINGS),
+                 __print_symbolic(__entry->domain, 
XFS_HEALTHUP_DOMAIN_STRINGS),
+                 __entry->old_mask,
+                 __entry->new_mask,
+                 __entry->ino,
+                 __entry->gen,
+                 __entry->group,
+                 __entry->events,
+                 __entry->lost_prev)
+);
+
 DECLARE_EVENT_CLASS(xfs_healthmon_class,
        TP_PROTO(const struct xfs_mount *mp, unsigned int events, bool 
lost_prev),
        TP_ARGS(mp, events, lost_prev),
@@ -5979,15 +6045,33 @@ DEFINE_HEALTHMON_EVENT(xfs_healthmon_unmount);
 
 #define XFS_HEALTHMON_TYPE_STRINGS \
        { XFS_HEALTHMON_LOST,           "lost" }, \
-       { XFS_HEALTHMON_SHUTDOWN,       "shutdown" }
+       { XFS_HEALTHMON_SHUTDOWN,       "shutdown" }, \
+       { XFS_HEALTHMON_UNMOUNT,        "unmount" }, \
+       { XFS_HEALTHMON_SICK,           "sick" }, \
+       { XFS_HEALTHMON_CORRUPT,        "corrupt" }, \
+       { XFS_HEALTHMON_HEALTHY,        "healthy" }
 
 #define XFS_HEALTHMON_DOMAIN_STRINGS \
-       { XFS_HEALTHMON_MOUNT,          "mount" }
+       { XFS_HEALTHMON_MOUNT,          "mount" }, \
+       { XFS_HEALTHMON_FS,             "fs" }, \
+       { XFS_HEALTHMON_RT,             "realtime" }, \
+       { XFS_HEALTHMON_AG,             "ag" }, \
+       { XFS_HEALTHMON_INODE,          "inode" }, \
+       { XFS_HEALTHMON_RTGROUP,        "rtgroup" }
 
 TRACE_DEFINE_ENUM(XFS_HEALTHMON_LOST);
 TRACE_DEFINE_ENUM(XFS_HEALTHMON_SHUTDOWN);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_UNMOUNT);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_SICK);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_CORRUPT);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_HEALTHY);
 
 TRACE_DEFINE_ENUM(XFS_HEALTHMON_MOUNT);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_FS);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_RT);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_AG);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_INODE);
+TRACE_DEFINE_ENUM(XFS_HEALTHMON_RTGROUP);
 
 DECLARE_EVENT_CLASS(xfs_healthmon_event_class,
        TP_PROTO(const struct xfs_mount *mp, const struct xfs_healthmon_event 
*event),
@@ -6009,6 +6093,20 @@ DECLARE_EVENT_CLASS(xfs_healthmon_event_class,
                case XFS_HEALTHMON_MOUNT:
                        __entry->mask = event->flags;
                        break;
+               case XFS_HEALTHMON_FS:
+               case XFS_HEALTHMON_RT:
+                       __entry->mask = event->fsmask;
+                       break;
+               case XFS_HEALTHMON_AG:
+               case XFS_HEALTHMON_RTGROUP:
+                       __entry->mask = event->grpmask;
+                       __entry->group = event->group;
+                       break;
+               case XFS_HEALTHMON_INODE:
+                       __entry->mask = event->imask;
+                       __entry->ino = event->ino;
+                       __entry->gen = event->gen;
+                       break;
                }
        ),
        TP_printk("dev %d:%d type %s domain %s mask 0x%x ino 0x%llx gen 0x%x 
group 0x%x",


Reply via email to