summaryrefslogtreecommitdiffstats
path: root/module/zfs/zfs_fm.c
diff options
context:
space:
mode:
Diffstat (limited to 'module/zfs/zfs_fm.c')
-rw-r--r--module/zfs/zfs_fm.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/module/zfs/zfs_fm.c b/module/zfs/zfs_fm.c
index 236d69e7e..8b7785fa8 100644
--- a/module/zfs/zfs_fm.c
+++ b/module/zfs/zfs_fm.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -96,7 +96,6 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio,
nvlist_t *ereport, *detector;
uint64_t ena;
char class[64];
- int state;
/*
* If we are doing a spa_tryimport(), ignore errors.
@@ -130,15 +129,39 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio,
return;
/*
- * If the vdev has already been marked as failing due to a
- * failed probe, then ignore any subsequent I/O errors, as the
- * DE will automatically fault the vdev on the first such
- * failure.
+ * If this I/O is not a retry I/O, don't post an ereport.
+ * Otherwise, we risk making bad diagnoses based on B_FAILFAST
+ * I/Os.
*/
- if (vd != NULL &&
- (!vdev_readable(vd) || !vdev_writeable(vd)) &&
- strcmp(subclass, FM_EREPORT_ZFS_PROBE_FAILURE) != 0)
+ if (zio->io_error == EIO &&
+ !(zio->io_flags & ZIO_FLAG_IO_RETRY))
return;
+
+ if (vd != NULL) {
+ /*
+ * If the vdev has already been marked as failing due
+ * to a failed probe, then ignore any subsequent I/O
+ * errors, as the DE will automatically fault the vdev
+ * on the first such failure. This also catches cases
+ * where vdev_remove_wanted is set and the device has
+ * not yet been asynchronously placed into the REMOVED
+ * state.
+ */
+ if (zio->io_vd == vd &&
+ !vdev_accessible(vd, zio) &&
+ strcmp(subclass, FM_EREPORT_ZFS_PROBE_FAILURE) != 0)
+ return;
+
+ /*
+ * Ignore checksum errors for reads from DTL regions of
+ * leaf vdevs.
+ */
+ if (zio->io_type == ZIO_TYPE_READ &&
+ zio->io_error == ECKSUM &&
+ vd->vdev_ops->vdev_op_leaf &&
+ vdev_dtl_contains(vd, DTL_MISSING, zio->io_txg, 1))
+ return;
+ }
}
if ((ereport = fm_nvlist_create(NULL)) == NULL)
@@ -189,21 +212,13 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio,
*/
/*
- * If we are importing a faulted pool, then we treat it like an open,
- * not an import. Otherwise, the DE will ignore all faults during
- * import, since the default behavior is to mark the devices as
- * persistently unavailable, not leave them in the faulted state.
- */
- state = spa->spa_import_faulted ? SPA_LOAD_OPEN : spa->spa_load_state;
-
- /*
* Generic payload members common to all ereports.
*/
fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_POOL,
DATA_TYPE_STRING, spa_name(spa), FM_EREPORT_PAYLOAD_ZFS_POOL_GUID,
DATA_TYPE_UINT64, spa_guid(spa),
FM_EREPORT_PAYLOAD_ZFS_POOL_CONTEXT, DATA_TYPE_INT32,
- state, NULL);
+ spa->spa_load_state, NULL);
if (spa != NULL) {
fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_POOL_FAILMODE,
@@ -222,14 +237,18 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio,
DATA_TYPE_UINT64, vd->vdev_guid,
FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE,
DATA_TYPE_STRING, vd->vdev_ops->vdev_op_type, NULL);
- if (vd->vdev_path)
+ if (vd->vdev_path != NULL)
fm_payload_set(ereport,
FM_EREPORT_PAYLOAD_ZFS_VDEV_PATH,
DATA_TYPE_STRING, vd->vdev_path, NULL);
- if (vd->vdev_devid)
+ if (vd->vdev_devid != NULL)
fm_payload_set(ereport,
FM_EREPORT_PAYLOAD_ZFS_VDEV_DEVID,
DATA_TYPE_STRING, vd->vdev_devid, NULL);
+ if (vd->vdev_fru != NULL)
+ fm_payload_set(ereport,
+ FM_EREPORT_PAYLOAD_ZFS_VDEV_FRU,
+ DATA_TYPE_STRING, vd->vdev_fru, NULL);
if (pvd != NULL) {
fm_payload_set(ereport,