aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/cmd/zed/agents/zfs_diagnosis.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/openzfs/cmd/zed/agents/zfs_diagnosis.c')
-rw-r--r--sys/contrib/openzfs/cmd/zed/agents/zfs_diagnosis.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/sys/contrib/openzfs/cmd/zed/agents/zfs_diagnosis.c b/sys/contrib/openzfs/cmd/zed/agents/zfs_diagnosis.c
index 4fe9ee2bc5b2..813916d2e82c 100644
--- a/sys/contrib/openzfs/cmd/zed/agents/zfs_diagnosis.c
+++ b/sys/contrib/openzfs/cmd/zed/agents/zfs_diagnosis.c
@@ -34,6 +34,7 @@
#include <sys/fs/zfs.h>
#include <sys/fm/protocol.h>
#include <sys/fm/fs/zfs.h>
+#include <sys/zio.h>
#include "zfs_agents.h"
#include "fmd_api.h"
@@ -770,6 +771,8 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE))) {
char *failmode = NULL;
boolean_t checkremove = B_FALSE;
+ uint32_t pri = 0;
+ int32_t flags = 0;
/*
* If this is a checksum or I/O error, then toss it into the
@@ -792,6 +795,23 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
checkremove = B_TRUE;
} else if (fmd_nvl_class_match(hdl, nvl,
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_CHECKSUM))) {
+ /*
+ * We ignore ereports for checksum errors generated by
+ * scrub/resilver I/O to avoid potentially further
+ * degrading the pool while it's being repaired.
+ */
+ if (((nvlist_lookup_uint32(nvl,
+ FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY, &pri) == 0) &&
+ (pri == ZIO_PRIORITY_SCRUB ||
+ pri == ZIO_PRIORITY_REBUILD)) ||
+ ((nvlist_lookup_int32(nvl,
+ FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS, &flags) == 0) &&
+ (flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)))) {
+ fmd_hdl_debug(hdl, "ignoring '%s' for "
+ "scrub/resilver I/O", class);
+ return;
+ }
+
if (zcp->zc_data.zc_serd_checksum[0] == '\0') {
zfs_serd_name(zcp->zc_data.zc_serd_checksum,
pool_guid, vdev_guid, "checksum");