mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 14:42:08 +02:00
xfs: convey filesystem shutdown events to the health monitor
Connect the filesystem shutdown code to the health monitor so that xfs can send events about that to the xfs_healer daemon. Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
5eb4cb18e4
commit
74c4795e50
|
|
@ -1028,6 +1028,9 @@ struct xfs_rtgroup_geometry {
|
|||
#define XFS_HEALTH_MONITOR_TYPE_CORRUPT (4)
|
||||
#define XFS_HEALTH_MONITOR_TYPE_HEALTHY (5)
|
||||
|
||||
/* filesystem shutdown */
|
||||
#define XFS_HEALTH_MONITOR_TYPE_SHUTDOWN (6)
|
||||
|
||||
/* lost events */
|
||||
struct xfs_health_monitor_lost {
|
||||
__u64 count;
|
||||
|
|
@ -1054,6 +1057,20 @@ struct xfs_health_monitor_inode {
|
|||
__u64 ino;
|
||||
};
|
||||
|
||||
/* shutdown reasons */
|
||||
#define XFS_HEALTH_SHUTDOWN_META_IO_ERROR (1u << 0)
|
||||
#define XFS_HEALTH_SHUTDOWN_LOG_IO_ERROR (1u << 1)
|
||||
#define XFS_HEALTH_SHUTDOWN_FORCE_UMOUNT (1u << 2)
|
||||
#define XFS_HEALTH_SHUTDOWN_CORRUPT_INCORE (1u << 3)
|
||||
#define XFS_HEALTH_SHUTDOWN_CORRUPT_ONDISK (1u << 4)
|
||||
#define XFS_HEALTH_SHUTDOWN_DEVICE_REMOVED (1u << 5)
|
||||
|
||||
/* shutdown */
|
||||
struct xfs_health_monitor_shutdown {
|
||||
/* XFS_HEALTH_SHUTDOWN_* flags */
|
||||
__u32 reasons;
|
||||
};
|
||||
|
||||
struct xfs_health_monitor_event {
|
||||
/* XFS_HEALTH_MONITOR_DOMAIN_* */
|
||||
__u32 domain;
|
||||
|
|
@ -1074,6 +1091,7 @@ struct xfs_health_monitor_event {
|
|||
struct xfs_health_monitor_fs fs;
|
||||
struct xfs_health_monitor_group group;
|
||||
struct xfs_health_monitor_inode inode;
|
||||
struct xfs_health_monitor_shutdown shutdown;
|
||||
} e;
|
||||
|
||||
/* zeroes */
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "xfs_rtrmap_btree.h"
|
||||
#include "xfs_rtrefcount_btree.h"
|
||||
#include "xfs_metafile.h"
|
||||
#include "xfs_healthmon.h"
|
||||
|
||||
#include <linux/fserror.h>
|
||||
|
||||
|
|
@ -544,6 +545,7 @@ xfs_do_force_shutdown(
|
|||
xfs_stack_trace();
|
||||
|
||||
fserror_report_shutdown(mp->m_super, GFP_KERNEL);
|
||||
xfs_healthmon_report_shutdown(mp, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "xfs_rtgroup.h"
|
||||
#include "xfs_health.h"
|
||||
#include "xfs_healthmon.h"
|
||||
#include "xfs_fsops.h"
|
||||
|
||||
#include <linux/anon_inodes.h>
|
||||
#include <linux/eventpoll.h>
|
||||
|
|
@ -202,6 +203,11 @@ xfs_healthmon_merge_events(
|
|||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
case XFS_HEALTHMON_SHUTDOWN:
|
||||
/* yes, we can race to shutdown */
|
||||
existing->flags |= new->flags;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -494,6 +500,28 @@ xfs_healthmon_report_inode(
|
|||
xfs_healthmon_put(hm);
|
||||
}
|
||||
|
||||
/* Add a shutdown event to the reporting queue. */
|
||||
void
|
||||
xfs_healthmon_report_shutdown(
|
||||
struct xfs_mount *mp,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct xfs_healthmon_event event = {
|
||||
.type = XFS_HEALTHMON_SHUTDOWN,
|
||||
.domain = XFS_HEALTHMON_MOUNT,
|
||||
.flags = flags,
|
||||
};
|
||||
struct xfs_healthmon *hm = xfs_healthmon_get(mp);
|
||||
|
||||
if (!hm)
|
||||
return;
|
||||
|
||||
trace_xfs_healthmon_report_shutdown(hm, flags);
|
||||
|
||||
xfs_healthmon_push(hm, &event);
|
||||
xfs_healthmon_put(hm);
|
||||
}
|
||||
|
||||
static inline void
|
||||
xfs_healthmon_reset_outbuf(
|
||||
struct xfs_healthmon *hm)
|
||||
|
|
@ -502,6 +530,44 @@ xfs_healthmon_reset_outbuf(
|
|||
hm->bufhead = 0;
|
||||
}
|
||||
|
||||
struct flags_map {
|
||||
unsigned int in_mask;
|
||||
unsigned int out_mask;
|
||||
};
|
||||
|
||||
static const struct flags_map shutdown_map[] = {
|
||||
{ SHUTDOWN_META_IO_ERROR, XFS_HEALTH_SHUTDOWN_META_IO_ERROR },
|
||||
{ SHUTDOWN_LOG_IO_ERROR, XFS_HEALTH_SHUTDOWN_LOG_IO_ERROR },
|
||||
{ SHUTDOWN_FORCE_UMOUNT, XFS_HEALTH_SHUTDOWN_FORCE_UMOUNT },
|
||||
{ SHUTDOWN_CORRUPT_INCORE, XFS_HEALTH_SHUTDOWN_CORRUPT_INCORE },
|
||||
{ SHUTDOWN_CORRUPT_ONDISK, XFS_HEALTH_SHUTDOWN_CORRUPT_ONDISK },
|
||||
{ SHUTDOWN_DEVICE_REMOVED, XFS_HEALTH_SHUTDOWN_DEVICE_REMOVED },
|
||||
};
|
||||
|
||||
static inline unsigned int
|
||||
__map_flags(
|
||||
const struct flags_map *map,
|
||||
size_t array_len,
|
||||
unsigned int flags)
|
||||
{
|
||||
const struct flags_map *m;
|
||||
unsigned int ret = 0;
|
||||
|
||||
for (m = map; m < map + array_len; m++) {
|
||||
if (flags & m->in_mask)
|
||||
ret |= m->out_mask;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define map_flags(map, flags) __map_flags((map), ARRAY_SIZE(map), (flags))
|
||||
|
||||
static inline unsigned int shutdown_mask(unsigned int in)
|
||||
{
|
||||
return map_flags(shutdown_map, in);
|
||||
}
|
||||
|
||||
static const unsigned int domain_map[] = {
|
||||
[XFS_HEALTHMON_MOUNT] = XFS_HEALTH_MONITOR_DOMAIN_MOUNT,
|
||||
[XFS_HEALTHMON_FS] = XFS_HEALTH_MONITOR_DOMAIN_FS,
|
||||
|
|
@ -517,6 +583,7 @@ static const unsigned int type_map[] = {
|
|||
[XFS_HEALTHMON_CORRUPT] = XFS_HEALTH_MONITOR_TYPE_CORRUPT,
|
||||
[XFS_HEALTHMON_HEALTHY] = XFS_HEALTH_MONITOR_TYPE_HEALTHY,
|
||||
[XFS_HEALTHMON_UNMOUNT] = XFS_HEALTH_MONITOR_TYPE_UNMOUNT,
|
||||
[XFS_HEALTHMON_SHUTDOWN] = XFS_HEALTH_MONITOR_TYPE_SHUTDOWN,
|
||||
};
|
||||
|
||||
/* Render event as a V0 structure */
|
||||
|
|
@ -545,6 +612,9 @@ xfs_healthmon_format_v0(
|
|||
case XFS_HEALTHMON_LOST:
|
||||
hme.e.lost.count = event->lostcount;
|
||||
break;
|
||||
case XFS_HEALTHMON_SHUTDOWN:
|
||||
hme.e.shutdown.reasons = shutdown_mask(event->flags);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,9 @@ enum xfs_healthmon_type {
|
|||
XFS_HEALTHMON_LOST, /* message lost */
|
||||
XFS_HEALTHMON_UNMOUNT, /* filesystem is unmounting */
|
||||
|
||||
/* filesystem shutdown */
|
||||
XFS_HEALTHMON_SHUTDOWN,
|
||||
|
||||
/* metadata health events */
|
||||
XFS_HEALTHMON_SICK, /* runtime corruption observed */
|
||||
XFS_HEALTHMON_CORRUPT, /* fsck reported corruption */
|
||||
|
|
@ -119,6 +122,10 @@ struct xfs_healthmon_event {
|
|||
uint32_t gen;
|
||||
xfs_ino_t ino;
|
||||
};
|
||||
/* shutdown */
|
||||
struct {
|
||||
unsigned int flags;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -132,6 +139,8 @@ void xfs_healthmon_report_inode(struct xfs_inode *ip,
|
|||
enum xfs_healthmon_type type, unsigned int old_mask,
|
||||
unsigned int new_mask);
|
||||
|
||||
void xfs_healthmon_report_shutdown(struct xfs_mount *mp, uint32_t flags);
|
||||
|
||||
long xfs_ioc_health_monitor(struct file *file,
|
||||
struct xfs_health_monitor __user *arg);
|
||||
|
||||
|
|
|
|||
|
|
@ -6012,7 +6012,8 @@ DEFINE_HEALTHMON_EVENT(xfs_healthmon_report_unmount);
|
|||
{ XFS_HEALTHMON_UNMOUNT, "unmount" }, \
|
||||
{ XFS_HEALTHMON_SICK, "sick" }, \
|
||||
{ XFS_HEALTHMON_CORRUPT, "corrupt" }, \
|
||||
{ XFS_HEALTHMON_HEALTHY, "healthy" }
|
||||
{ XFS_HEALTHMON_HEALTHY, "healthy" }, \
|
||||
{ XFS_HEALTHMON_SHUTDOWN, "shutdown" }
|
||||
|
||||
#define XFS_HEALTHMON_DOMAIN_STRINGS \
|
||||
{ XFS_HEALTHMON_MOUNT, "mount" }, \
|
||||
|
|
@ -6022,6 +6023,7 @@ DEFINE_HEALTHMON_EVENT(xfs_healthmon_report_unmount);
|
|||
{ 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);
|
||||
|
|
@ -6063,6 +6065,9 @@ DECLARE_EVENT_CLASS(xfs_healthmon_event_class,
|
|||
switch (__entry->domain) {
|
||||
case XFS_HEALTHMON_MOUNT:
|
||||
switch (__entry->type) {
|
||||
case XFS_HEALTHMON_SHUTDOWN:
|
||||
__entry->mask = event->flags;
|
||||
break;
|
||||
case XFS_HEALTHMON_LOST:
|
||||
__entry->lostcount = event->lostcount;
|
||||
break;
|
||||
|
|
@ -6207,6 +6212,22 @@ TRACE_EVENT(xfs_healthmon_report_inode,
|
|||
__entry->gen)
|
||||
);
|
||||
|
||||
TRACE_EVENT(xfs_healthmon_report_shutdown,
|
||||
TP_PROTO(const struct xfs_healthmon *hm, uint32_t shutdown_flags),
|
||||
TP_ARGS(hm, shutdown_flags),
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(uint32_t, shutdown_flags)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->dev = hm->dev;
|
||||
__entry->shutdown_flags = shutdown_flags;
|
||||
),
|
||||
TP_printk("dev %d:%d shutdown_flags %s",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
__print_flags(__entry->shutdown_flags, "|", XFS_SHUTDOWN_STRINGS))
|
||||
);
|
||||
|
||||
#endif /* _TRACE_XFS_H */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user