zio: rename io_reexecute as io_post; use it for the direct IO checksum error flag

We're not supposed to modify someone else's io_flags, so we need another
way to propagate DIO_CHKSUM_ERR.

If we squint, we can see that io_reexecute is really just recording
exceptional events that a parent (or its parents) will need to do
something about. It just happens that the only things we've had
historically are two forms of reexecution: now or later (suspend).

So, rename it to io_post, as in, post-IO info/events/actions. And now we
have a few spare bits for other conditions.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17507
This commit is contained in:
Rob Norris 2025-07-05 13:16:14 +10:00 committed by GitHub
parent ee0cb4cb89
commit 92d3b4ee2c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 50 additions and 52 deletions

View File

@ -45,7 +45,7 @@
__field(zio_flag_t, zio_orig_flags) \ __field(zio_flag_t, zio_orig_flags) \
__field(enum zio_stage, zio_orig_stage) \ __field(enum zio_stage, zio_orig_stage) \
__field(enum zio_stage, zio_orig_pipeline) \ __field(enum zio_stage, zio_orig_pipeline) \
__field(uint8_t, zio_reexecute) \ __field(uint8_t, zio_post) \
__field(uint64_t, zio_txg) \ __field(uint64_t, zio_txg) \
__field(int, zio_error) \ __field(int, zio_error) \
__field(uint64_t, zio_ena) \ __field(uint64_t, zio_ena) \
@ -74,7 +74,7 @@
__entry->zio_orig_flags = zio->io_orig_flags; \ __entry->zio_orig_flags = zio->io_orig_flags; \
__entry->zio_orig_stage = zio->io_orig_stage; \ __entry->zio_orig_stage = zio->io_orig_stage; \
__entry->zio_orig_pipeline = zio->io_orig_pipeline; \ __entry->zio_orig_pipeline = zio->io_orig_pipeline; \
__entry->zio_reexecute = zio->io_reexecute; \ __entry->zio_post = zio->io_post; \
__entry->zio_txg = zio->io_txg; \ __entry->zio_txg = zio->io_txg; \
__entry->zio_error = zio->io_error; \ __entry->zio_error = zio->io_error; \
__entry->zio_ena = zio->io_ena; \ __entry->zio_ena = zio->io_ena; \
@ -92,7 +92,7 @@
"zio { type %u prio %u size %llu orig_size %llu " \ "zio { type %u prio %u size %llu orig_size %llu " \
"offset %llu timestamp %llu delta %llu delay %llu " \ "offset %llu timestamp %llu delta %llu delay %llu " \
"flags 0x%llx stage 0x%x pipeline 0x%x orig_flags 0x%llx " \ "flags 0x%llx stage 0x%x pipeline 0x%x orig_flags 0x%llx " \
"orig_stage 0x%x orig_pipeline 0x%x reexecute %u " \ "orig_stage 0x%x orig_pipeline 0x%x post %u " \
"txg %llu error %d ena %llu prop { checksum %u compress %u " \ "txg %llu error %d ena %llu prop { checksum %u compress %u " \
"type %u level %u copies %u dedup %u dedup_verify %u nopwrite %u } }" "type %u level %u copies %u dedup %u dedup_verify %u nopwrite %u } }"
@ -102,7 +102,7 @@
__entry->zio_timestamp, __entry->zio_delta, __entry->zio_delay, \ __entry->zio_timestamp, __entry->zio_delta, __entry->zio_delay, \
__entry->zio_flags, __entry->zio_stage, __entry->zio_pipeline, \ __entry->zio_flags, __entry->zio_stage, __entry->zio_pipeline, \
__entry->zio_orig_flags, __entry->zio_orig_stage, \ __entry->zio_orig_flags, __entry->zio_orig_stage, \
__entry->zio_orig_pipeline, __entry->zio_reexecute, \ __entry->zio_orig_pipeline, __entry->zio_post, \
__entry->zio_txg, __entry->zio_error, __entry->zio_ena, \ __entry->zio_txg, __entry->zio_error, __entry->zio_ena, \
__entry->zp_checksum, __entry->zp_compress, __entry->zp_type, \ __entry->zp_checksum, __entry->zp_compress, __entry->zp_type, \
__entry->zp_level, __entry->zp_copies, __entry->zp_dedup, \ __entry->zp_level, __entry->zp_copies, __entry->zp_dedup, \

View File

