|
|
|
@@ -850,15 +850,9 @@ zio_notify_parent(zio_t *pio, zio_t *zio, enum zio_wait_type wait,
|
|
|
|
|
mutex_enter(&pio->io_lock);
|
|
|
|
|
if (zio->io_error && !(zio->io_flags & ZIO_FLAG_DONT_PROPAGATE))
|
|
|
|
|
*errorp = zio_worst_error(*errorp, zio->io_error);
|
|
|
|
|
pio->io_reexecute |= zio->io_reexecute;
|
|
|
|
|
pio->io_post |= zio->io_post;
|
|
|
|
|
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)--;
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
* 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 &&
|
|
|
|
|
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_stage = pio->io_orig_stage;
|
|
|
|
|
pio->io_pipeline = pio->io_orig_pipeline;
|
|
|
|
|
pio->io_reexecute = 0;
|
|
|
|
|
pio->io_post = 0;
|
|
|
|
|
pio->io_flags |= ZIO_FLAG_REEXECUTED;
|
|
|
|
|
pio->io_pipeline_trace = 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
|
|
|
|
|
* 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) {
|
|
|
|
|
ASSERT3U(zio->io_child_type, ==, ZIO_CHILD_LOGICAL);
|
|
|
|
|
ASSERT3U(zio->io_error, ==, EIO);
|
|
|
|
@@ -5031,7 +5025,7 @@ zio_checksum_verify(zio_t *zio)
|
|
|
|
|
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,
|
|
|
|
|
!(zio->io_flags & ZIO_FLAG_SPECULATIVE));
|
|
|
|
|
|
|
|
|
@@ -5040,7 +5034,7 @@ zio_checksum_verify(zio_t *zio)
|
|
|
|
|
if (error == ECKSUM &&
|
|
|
|
|
!(zio->io_flags & ZIO_FLAG_SPECULATIVE)) {
|
|
|
|
|
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);
|
|
|
|
|
/*
|
|
|
|
|
* 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) {
|
|
|
|
|
zio->io_error = error;
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -5115,7 +5109,7 @@ zio_checksum_verified(zio_t *zio)
|
|
|
|
|
void
|
|
|
|
|
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)
|
|
|
|
|
return;
|
|
|
|
@@ -5431,7 +5425,7 @@ zio_done(zio_t *zio)
|
|
|
|
|
*/
|
|
|
|
|
if (zio->io_error != ECKSUM && zio->io_vd != NULL &&
|
|
|
|
|
!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,
|
|
|
|
|
zio->io_spa, zio->io_vd, &zio->io_bookmark, zio, 0);
|
|
|
|
|
if (ret != EALREADY) {
|
|
|
|
@@ -5446,7 +5440,7 @@ zio_done(zio_t *zio)
|
|
|
|
|
|
|
|
|
|
if ((zio->io_error == EIO || !(zio->io_flags &
|
|
|
|
|
(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) {
|
|
|
|
|
/*
|
|
|
|
|
* 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) &&
|
|
|
|
|
zio->io_prop.zp_dedup) {
|
|
|
|
|
zio->io_reexecute |= ZIO_REEXECUTE_NOW;
|
|
|
|
|
zio->io_post |= ZIO_POST_REEXECUTE;
|
|
|
|
|
zio->io_prop.zp_dedup = B_FALSE;
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
@@ -5479,11 +5473,11 @@ zio_done(zio_t *zio)
|
|
|
|
|
|
|
|
|
|
if (IO_IS_ALLOCATING(zio) &&
|
|
|
|
|
!(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)
|
|
|
|
|
zio->io_reexecute |= ZIO_REEXECUTE_NOW;
|
|
|
|
|
zio->io_post |= ZIO_POST_REEXECUTE;
|
|
|
|
|
else
|
|
|
|
|
zio->io_reexecute |= ZIO_REEXECUTE_SUSPEND;
|
|
|
|
|
zio->io_post |= ZIO_POST_SUSPEND;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((zio->io_type == ZIO_TYPE_READ ||
|
|
|
|
@@ -5492,10 +5486,11 @@ zio_done(zio_t *zio)
|
|
|
|
|
zio->io_error == ENXIO &&
|
|
|
|
|
spa_load_state(zio->io_spa) == SPA_LOAD_NONE &&
|
|
|
|
|
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)
|
|
|
|
|
zio->io_reexecute |= ZIO_REEXECUTE_SUSPEND;
|
|
|
|
|
if (!(zio->io_flags & ZIO_FLAG_CANFAIL) &&
|
|
|
|
|
!(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
|
|
|
|
@@ -5514,7 +5509,8 @@ zio_done(zio_t *zio)
|
|
|
|
|
*/
|
|
|
|
|
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 &&
|
|
|
|
|
!(zio->io_flags & (ZIO_FLAG_IO_REWRITE | ZIO_FLAG_NOPWRITE)))
|
|
|
|
|
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.
|
|
|
|
|
*/
|
|
|
|
|
if ((zio->io_flags & ZIO_FLAG_GODFATHER) &&
|
|
|
|
|
(zio->io_reexecute & ZIO_REEXECUTE_SUSPEND))
|
|
|
|
|
zio->io_reexecute &= ~ZIO_REEXECUTE_SUSPEND;
|
|
|
|
|
(zio->io_post & ZIO_POST_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
|
|
|
|
|
* should not attempt to reexecute. Instead, the error should
|
|
|
|
|
* 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.
|
|
|
|
@@ -5571,7 +5567,7 @@ zio_done(zio_t *zio)
|
|
|
|
|
pio_next = zio_walk_parents(zio, &zl);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
/*
|
|
|
|
|
* This is a rare code path, so we don't
|
|
|
|
@@ -5595,13 +5591,14 @@ zio_done(zio_t *zio)
|
|
|
|
|
* "next_to_execute".
|
|
|
|
|
*/
|
|
|
|
|
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
|
|
|
|
|
* until conditions improve (e.g. device comes online).
|
|
|
|
|
*/
|
|
|
|
|
zio_suspend(zio->io_spa, zio, ZIO_SUSPEND_IOERR);
|
|
|
|
|
} else {
|
|
|
|
|
ASSERT(zio->io_post & ZIO_POST_REEXECUTE);
|
|
|
|
|
/*
|
|
|
|
|
* Reexecution is potentially a huge amount of work.
|
|
|
|
|
* 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(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));
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|