+ vps = kmem_zalloc(sizeof (*vps), KM_SLEEP);
+
+ vps->vps_flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_PROBE |
+ ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_AGGREGATE | ZIO_FLAG_DONT_RETRY;
+
+ if (spa_config_held(spa, SCL_ZIO, RW_WRITER)) {
+ /*
+ * vdev_cant_read and vdev_cant_write can only transition
+ * from TRUE to FALSE when we have the SCL_ZIO lock as writer;
+ * otherwise they can only transition from FALSE to TRUE.
+ * This ensures that any zio looking at these values can
+ * assume that failures persist for the life of the I/O.
+ * That's important because when a device has intermittent
+ * connectivity problems, we want to ensure that they're
+ * ascribed to the device (ENXIO) and not the zio (EIO).
+ *
+ * Since we hold SCL_ZIO as writer here, clear both values
+ * so the probe can reevaluate from first principles.
+ */
+ vps->vps_flags |= ZIO_FLAG_CONFIG_WRITER;
+ vd->vdev_cant_read = B_FALSE;
+ vd->vdev_cant_write = B_FALSE;
+ }
+
+ ASSERT(vd->vdev_ops->vdev_op_leaf);
+
+ zio = zio_null(pio, spa, vdev_probe_done, vps, vps->vps_flags);
+
+ vps->vps_root = zio;
+ vps->vps_vd = vd;
+
+ for (int l = 1; l < VDEV_LABELS; l++) {
+ zio_nowait(zio_read_phys(zio, vd,
+ vdev_label_offset(vd->vdev_psize, l,
+ offsetof(vdev_label_t, vl_pad)),
+ VDEV_SKIP_SIZE, zio_buf_alloc(VDEV_SKIP_SIZE),
+ ZIO_CHECKSUM_OFF, vdev_probe_done, vps,
+ ZIO_PRIORITY_SYNC_READ, vps->vps_flags, B_TRUE));
+ }
+
+ return (zio);