@ -226,8 +226,7 @@ typedef uint64_t zio_flag_t;
#define ZIO_FLAG_NOPWRITE (1ULL << 29) #define ZIO_FLAG_NOPWRITE (1ULL << 29)
#define ZIO_FLAG_REEXECUTED (1ULL << 30) #define ZIO_FLAG_REEXECUTED (1ULL << 30)
#define ZIO_FLAG_DELEGATED (1ULL << 31) #define ZIO_FLAG_DELEGATED (1ULL << 31)
#define ZIO_FLAG_DIO_CHKSUM_ERR (1ULL << 32) #define ZIO_FLAG_PREALLOCATED (1ULL << 32)
#define ZIO_FLAG_PREALLOCATED (1ULL << 33)
#define ZIO_ALLOCATOR_NONE (-1) #define ZIO_ALLOCATOR_NONE (-1)
#define ZIO_HAS_ALLOCATOR(zio) ((zio)->io_allocator != ZIO_ALLOCATOR_NONE) #define ZIO_HAS_ALLOCATOR(zio) ((zio)->io_allocator != ZIO_ALLOCATOR_NONE)
@ -418,14 +417,16 @@ typedef struct zio_transform {
typedef zio_t *zio_pipe_stage_t(zio_t *zio); typedef zio_t *zio_pipe_stage_t(zio_t *zio);
/* /*
* The io_reexecute flags are distinct from io_flags because the child must * The io_post flags describe additional actions that a parent IO should
* be able to propagate them to the parent. The normal io_flags are local * consider or perform on behalf of a child. They are distinct from io_flags
* to the zio, not protected by any lock, and not modifiable by children; * because the child must be able to propagate them to the parent. The normal
* the reexecute flags are protected by io_lock, modifiable by children, * io_flags are local to the zio, not protected by any lock, and not modifiable
* and always propagated -- even when ZIO_FLAG_DONT_PROPAGATE is set. * by children; the reexecute flags are protected by io_lock, modifiable by
* children, and always propagated -- even when ZIO_FLAG_DONT_PROPAGATE is set.
*/ */
#define ZIO_REEXECUTE_NOW 0x01 #define ZIO_POST_REEXECUTE (1 << 0)
#define ZIO_REEXECUTE_SUSPEND 0x02 #define ZIO_POST_SUSPEND (1 << 1)
#define ZIO_POST_DIO_CHKSUM_ERR (1 << 2)
/* /*
* The io_trim flags are used to specify the type of TRIM to perform. They * The io_trim flags are used to specify the type of TRIM to perform. They
@ -461,7 +462,7 @@ struct zio {
enum zio_child io_child_type; enum zio_child io_child_type;
enum trim_flag io_trim_flags; enum trim_flag io_trim_flags;
zio_priority_t io_priority; zio_priority_t io_priority;
uint8_t io_reexecute; uint8_t io_post;
uint8_t io_state[ZIO_WAIT_TYPES]; uint8_t io_state[ZIO_WAIT_TYPES];
uint64_t io_txg; uint64_t io_txg;
spa_t *io_spa; spa_t *io_spa;

View File

@ -221,7 +221,6 @@ _VALSTR_BITFIELD_IMPL(zio_flag,
{ '.', "NP", "NOPWRITE" }, { '.', "NP", "NOPWRITE" },
{ '.', "EX", "REEXECUTED" }, { '.', "EX", "REEXECUTED" },
{ '.', "DG", "DELEGATED" }, { '.', "DG", "DELEGATED" },
{ '.', "DC", "DIO_CHKSUM_ERR" },
{ '.', "PA", "PREALLOCATED" }, { '.', "PA", "PREALLOCATED" },
) )

View File

@ -104,7 +104,7 @@ dmu_write_direct_done(zio_t *zio)
dmu_sync_done(zio, NULL, zio->io_private); dmu_sync_done(zio, NULL, zio->io_private);
if (zio->io_error != 0) { if (zio->io_error != 0) {
if (zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR) if (zio->io_post & ZIO_POST_DIO_CHKSUM_ERR)
ASSERT3U(zio->io_error, ==, EIO); ASSERT3U(zio->io_error, ==, EIO);
/* /*

View File

@ -1842,7 +1842,7 @@ vdev_indirect_io_done(zio_t *zio)
*/ */
if (zio->io_flags & ZIO_FLAG_DIO_READ && ret == ECKSUM) { if (zio->io_flags & ZIO_FLAG_DIO_READ && ret == ECKSUM) {
zio->io_error = ret; zio->io_error = ret;
zio->io_flags |= ZIO_FLAG_DIO_CHKSUM_ERR; zio->io_post |= ZIO_POST_DIO_CHKSUM_ERR;
zio_dio_chksum_verify_error_report(zio); zio_dio_chksum_verify_error_report(zio);
ret = 0; ret = 0;
} }

View File

@ -779,7 +779,7 @@ vdev_mirror_io_done(zio_t *zio)
* being written out during self healing. * being written out during self healing.
*/ */
if ((zio->io_flags & ZIO_FLAG_DIO_READ) && if ((zio->io_flags & ZIO_FLAG_DIO_READ) &&
(zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR)) { (zio->io_post & ZIO_POST_DIO_CHKSUM_ERR)) {
zio_dio_chksum_verify_error_report(zio); zio_dio_chksum_verify_error_report(zio);
zio->io_error = vdev_mirror_worst_error(mm); zio->io_error = vdev_mirror_worst_error(mm);
ASSERT3U(zio->io_error, ==, ECKSUM); ASSERT3U(zio->io_error, ==, ECKSUM);

View File

@ -2691,7 +2691,7 @@ raidz_checksum_verify(zio_t *zio)
*/ */
if (zio->io_flags & ZIO_FLAG_DIO_READ && ret == ECKSUM) { if (zio->io_flags & ZIO_FLAG_DIO_READ && ret == ECKSUM) {
zio->io_error = ret; zio->io_error = ret;
zio->io_flags |= ZIO_FLAG_DIO_CHKSUM_ERR; zio->io_post |= ZIO_POST_DIO_CHKSUM_ERR;
zio_dio_chksum_verify_error_report(zio); zio_dio_chksum_verify_error_report(zio);
zio_checksum_verified(zio); zio_checksum_verified(zio);
return (0); return (0);
@ -3048,7 +3048,7 @@ raidz_reconstruct(zio_t *zio, int *ltgts, int ntgts, int nparity)
/* Check for success */ /* Check for success */
if (raidz_checksum_verify(zio) == 0) { if (raidz_checksum_verify(zio) == 0) {
if (zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR) if (zio->io_post & ZIO_POST_DIO_CHKSUM_ERR)
return (0); return (0);
/* Reconstruction succeeded - report errors */ /* Reconstruction succeeded - report errors */
@ -3514,7 +3514,7 @@ vdev_raidz_io_done(zio_t *zio)
} }
if (raidz_checksum_verify(zio) == 0) { if (raidz_checksum_verify(zio) == 0) {
if (zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR) if (zio->io_post & ZIO_POST_DIO_CHKSUM_ERR)
goto done; goto done;
for (int i = 0; i < rm->rm_nrows; i++) { for (int i = 0; i < rm->rm_nrows; i++) {

View File

@ -850,15 +850,9 @@ zio_notify_parent(zio_t *pio, zio_t *zio, enum zio_wait_type wait,
mutex_enter(&pio->io_lock); mutex_enter(&pio->io_lock);
if (zio->io_error && !(zio->io_flags & ZIO_FLAG_DONT_PROPAGATE)) if (zio->io_error && !(zio->io_flags & ZIO_FLAG_DONT_PROPAGATE))
*errorp = zio_worst_error(*errorp, zio->io_error); *errorp = zio_worst_error(*errorp, zio->io_error);
pio->io_reexecute |= zio->io_reexecute; pio->io_post |= zio->io_post;
ASSERT3U(*countp, >, 0); ASSERT3U(*countp, >, 0);
/*
* Propogate the Direct I/O checksum verify failure to the parent.
*/
if (zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR)
pio->io_flags |= ZIO_FLAG_DIO_CHKSUM_ERR;
(*countp)--; (*countp)--;
if (*countp == 0 && pio->io_stall == countp) { if (*countp == 0 && pio->io_stall == countp) {
@ -1649,7 +1643,7 @@ zio_vdev_child_io(zio_t *pio, blkptr_t *bp, vdev_t *vd, uint64_t offset,
* through the mirror during self healing. See comment in * through the mirror during self healing. See comment in
* vdev_mirror_io_done() for more details. * vdev_mirror_io_done() for more details.
*/ */
ASSERT0(pio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR); ASSERT0(pio->io_post & ZIO_POST_DIO_CHKSUM_ERR);
} else if (type == ZIO_TYPE_WRITE && } else if (type == ZIO_TYPE_WRITE &&
pio->io_prop.zp_direct_write == B_TRUE) { pio->io_prop.zp_direct_write == B_TRUE) {
/* /*
@ -2602,7 +2596,7 @@ zio_reexecute(void *arg)
pio->io_flags = pio->io_orig_flags; pio->io_flags = pio->io_orig_flags;
pio->io_stage = pio->io_orig_stage; pio->io_stage = pio->io_orig_stage;
pio->io_pipeline = pio->io_orig_pipeline; pio->io_pipeline = pio->io_orig_pipeline;
pio->io_reexecute = 0; pio->io_post = 0;
pio->io_flags |= ZIO_FLAG_REEXECUTED; pio->io_flags |= ZIO_FLAG_REEXECUTED;
pio->io_pipeline_trace = 0; pio->io_pipeline_trace = 0;
pio->io_error = 0; pio->io_error = 0;
@ -4722,7 +4716,7 @@ zio_vdev_io_assess(zio_t *zio)
* If a Direct I/O operation has a checksum verify error then this I/O * If a Direct I/O operation has a checksum verify error then this I/O
* should not attempt to be issued again. * should not attempt to be issued again.
*/ */
if (zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR) { if (zio->io_post & ZIO_POST_DIO_CHKSUM_ERR) {
if (zio->io_type == ZIO_TYPE_WRITE) { if (zio->io_type == ZIO_TYPE_WRITE) {
ASSERT3U(zio->io_child_type, ==, ZIO_CHILD_LOGICAL); ASSERT3U(zio->io_child_type, ==, ZIO_CHILD_LOGICAL);
ASSERT3U(zio->io_error, ==, EIO); ASSERT3U(zio->io_error, ==, EIO);
@ -5031,7 +5025,7 @@ zio_checksum_verify(zio_t *zio)
ASSERT3U(zio->io_prop.zp_checksum, ==, ZIO_CHECKSUM_LABEL); ASSERT3U(zio->io_prop.zp_checksum, ==, ZIO_CHECKSUM_LABEL);
} }
ASSERT0(zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR); ASSERT0(zio->io_post & ZIO_POST_DIO_CHKSUM_ERR);
IMPLY(zio->io_flags & ZIO_FLAG_DIO_READ, IMPLY(zio->io_flags & ZIO_FLAG_DIO_READ,
!(zio->io_flags & ZIO_FLAG_SPECULATIVE)); !(zio->io_flags & ZIO_FLAG_SPECULATIVE));
@ -5040,7 +5034,7 @@ zio_checksum_verify(zio_t *zio)
if (error == ECKSUM && if (error == ECKSUM &&
!(zio->io_flags & ZIO_FLAG_SPECULATIVE)) { !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) {
if (zio->io_flags & ZIO_FLAG_DIO_READ) { if (zio->io_flags & ZIO_FLAG_DIO_READ) {
zio->io_flags |= ZIO_FLAG_DIO_CHKSUM_ERR; zio->io_post |= ZIO_POST_DIO_CHKSUM_ERR;
zio_t *pio = zio_unique_parent(zio); zio_t *pio = zio_unique_parent(zio);
/* /*
* Any Direct I/O read that has a checksum * Any Direct I/O read that has a checksum
@ -5090,7 +5084,7 @@ zio_dio_checksum_verify(zio_t *zio)
if ((error = zio_checksum_error(zio, NULL)) != 0) { if ((error = zio_checksum_error(zio, NULL)) != 0) {
zio->io_error = error; zio->io_error = error;
if (error == ECKSUM) { if (error == ECKSUM) {
zio->io_flags |= ZIO_FLAG_DIO_CHKSUM_ERR; zio->io_post |= ZIO_POST_DIO_CHKSUM_ERR;
zio_dio_chksum_verify_error_report(zio); zio_dio_chksum_verify_error_report(zio);
} }
} }
@ -5115,7 +5109,7 @@ zio_checksum_verified(zio_t *zio)
void void
zio_dio_chksum_verify_error_report(zio_t *zio) zio_dio_chksum_verify_error_report(zio_t *zio)
{ {
ASSERT(zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR); ASSERT(zio->io_post & ZIO_POST_DIO_CHKSUM_ERR);
if (zio->io_child_type == ZIO_CHILD_LOGICAL) if (zio->io_child_type == ZIO_CHILD_LOGICAL)
return; return;
@ -5431,7 +5425,7 @@ zio_done(zio_t *zio)
*/ */
if (zio->io_error != ECKSUM && zio->io_vd != NULL && if (zio->io_error != ECKSUM && zio->io_vd != NULL &&
!vdev_is_dead(zio->io_vd) && !vdev_is_dead(zio->io_vd) &&
!(zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR)) { !(zio->io_post & ZIO_POST_DIO_CHKSUM_ERR)) {
int ret = zfs_ereport_post(FM_EREPORT_ZFS_IO, int ret = zfs_ereport_post(FM_EREPORT_ZFS_IO,
zio->io_spa, zio->io_vd, &zio->io_bookmark, zio, 0); zio->io_spa, zio->io_vd, &zio->io_bookmark, zio, 0);
if (ret != EALREADY) { if (ret != EALREADY) {
@ -5446,7 +5440,7 @@ zio_done(zio_t *zio)
if ((zio->io_error == EIO || !(zio->io_flags & if ((zio->io_error == EIO || !(zio->io_flags &
(ZIO_FLAG_SPECULATIVE | ZIO_FLAG_DONT_PROPAGATE))) && (ZIO_FLAG_SPECULATIVE | ZIO_FLAG_DONT_PROPAGATE))) &&
!(zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR) && !(zio->io_post & ZIO_POST_DIO_CHKSUM_ERR) &&
zio == zio->io_logical) { zio == zio->io_logical) {
/* /*
* For logical I/O requests, tell the SPA to log the * For logical I/O requests, tell the SPA to log the
@ -5467,7 +5461,7 @@ zio_done(zio_t *zio)
*/ */
if (zio->io_error == EAGAIN && IO_IS_ALLOCATING(zio) && if (zio->io_error == EAGAIN && IO_IS_ALLOCATING(zio) &&
zio->io_prop.zp_dedup) { zio->io_prop.zp_dedup) {
zio->io_reexecute |= ZIO_REEXECUTE_NOW; zio->io_post |= ZIO_POST_REEXECUTE;
zio->io_prop.zp_dedup = B_FALSE; zio->io_prop.zp_dedup = B_FALSE;
} }
/* /*
@ -5479,11 +5473,11 @@ zio_done(zio_t *zio)
if (IO_IS_ALLOCATING(zio) && if (IO_IS_ALLOCATING(zio) &&
!(zio->io_flags & ZIO_FLAG_CANFAIL) && !(zio->io_flags & ZIO_FLAG_CANFAIL) &&
!(zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR)) { !(zio->io_post & ZIO_POST_DIO_CHKSUM_ERR)) {
if (zio->io_error != ENOSPC) if (zio->io_error != ENOSPC)
zio->io_reexecute |= ZIO_REEXECUTE_NOW; zio->io_post |= ZIO_POST_REEXECUTE;
else else
zio->io_reexecute |= ZIO_REEXECUTE_SUSPEND; zio->io_post |= ZIO_POST_SUSPEND;
} }
if ((zio->io_type == ZIO_TYPE_READ || if ((zio->io_type == ZIO_TYPE_READ ||
@ -5492,10 +5486,11 @@ zio_done(zio_t *zio)
zio->io_error == ENXIO && zio->io_error == ENXIO &&
spa_load_state(zio->io_spa) == SPA_LOAD_NONE && spa_load_state(zio->io_spa) == SPA_LOAD_NONE &&
spa_get_failmode(zio->io_spa) != ZIO_FAILURE_MODE_CONTINUE) spa_get_failmode(zio->io_spa) != ZIO_FAILURE_MODE_CONTINUE)
zio->io_reexecute |= ZIO_REEXECUTE_SUSPEND; zio->io_post |= ZIO_POST_SUSPEND;
if (!(zio->io_flags & ZIO_FLAG_CANFAIL) && !zio->io_reexecute) if (!(zio->io_flags & ZIO_FLAG_CANFAIL) &&
zio->io_reexecute |= ZIO_REEXECUTE_SUSPEND; !(zio->io_post & (ZIO_POST_REEXECUTE|ZIO_POST_SUSPEND)))
zio->io_post |= ZIO_POST_SUSPEND;
/* /*
* Here is a possibly good place to attempt to do * Here is a possibly good place to attempt to do
@ -5514,7 +5509,8 @@ zio_done(zio_t *zio)
*/ */
zio_inherit_child_errors(zio, ZIO_CHILD_LOGICAL); zio_inherit_child_errors(zio, ZIO_CHILD_LOGICAL);
if ((zio->io_error || zio->io_reexecute) && if ((zio->io_error ||
(zio->io_post & (ZIO_POST_REEXECUTE|ZIO_POST_SUSPEND))) &&
IO_IS_ALLOCATING(zio) && zio->io_gang_leader == zio && IO_IS_ALLOCATING(zio) && zio->io_gang_leader == zio &&
!(zio->io_flags & (ZIO_FLAG_IO_REWRITE | ZIO_FLAG_NOPWRITE))) !(zio->io_flags & (ZIO_FLAG_IO_REWRITE | ZIO_FLAG_NOPWRITE)))
zio_dva_unallocate(zio, zio->io_gang_tree, zio->io_bp); zio_dva_unallocate(zio, zio->io_gang_tree, zio->io_bp);
@ -5525,16 +5521,16 @@ zio_done(zio_t *zio)
* Godfather I/Os should never suspend. * Godfather I/Os should never suspend.
*/ */
if ((zio->io_flags & ZIO_FLAG_GODFATHER) && if ((zio->io_flags & ZIO_FLAG_GODFATHER) &&
(zio->io_reexecute & ZIO_REEXECUTE_SUSPEND)) (zio->io_post & ZIO_POST_SUSPEND))
zio->io_reexecute &= ~ZIO_REEXECUTE_SUSPEND; zio->io_post &= ~ZIO_POST_SUSPEND;
if (zio->io_reexecute) { if (zio->io_post & (ZIO_POST_REEXECUTE|ZIO_POST_SUSPEND)) {
/* /*
* A Direct I/O operation that has a checksum verify error * A Direct I/O operation that has a checksum verify error
* should not attempt to reexecute. Instead, the error should * should not attempt to reexecute. Instead, the error should
* just be propagated back. * just be propagated back.
*/ */
ASSERT(!(zio->io_flags & ZIO_FLAG_DIO_CHKSUM_ERR)); ASSERT0(zio->io_post & ZIO_POST_DIO_CHKSUM_ERR);
/* /*
* This is a logical I/O that wants to reexecute. * This is a logical I/O that wants to reexecute.
@ -5571,7 +5567,7 @@ zio_done(zio_t *zio)
pio_next = zio_walk_parents(zio, &zl); pio_next = zio_walk_parents(zio, &zl);
if ((pio->io_flags & ZIO_FLAG_GODFATHER) && if ((pio->io_flags & ZIO_FLAG_GODFATHER) &&
(zio->io_reexecute & ZIO_REEXECUTE_SUSPEND)) { (zio->io_post & ZIO_POST_SUSPEND)) {
zio_remove_child(pio, zio, remove_zl); zio_remove_child(pio, zio, remove_zl);
/* /*
* This is a rare code path, so we don't * This is a rare code path, so we don't
@ -5595,13 +5591,14 @@ zio_done(zio_t *zio)
* "next_to_execute". * "next_to_execute".
*/ */
zio_notify_parent(pio, zio, ZIO_WAIT_DONE, NULL); zio_notify_parent(pio, zio, ZIO_WAIT_DONE, NULL);
} else if (zio->io_reexecute & ZIO_REEXECUTE_SUSPEND) { } else if (zio->io_post & ZIO_POST_SUSPEND) {
/* /*
* We'd fail again if we reexecuted now, so suspend * We'd fail again if we reexecuted now, so suspend
* until conditions improve (e.g. device comes online). * until conditions improve (e.g. device comes online).
*/ */
zio_suspend(zio->io_spa, zio, ZIO_SUSPEND_IOERR); zio_suspend(zio->io_spa, zio, ZIO_SUSPEND_IOERR);
} else { } else {
ASSERT(zio->io_post & ZIO_POST_REEXECUTE);
/* /*
* Reexecution is potentially a huge amount of work. * Reexecution is potentially a huge amount of work.
* Hand it off to the otherwise-unused claim taskq. * Hand it off to the otherwise-unused claim taskq.
@ -5614,7 +5611,8 @@ zio_done(zio_t *zio)
} }
ASSERT(list_is_empty(&zio->io_child_list)); ASSERT(list_is_empty(&zio->io_child_list));
ASSERT(zio->io_reexecute == 0); ASSERT0(zio->io_post & ZIO_POST_REEXECUTE);
ASSERT0(zio->io_post & ZIO_POST_SUSPEND);
ASSERT(zio->io_error == 0 || (zio->io_flags & ZIO_FLAG_CANFAIL)); ASSERT(zio->io_error == 0 || (zio->io_flags & ZIO_FLAG_CANFAIL));
/* /*