zio: do no-op injections just before handing off to vdevs

The purpose of no-op is to simulate a failure between a device cache and
its permanent store. We still want it to go through the queue and
respond in the same way to everything else.

So, inject "success" as the very last thing, and then move on to
VDEV_IO_DONE to be dequeued and so any followup work can occur.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Alexander Motin <[email protected]>
Reviewed-by: Tony Hutter <[email protected]>
Signed-off-by: Rob Norris <[email protected]>
Closes #17029
This commit is contained in:
Rob Norris authored and GitHub committed 2025-02-07 20:42:24 -05:00
1 parent d2147de319
commit b8c73ab780
1 file changed
+9 -10
+9 -10
View File
@@ -4495,16 +4495,6 @@ zio_vdev_io_start(zio_t *zio)
zio->io_type == ZIO_TYPE_WRITE ||
zio->io_type == ZIO_TYPE_TRIM)) {
if (zio_handle_device_injection(vd, zio, ENOSYS) != 0) {
/*
* "no-op" injections return success, but do no actual
* work. Just skip the remaining vdev stages.
*/
zio_vdev_io_bypass(zio);
zio_interrupt(zio);
return (NULL);
}
if ((zio = vdev_queue_io(zio)) == NULL)
return (NULL);
@@ -4514,6 +4504,15 @@ zio_vdev_io_start(zio_t *zio)
return (NULL);
}
zio->io_delay = gethrtime();
if (zio_handle_device_injection(vd, zio, ENOSYS) != 0) {
/*
* "no-op" injections return success, but do no actual
* work. Just return it.
*/
zio_delay_interrupt(zio);
return (NULL);
}
}
vd->vdev_ops->vdev_op_io_start(zio);