/* affects the whole fs */
#define XFS_HEALTH_MONITOR_DOMAIN_MOUNT (0)
+/* metadata health events */
+#define XFS_HEALTH_MONITOR_DOMAIN_FS (1)
+#define XFS_HEALTH_MONITOR_DOMAIN_AG (2)
+#define XFS_HEALTH_MONITOR_DOMAIN_INODE (3)
+#define XFS_HEALTH_MONITOR_DOMAIN_RTGROUP (4)
+
/* Health monitor event types */
/* status of the monitor itself */
/* filesystem was unmounted */
#define XFS_HEALTH_MONITOR_TYPE_UNMOUNT (2)
+/* metadata health events */
+#define XFS_HEALTH_MONITOR_TYPE_SICK (3)
+#define XFS_HEALTH_MONITOR_TYPE_CORRUPT (4)
+#define XFS_HEALTH_MONITOR_TYPE_HEALTHY (5)
+
/* lost events */
struct xfs_health_monitor_lost {
__u64 count;
};
+/* fs/rt metadata */
+struct xfs_health_monitor_fs {
+ /* XFS_FSOP_GEOM_SICK_* flags */
+ __u32 mask;
+};
+
+/* ag/rtgroup metadata */
+struct xfs_health_monitor_group {
+ /* XFS_{AG,RTGROUP}_SICK_* flags */
+ __u32 mask;
+ __u32 gno;
+};
+
+/* inode metadata */
+struct xfs_health_monitor_inode {
+ /* XFS_BS_SICK_* flags */
+ __u32 mask;
+ __u32 gen;
+ __u64 ino;
+};
+
struct xfs_health_monitor_event {
/* XFS_HEALTH_MONITOR_DOMAIN_* */
__u32 domain;
*/
union {
struct xfs_health_monitor_lost lost;
+ struct xfs_health_monitor_fs fs;
+ struct xfs_health_monitor_group group;
+ struct xfs_health_monitor_inode inode;
} e;
/* zeroes */
#define xfs_metadata_is_sick(error) \
(unlikely((error) == -EFSCORRUPTED || (error) == -EFSBADCRC))
+unsigned int xfs_healthmon_inode_mask(unsigned int sick_mask);
+unsigned int xfs_healthmon_rtgroup_mask(unsigned int sick_mask);
+unsigned int xfs_healthmon_perag_mask(unsigned int sick_mask);
+unsigned int xfs_healthmon_fs_mask(unsigned int sick_mask);
+
#endif /* __XFS_HEALTH_H__ */
struct xfs_mount *mp,
unsigned int mask)
{
+ unsigned int old_mask;
+
ASSERT(!(mask & ~XFS_SICK_FS_ALL));
trace_xfs_fs_mark_sick(mp, mask);
spin_lock(&mp->m_sb_lock);
+ old_mask = mp->m_fs_sick;
mp->m_fs_sick |= mask;
spin_unlock(&mp->m_sb_lock);
fserror_report_metadata(mp->m_super, -EFSCORRUPTED, GFP_NOFS);
+ if (mask)
+ xfs_healthmon_report_fs(mp, XFS_HEALTHMON_SICK, old_mask, mask);
}
/* Mark per-fs metadata as having been checked and found unhealthy by fsck. */
struct xfs_mount *mp,
unsigned int mask)
{
+ unsigned int old_mask;
+
ASSERT(!(mask & ~XFS_SICK_FS_ALL));
trace_xfs_fs_mark_corrupt(mp, mask);
spin_lock(&mp->m_sb_lock);
+ old_mask = mp->m_fs_sick;
mp->m_fs_sick |= mask;
mp->m_fs_checked |= mask;
spin_unlock(&mp->m_sb_lock);
fserror_report_metadata(mp->m_super, -EFSCORRUPTED, GFP_NOFS);
+ if (mask)
+ xfs_healthmon_report_fs(mp, XFS_HEALTHMON_CORRUPT, old_mask,
+ mask);
}
/* Mark a per-fs metadata healed. */
struct xfs_mount *mp,
unsigned int mask)
{
+ unsigned int old_mask;
+
ASSERT(!(mask & ~XFS_SICK_FS_ALL));
trace_xfs_fs_mark_healthy(mp, mask);
spin_lock(&mp->m_sb_lock);
+ old_mask = mp->m_fs_sick;
mp->m_fs_sick &= ~mask;
if (!(mp->m_fs_sick & XFS_SICK_FS_PRIMARY))
mp->m_fs_sick &= ~XFS_SICK_FS_SECONDARY;
mp->m_fs_checked |= mask;
spin_unlock(&mp->m_sb_lock);
+
+ if (mask)
+ xfs_healthmon_report_fs(mp, XFS_HEALTHMON_HEALTHY, old_mask,
+ mask);
}
/* Sample which per-fs metadata are unhealthy. */
struct xfs_group *xg,
unsigned int mask)
{
+ unsigned int old_mask;
+
xfs_group_check_mask(xg, mask);
trace_xfs_group_mark_sick(xg, mask);
spin_lock(&xg->xg_state_lock);
+ old_mask = xg->xg_sick;
xg->xg_sick |= mask;
spin_unlock(&xg->xg_state_lock);
fserror_report_metadata(xg->xg_mount->m_super, -EFSCORRUPTED, GFP_NOFS);
+ if (mask)
+ xfs_healthmon_report_group(xg, XFS_HEALTHMON_SICK, old_mask,
+ mask);
}
/*
struct xfs_group *xg,
unsigned int mask)
{
+ unsigned int old_mask;
+
xfs_group_check_mask(xg, mask);
trace_xfs_group_mark_corrupt(xg, mask);
spin_lock(&xg->xg_state_lock);
+ old_mask = xg->xg_sick;
xg->xg_sick |= mask;
xg->xg_checked |= mask;
spin_unlock(&xg->xg_state_lock);
fserror_report_metadata(xg->xg_mount->m_super, -EFSCORRUPTED, GFP_NOFS);
+ if (mask)
+ xfs_healthmon_report_group(xg, XFS_HEALTHMON_CORRUPT, old_mask,
+ mask);
}
/*
struct xfs_group *xg,
unsigned int mask)
{
+ unsigned int old_mask;
+
xfs_group_check_mask(xg, mask);
trace_xfs_group_mark_healthy(xg, mask);
spin_lock(&xg->xg_state_lock);
+ old_mask = xg->xg_sick;
xg->xg_sick &= ~mask;
if (!(xg->xg_sick & XFS_SICK_AG_PRIMARY))
xg->xg_sick &= ~XFS_SICK_AG_SECONDARY;
xg->xg_checked |= mask;
spin_unlock(&xg->xg_state_lock);
+
+ if (mask)
+ xfs_healthmon_report_group(xg, XFS_HEALTHMON_HEALTHY, old_mask,
+ mask);
}
/* Sample which per-ag metadata are unhealthy. */
struct xfs_inode *ip,
unsigned int mask)
{
+ unsigned int old_mask;
+
ASSERT(!(mask & ~XFS_SICK_INO_ALL));
trace_xfs_inode_mark_sick(ip, mask);
spin_lock(&ip->i_flags_lock);
+ old_mask = ip->i_sick;
ip->i_sick |= mask;
spin_unlock(&ip->i_flags_lock);
spin_unlock(&VFS_I(ip)->i_lock);
fserror_report_file_metadata(VFS_I(ip), -EFSCORRUPTED, GFP_NOFS);
+ if (mask)
+ xfs_healthmon_report_inode(ip, XFS_HEALTHMON_SICK, old_mask,
+ mask);
}
/* Mark inode metadata as having been checked and found unhealthy by fsck. */
struct xfs_inode *ip,
unsigned int mask)
{
+ unsigned int old_mask;
+
ASSERT(!(mask & ~XFS_SICK_INO_ALL));
trace_xfs_inode_mark_corrupt(ip, mask);
spin_lock(&ip->i_flags_lock);
+ old_mask = ip->i_sick;
ip->i_sick |= mask;
ip->i_checked |= mask;
spin_unlock(&ip->i_flags_lock);
spin_unlock(&VFS_I(ip)->i_lock);
fserror_report_file_metadata(VFS_I(ip), -EFSCORRUPTED, GFP_NOFS);
+ if (mask)
+ xfs_healthmon_report_inode(ip, XFS_HEALTHMON_CORRUPT, old_mask,
+ mask);
}
/* Mark parts of an inode healed. */
struct xfs_inode *ip,
unsigned int mask)
{
+ unsigned int old_mask;
+
ASSERT(!(mask & ~XFS_SICK_INO_ALL));
trace_xfs_inode_mark_healthy(ip, mask);
spin_lock(&ip->i_flags_lock);
+ old_mask = ip->i_sick;
ip->i_sick &= ~mask;
if (!(ip->i_sick & XFS_SICK_INO_PRIMARY))
ip->i_sick &= ~XFS_SICK_INO_SECONDARY;
ip->i_checked |= mask;
spin_unlock(&ip->i_flags_lock);
+
+ if (mask)
+ xfs_healthmon_report_inode(ip, XFS_HEALTHMON_HEALTHY, old_mask,
+ mask);
}
/* Sample which parts of an inode are unhealthy. */
}
}
+/*
+ * Translate XFS_SICK_FS_* into XFS_FSOP_GEOM_SICK_* except for the rt free
+ * space codes, which are sent via the rtgroup events.
+ */
+unsigned int
+xfs_healthmon_fs_mask(
+ unsigned int sick_mask)
+{
+ const struct ioctl_sick_map *m;
+ unsigned int ioctl_mask = 0;
+
+ for_each_sick_map(fs_map, m) {
+ if (sick_mask & m->sick_mask)
+ ioctl_mask |= m->ioctl_mask;
+ }
+
+ return ioctl_mask;
+}
+
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 },
}
}
+/* Translate XFS_SICK_AG_* into XFS_AG_GEOM_SICK_*. */
+unsigned int
+xfs_healthmon_perag_mask(
+ unsigned int sick_mask)
+{
+ const struct ioctl_sick_map *m;
+ unsigned int ioctl_mask = 0;
+
+ for_each_sick_map(ag_map, m) {
+ if (sick_mask & m->sick_mask)
+ ioctl_mask |= m->ioctl_mask;
+ }
+
+ return ioctl_mask;
+}
+
static const struct ioctl_sick_map rtgroup_map[] = {
{ XFS_SICK_RG_SUPER, XFS_RTGROUP_GEOM_SICK_SUPER },
{ XFS_SICK_RG_BITMAP, XFS_RTGROUP_GEOM_SICK_BITMAP },
}
}
+/* Translate XFS_SICK_RG_* into XFS_RTGROUP_GEOM_SICK_*. */
+unsigned int
+xfs_healthmon_rtgroup_mask(
+ unsigned int sick_mask)
+{
+ const struct ioctl_sick_map *m;
+ unsigned int ioctl_mask = 0;
+
+ for_each_sick_map(rtgroup_map, m) {
+ if (sick_mask & m->sick_mask)
+ ioctl_mask |= m->ioctl_mask;
+ }
+
+ return ioctl_mask;
+}
+
static const struct ioctl_sick_map ino_map[] = {
{ XFS_SICK_INO_CORE, XFS_BS_SICK_INODE },
{ XFS_SICK_INO_BMBTD, XFS_BS_SICK_BMBTD },
}
}
+/* Translate XFS_SICK_INO_* into XFS_BS_SICK_*. */
+unsigned int
+xfs_healthmon_inode_mask(
+ unsigned int sick_mask)
+{
+ const struct ioctl_sick_map *m;
+ unsigned int ioctl_mask = 0;
+
+ for_each_sick_map(ino_map, m) {
+ if (sick_mask & m->sick_mask)
+ ioctl_mask |= m->ioctl_mask;
+ }
+
+ return ioctl_mask;
+}
+
/* Mark a block mapping sick. */
void
xfs_bmap_mark_sick(
#include "xfs_da_btree.h"
#include "xfs_quota_defs.h"
#include "xfs_rtgroup.h"
+#include "xfs_health.h"
#include "xfs_healthmon.h"
#include <linux/anon_inodes.h>
case XFS_HEALTHMON_LOST:
existing->lostcount += new->lostcount;
return true;
+
+ case XFS_HEALTHMON_SICK:
+ case XFS_HEALTHMON_CORRUPT:
+ case XFS_HEALTHMON_HEALTHY:
+ switch (existing->domain) {
+ case XFS_HEALTHMON_FS:
+ existing->fsmask |= new->fsmask;
+ return true;
+ case XFS_HEALTHMON_AG:
+ case XFS_HEALTHMON_RTGROUP:
+ if (existing->group == new->group){
+ existing->grpmask |= new->grpmask;
+ return true;
+ }
+ return false;
+ case XFS_HEALTHMON_INODE:
+ if (existing->ino == new->ino &&
+ existing->gen == new->gen) {
+ existing->imask |= new->imask;
+ return true;
+ }
+ return false;
+ default:
+ ASSERT(0);
+ return false;
+ }
+ return false;
}
return false;
xfs_healthmon_put(hm);
}
+/* Compute the reporting mask for non-unmount metadata health events. */
+static inline unsigned int
+metadata_event_mask(
+ struct xfs_healthmon *hm,
+ enum xfs_healthmon_type type,
+ unsigned int old_mask,
+ unsigned int new_mask)
+{
+ /* If we want all events, return all events. */
+ if (hm->verbose)
+ return new_mask;
+
+ switch (type) {
+ case XFS_HEALTHMON_SICK:
+ /* Always report runtime corruptions */
+ return new_mask;
+ case XFS_HEALTHMON_CORRUPT:
+ /* Only report new fsck errors */
+ return new_mask & ~old_mask;
+ case XFS_HEALTHMON_HEALTHY:
+ /* Only report healthy metadata that got fixed */
+ return new_mask & old_mask;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ return 0;
+}
+
+/* Report XFS_FS_SICK_* events to healthmon */
+void
+xfs_healthmon_report_fs(
+ struct xfs_mount *mp,
+ enum xfs_healthmon_type type,
+ unsigned int old_mask,
+ unsigned int new_mask)
+{
+ struct xfs_healthmon_event event = {
+ .type = type,
+ .domain = XFS_HEALTHMON_FS,
+ };
+ struct xfs_healthmon *hm = xfs_healthmon_get(mp);
+
+ if (!hm)
+ return;
+
+ event.fsmask = metadata_event_mask(hm, type, old_mask, new_mask) &
+ ~XFS_SICK_FS_SECONDARY;
+ trace_xfs_healthmon_report_fs(hm, old_mask, new_mask, &event);
+
+ if (event.fsmask)
+ xfs_healthmon_push(hm, &event);
+
+ xfs_healthmon_put(hm);
+}
+
+/* Report XFS_SICK_(AG|RG)* flags to healthmon */
+void
+xfs_healthmon_report_group(
+ struct xfs_group *xg,
+ enum xfs_healthmon_type type,
+ unsigned int old_mask,
+ unsigned int new_mask)
+{
+ struct xfs_healthmon_event event = {
+ .type = type,
+ .group = xg->xg_gno,
+ };
+ struct xfs_healthmon *hm = xfs_healthmon_get(xg->xg_mount);
+
+ if (!hm)
+ return;
+
+ switch (xg->xg_type) {
+ case XG_TYPE_RTG:
+ event.domain = XFS_HEALTHMON_RTGROUP;
+ event.grpmask = metadata_event_mask(hm, type, old_mask,
+ new_mask) &
+ ~XFS_SICK_RG_SECONDARY;
+ break;
+ case XG_TYPE_AG:
+ event.domain = XFS_HEALTHMON_AG;
+ event.grpmask = metadata_event_mask(hm, type, old_mask,
+ new_mask) &
+ ~XFS_SICK_AG_SECONDARY;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ trace_xfs_healthmon_report_group(hm, old_mask, new_mask, &event);
+
+ if (event.grpmask)
+ xfs_healthmon_push(hm, &event);
+
+ xfs_healthmon_put(hm);
+}
+
+/* Report XFS_SICK_INO_* flags to healthmon */
+void
+xfs_healthmon_report_inode(
+ struct xfs_inode *ip,
+ enum xfs_healthmon_type type,
+ unsigned int old_mask,
+ unsigned int new_mask)
+{
+ struct xfs_healthmon_event event = {
+ .type = type,
+ .domain = XFS_HEALTHMON_INODE,
+ .ino = ip->i_ino,
+ .gen = VFS_I(ip)->i_generation,
+ };
+ struct xfs_healthmon *hm = xfs_healthmon_get(ip->i_mount);
+
+ if (!hm)
+ return;
+
+ event.imask = metadata_event_mask(hm, type, old_mask, new_mask) &
+ ~XFS_SICK_INO_SECONDARY;
+ trace_xfs_healthmon_report_inode(hm, old_mask, event.imask, &event);
+
+ if (event.imask)
+ xfs_healthmon_push(hm, &event);
+
+ xfs_healthmon_put(hm);
+}
+
static inline void
xfs_healthmon_reset_outbuf(
struct xfs_healthmon *hm)
static const unsigned int domain_map[] = {
[XFS_HEALTHMON_MOUNT] = XFS_HEALTH_MONITOR_DOMAIN_MOUNT,
+ [XFS_HEALTHMON_FS] = XFS_HEALTH_MONITOR_DOMAIN_FS,
+ [XFS_HEALTHMON_AG] = XFS_HEALTH_MONITOR_DOMAIN_AG,
+ [XFS_HEALTHMON_INODE] = XFS_HEALTH_MONITOR_DOMAIN_INODE,
+ [XFS_HEALTHMON_RTGROUP] = XFS_HEALTH_MONITOR_DOMAIN_RTGROUP,
};
static const unsigned int type_map[] = {
[XFS_HEALTHMON_RUNNING] = XFS_HEALTH_MONITOR_TYPE_RUNNING,
[XFS_HEALTHMON_LOST] = XFS_HEALTH_MONITOR_TYPE_LOST,
+ [XFS_HEALTHMON_SICK] = XFS_HEALTH_MONITOR_TYPE_SICK,
+ [XFS_HEALTHMON_CORRUPT] = XFS_HEALTH_MONITOR_TYPE_CORRUPT,
+ [XFS_HEALTHMON_HEALTHY] = XFS_HEALTH_MONITOR_TYPE_HEALTHY,
+ [XFS_HEALTHMON_UNMOUNT] = XFS_HEALTH_MONITOR_TYPE_UNMOUNT,
};
/* Render event as a V0 structure */
break;
}
break;
+ case XFS_HEALTHMON_FS:
+ hme.e.fs.mask = xfs_healthmon_fs_mask(event->fsmask);
+ break;
+ case XFS_HEALTHMON_RTGROUP:
+ hme.e.group.mask = xfs_healthmon_rtgroup_mask(event->grpmask);
+ hme.e.group.gno = event->group;
+ break;
+ case XFS_HEALTHMON_AG:
+ hme.e.group.mask = xfs_healthmon_perag_mask(event->grpmask);
+ hme.e.group.gno = event->group;
+ break;
+ case XFS_HEALTHMON_INODE:
+ hme.e.inode.mask = xfs_healthmon_inode_mask(event->imask);
+ hme.e.inode.ino = event->ino;
+ hme.e.inode.gen = event->gen;
+ break;
default:
break;
}
XFS_HEALTHMON_RUNNING, /* monitor running */
XFS_HEALTHMON_LOST, /* message lost */
XFS_HEALTHMON_UNMOUNT, /* filesystem is unmounting */
+
+ /* metadata health events */
+ XFS_HEALTHMON_SICK, /* runtime corruption observed */
+ XFS_HEALTHMON_CORRUPT, /* fsck reported corruption */
+ XFS_HEALTHMON_HEALTHY, /* fsck reported healthy structure */
};
enum xfs_healthmon_domain {
XFS_HEALTHMON_MOUNT, /* affects the whole fs */
+
+ /* metadata health events */
+ XFS_HEALTHMON_FS, /* main filesystem metadata */
+ XFS_HEALTHMON_AG, /* allocation group metadata */
+ XFS_HEALTHMON_INODE, /* inode metadata */
+ XFS_HEALTHMON_RTGROUP, /* realtime group metadata */
};
struct xfs_healthmon_event {
struct {
uint64_t lostcount;
};
+ /* fs/rt metadata */
+ struct {
+ /* XFS_SICK_* flags */
+ unsigned int fsmask;
+ };
+ /* ag/rtgroup metadata */
+ struct {
+ /* XFS_SICK_(AG|RG)* flags */
+ unsigned int grpmask;
+ unsigned int group;
+ };
+ /* inode metadata */
+ struct {
+ /* XFS_SICK_INO_* flags */
+ unsigned int imask;
+ uint32_t gen;
+ xfs_ino_t ino;
+ };
};
};
+void xfs_healthmon_report_fs(struct xfs_mount *mp,
+ enum xfs_healthmon_type type, unsigned int old_mask,
+ unsigned int new_mask);
+void xfs_healthmon_report_group(struct xfs_group *xg,
+ enum xfs_healthmon_type type, unsigned int old_mask,
+ unsigned int new_mask);
+void xfs_healthmon_report_inode(struct xfs_inode *ip,
+ enum xfs_healthmon_type type, unsigned int old_mask,
+ unsigned int new_mask);
+
long xfs_ioc_health_monitor(struct file *file,
struct xfs_health_monitor __user *arg);
#define XFS_HEALTHMON_TYPE_STRINGS \
{ XFS_HEALTHMON_LOST, "lost" }, \
- { XFS_HEALTHMON_UNMOUNT, "unmount" }
+ { 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_AG, "ag" }, \
+ { XFS_HEALTHMON_INODE, "inode" }, \
+ { XFS_HEALTHMON_RTGROUP, "rtgroup" }
TRACE_DEFINE_ENUM(XFS_HEALTHMON_LOST);
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_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_healthmon *hm,
break;
}
break;
+ case XFS_HEALTHMON_FS:
+ __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 offset 0x%llx len 0x%llx group 0x%x lost %llu",
DEFINE_HEALTHMONEVENT_EVENT(xfs_healthmon_drop);
DEFINE_HEALTHMONEVENT_EVENT(xfs_healthmon_merge);
+TRACE_EVENT(xfs_healthmon_report_fs,
+ TP_PROTO(const struct xfs_healthmon *hm,
+ unsigned int old_mask, unsigned int new_mask,
+ const struct xfs_healthmon_event *event),
+ TP_ARGS(hm, old_mask, new_mask, event),
+ TP_STRUCT__entry(
+ __field(dev_t, dev)
+ __field(unsigned int, type)
+ __field(unsigned int, domain)
+ __field(unsigned int, old_mask)
+ __field(unsigned int, new_mask)
+ __field(unsigned int, fsmask)
+ ),
+ TP_fast_assign(
+ __entry->dev = hm->dev;
+ __entry->type = event->type;
+ __entry->domain = event->domain;
+ __entry->old_mask = old_mask;
+ __entry->new_mask = new_mask;
+ __entry->fsmask = event->fsmask;
+ ),
+ TP_printk("dev %d:%d type %s domain %s oldmask 0x%x newmask 0x%x fsmask 0x%x",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __print_symbolic(__entry->type, XFS_HEALTHMON_TYPE_STRINGS),
+ __print_symbolic(__entry->domain, XFS_HEALTHMON_DOMAIN_STRINGS),
+ __entry->old_mask,
+ __entry->new_mask,
+ __entry->fsmask)
+);
+
+TRACE_EVENT(xfs_healthmon_report_group,
+ TP_PROTO(const struct xfs_healthmon *hm,
+ unsigned int old_mask, unsigned int new_mask,
+ const struct xfs_healthmon_event *event),
+ TP_ARGS(hm, old_mask, new_mask, event),
+ TP_STRUCT__entry(
+ __field(dev_t, dev)
+ __field(unsigned int, type)
+ __field(unsigned int, domain)
+ __field(unsigned int, old_mask)
+ __field(unsigned int, new_mask)
+ __field(unsigned int, grpmask)
+ __field(unsigned int, group)
+ ),
+ TP_fast_assign(
+ __entry->dev = hm->dev;
+ __entry->type = event->type;
+ __entry->domain = event->domain;
+ __entry->old_mask = old_mask;
+ __entry->new_mask = new_mask;
+ __entry->grpmask = event->grpmask;
+ __entry->group = event->group;
+ ),
+ TP_printk("dev %d:%d type %s domain %s oldmask 0x%x newmask 0x%x grpmask 0x%x group 0x%x",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __print_symbolic(__entry->type, XFS_HEALTHMON_TYPE_STRINGS),
+ __print_symbolic(__entry->domain, XFS_HEALTHMON_DOMAIN_STRINGS),
+ __entry->old_mask,
+ __entry->new_mask,
+ __entry->grpmask,
+ __entry->group)
+);
+
+TRACE_EVENT(xfs_healthmon_report_inode,
+ TP_PROTO(const struct xfs_healthmon *hm,
+ unsigned int old_mask, unsigned int new_mask,
+ const struct xfs_healthmon_event *event),
+ TP_ARGS(hm, old_mask, new_mask, event),
+ TP_STRUCT__entry(
+ __field(dev_t, dev)
+ __field(unsigned int, type)
+ __field(unsigned int, domain)
+ __field(unsigned int, old_mask)
+ __field(unsigned int, new_mask)
+ __field(unsigned int, imask)
+ __field(unsigned long long, ino)
+ __field(unsigned int, gen)
+ ),
+ TP_fast_assign(
+ __entry->dev = hm->dev;
+ __entry->type = event->type;
+ __entry->domain = event->domain;
+ __entry->old_mask = old_mask;
+ __entry->new_mask = new_mask;
+ __entry->imask = event->imask;
+ __entry->ino = event->ino;
+ __entry->gen = event->gen;
+ ),
+ TP_printk("dev %d:%d type %s domain %s oldmask 0x%x newmask 0x%x imask 0x%x ino 0x%llx gen 0x%x",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __print_symbolic(__entry->type, XFS_HEALTHMON_TYPE_STRINGS),
+ __print_symbolic(__entry->domain, XFS_HEALTHMON_DOMAIN_STRINGS),
+ __entry->old_mask,
+ __entry->new_mask,
+ __entry->imask,
+ __entry->ino,
+ __entry->gen)
+);
+
#endif /* _TRACE_XFS_H */
#undef TRACE_INCLUDE_PATH