From b8c73ab7807bba7baac84dcf390171b447d0d08e Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 8 Feb 2025 12:42:24 +1100 Subject: [PATCH] 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 Reviewed-by: Tony Hutter Signed-off-by: Rob Norris Closes #17029 --- module/zfs/zio.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 10930e7f381e..b071ac17ed1f 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -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);