From 44e326689421f132243a1cbed369dd2ed6868e67 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 31 May 2025 00:29:29 +1000 Subject: [PATCH] events: include zio type in IO error reports Usually the IO type can be inferred from the other fields (in particular, priority and flags) sometimes it's not easy to see. This is just another little debug helper. May 27 2025 00:54:54.024110493 ereport.fs.zfs.data class = "ereport.fs.zfs.data" ena = 0x1f5ecfae600801 ... zio_delta = 0x0 zio_type = 0x2 [WRITE] zio_priority = 0x3 [ASYNC_WRITE] zio_objset = 0x0 Document zio_type and zio_priority. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Brian Behlendorf Reviewed-by: Alexander Motin Signed-off-by: Rob Norris Closes #17381 --- cmd/zpool/zpool_main.c | 5 +++ include/sys/fm/fs/zfs.h | 1 + include/zfs_valstr.h | 1 + lib/libzfs/libzfs.abi | 7 ++++ man/man8/zpool-events.8 | 59 ++++++++++++++++++++++++++++++++-- module/zcommon/zfs_valstr.c | 11 +++++++ module/zfs/zfs_fm.c | 2 ++ tests/zfs-tests/cmd/ereports.c | 1 + 8 files changed, 85 insertions(+), 2 deletions(-) diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index d45900246..d3094d448 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -12070,6 +12070,11 @@ zpool_do_events_nvprint(nvlist_t *nvl, int depth) zfs_valstr_zio_stage(i32, flagstr, sizeof (flagstr)); printf(gettext("0x%x [%s]"), i32, flagstr); + } else if (strcmp(name, + FM_EREPORT_PAYLOAD_ZFS_ZIO_TYPE) == 0) { + zfs_valstr_zio_type(i32, flagstr, + sizeof (flagstr)); + printf(gettext("0x%x [%s]"), i32, flagstr); } else if (strcmp(name, FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY) == 0) { zfs_valstr_zio_priority(i32, flagstr, diff --git a/include/sys/fm/fs/zfs.h b/include/sys/fm/fs/zfs.h index 30ced55da..659c64bf1 100644 --- a/include/sys/fm/fs/zfs.h +++ b/include/sys/fm/fs/zfs.h @@ -103,6 +103,7 @@ extern "C" { #define FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS "zio_flags" #define FM_EREPORT_PAYLOAD_ZFS_ZIO_STAGE "zio_stage" #define FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY "zio_priority" +#define FM_EREPORT_PAYLOAD_ZFS_ZIO_TYPE "zio_type" #define FM_EREPORT_PAYLOAD_ZFS_ZIO_PIPELINE "zio_pipeline" #define FM_EREPORT_PAYLOAD_ZFS_ZIO_DELAY "zio_delay" #define FM_EREPORT_PAYLOAD_ZFS_ZIO_TIMESTAMP "zio_timestamp" diff --git a/include/zfs_valstr.h b/include/zfs_valstr.h index 295449396..27b4c9ebb 100644 --- a/include/zfs_valstr.h +++ b/include/zfs_valstr.h @@ -73,6 +73,7 @@ extern "C" { _ZFS_VALSTR_DECLARE_BITFIELD(zio_flag) _ZFS_VALSTR_DECLARE_BITFIELD(zio_stage) +_ZFS_VALSTR_DECLARE_ENUM(zio_type) _ZFS_VALSTR_DECLARE_ENUM(zio_priority) #undef _ZFS_VALSTR_DECLARE_BITFIELD diff --git a/lib/libzfs/libzfs.abi b/lib/libzfs/libzfs.abi index 01fe98db8..35ecdca76 100644 --- a/lib/libzfs/libzfs.abi +++ b/lib/libzfs/libzfs.abi @@ -466,6 +466,7 @@ + @@ -10080,6 +10081,12 @@ + + + + + + diff --git a/man/man8/zpool-events.8 b/man/man8/zpool-events.8 index a176e54a2..7af1917da 100644 --- a/man/man8/zpool-events.8 +++ b/man/man8/zpool-events.8 @@ -26,9 +26,9 @@ .\" Copyright (c) 2018 George Melikov. All Rights Reserved. .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. -.\" Copyright (c) 2024, Klara Inc. +.\" Copyright (c) 2024, 2025, Klara, Inc. .\" -.Dd February 28, 2024 +.Dd May 27, 2025 .Dt ZPOOL-EVENTS 8 .Os . @@ -308,6 +308,16 @@ The valid pipeline stages for the I/O. See the .Sy I/O STAGES section for a full list of all the I/O stages. +.It Sy zio_priority +The queue priority of the I/O request. +See the +.Sy I/O PRIORITIES +section for a full list of all the I/O priorities. +.It Sy zio_tyoe +The type of the I/O request. +See the +.Sy I/O TYPES +section for a full list of all the I/O types. .It Sy zio_delay The time elapsed (in nanoseconds) waiting for the block layer to complete the I/O request. @@ -477,6 +487,51 @@ ZIO_FLAG_DELEGATED:0x40000000 ZIO_FLAG_FASTWRITE:0x80000000 .TE . +.Sh I/O TYPES +Every I/O request in the pipeline has a single type value. +This value describes the kind of low-level work the I/O represents. +This value will be set in an event as a +.Sy zio_type +payload entry. +.Pp +.TS +tab(:); +l l l . +Type:Value:Description +_:_:_ +ZIO_TYPE_NULL:0x0:internal I/O sync point +ZIO_TYPE_READ:0x1:data read +ZIO_TYPE_WRITE:0x2:data write +ZIO_TYPE_FREE:0x3:block free +ZIO_TYPE_CLAIM:0x4:block claim (ZIL replay) +ZIO_TYPE_FLUSH:0x5:disk cache flush request +ZIO_TYPE_TRIM:0x6:trim (discard) +.TE +. +.Sh I/O PRIORITIES +Every I/O request in the pipeline has a single priority value. +This value is used by the queuing code to decide which I/O to issue next. +This value will be set in an event as a +.Sy zio_priority +payload entry. +.Pp +.TS +tab(:); +l l l . +Type:Value:Description +_:_:_ +ZIO_PRIORITY_SYNC_READ:0x0: +ZIO_PRIORITY_SYNC_WRITE:0x1:ZIL +ZIO_PRIORITY_ASYNC_READ:0x2:prefetch +ZIO_PRIORITY_ASYNC_WRITE:0x3:spa_sync() +ZIO_PRIORITY_SCRUB:0x4:asynchronous scrub/resilver reads +ZIO_PRIORITY_REMOVAL:0x5:reads/writes for vdev removal +ZIO_PRIORITY_INITIALIZING:0x6:initializing I/O +ZIO_PRIORITY_TRIM:0x7:trim I/O (discard) +ZIO_PRIORITY_REBUILD:0x8:reads/writes for vdev rebuild +ZIO_PRIORITY_NOW:0xa:non-queued i/os (e.g. free) +.TE +. .Sh SEE ALSO .Xr zfs 4 , .Xr zed 8 , diff --git a/module/zcommon/zfs_valstr.c b/module/zcommon/zfs_valstr.c index fce5658b4..c39ac62f6 100644 --- a/module/zcommon/zfs_valstr.c +++ b/module/zcommon/zfs_valstr.c @@ -259,6 +259,17 @@ _VALSTR_BITFIELD_IMPL(zio_stage, { 'X', "X ", "DONE" }, ) +/* ZIO type: zio_type_t, typically zio->io_type */ +_VALSTR_ENUM_IMPL(zio_type, + "NULL", + "READ", + "WRITE", + "FREE", + "CLAIM", + "FLUSH", + "TRIM", +) + /* ZIO priority: zio_priority_t, typically zio->io_priority */ _VALSTR_ENUM_IMPL(zio_priority, "SYNC_READ", diff --git a/module/zfs/zfs_fm.c b/module/zfs/zfs_fm.c index cd02ae78f..221f24e38 100644 --- a/module/zfs/zfs_fm.c +++ b/module/zfs/zfs_fm.c @@ -659,6 +659,8 @@ zfs_ereport_start(nvlist_t **ereport_out, nvlist_t **detector_out, DATA_TYPE_UINT64, zio->io_timestamp, NULL); fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_DELTA, DATA_TYPE_UINT64, zio->io_delta, NULL); + fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_TYPE, + DATA_TYPE_UINT32, zio->io_type, NULL); fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY, DATA_TYPE_UINT32, zio->io_priority, NULL); diff --git a/tests/zfs-tests/cmd/ereports.c b/tests/zfs-tests/cmd/ereports.c index f05579e15..f981d5b34 100644 --- a/tests/zfs-tests/cmd/ereports.c +++ b/tests/zfs-tests/cmd/ereports.c @@ -49,6 +49,7 @@ static const char *const criteria_name[] = { FM_EREPORT_PAYLOAD_ZFS_ZIO_ERR, FM_EREPORT_PAYLOAD_ZFS_ZIO_SIZE, FM_EREPORT_PAYLOAD_ZFS_ZIO_OFFSET, + FM_EREPORT_PAYLOAD_ZFS_ZIO_TYPE, FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY, /* logical zio criteriai (optional) */