Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c (revision 344128) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c (working copy) @@ -219,9 +219,9 @@ vdev_mirror_map_init(zio_t *zio) * If we do not trust the pool config, some DVAs might be * invalid or point to vdevs that do not exist. We skip them. */ - if (!spa_trust_config(spa)) { - ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ); + if (zio->io_type == ZIO_TYPE_READ) { int j = 0; + for (int i = 0; i < c; i++) { if (zfs_dva_valid(spa, &dva[i], zio->io_bp)) dva_copy[j++] = dva[i]; @@ -228,7 +228,7 @@ vdev_mirror_map_init(zio_t *zio) } if (j == 0) { zio->io_vsd = NULL; - zio->io_error = ENXIO; + zio->io_error = EIO; return (NULL); } if (j < c) { @@ -509,7 +509,6 @@ vdev_mirror_io_start(zio_t *zio) mm = vdev_mirror_map_init(zio); if (mm == NULL) { - ASSERT(!spa_trust_config(zio->io_spa)); ASSERT(zio->io_type == ZIO_TYPE_READ); zio_execute(zio); return; Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c (revision 344128) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c (working copy) @@ -839,6 +839,48 @@ zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp) } } +static bool +zfs_blkptr_valid(spa_t *spa, const blkptr_t *bp) +{ + if (!DMU_OT_IS_VALID(BP_GET_TYPE(bp))) { + printf("blkptr at %p has invalid TYPE %llu\n", + bp, (longlong_t)BP_GET_TYPE(bp)); + return (false); + } + if (BP_GET_CHECKSUM(bp) >= ZIO_CHECKSUM_FUNCTIONS || + BP_GET_CHECKSUM(bp) <= ZIO_CHECKSUM_ON) { + printf("blkptr at %p has invalid CHECKSUM %llu\n", + bp, (longlong_t)BP_GET_CHECKSUM(bp)); + return (false); + } + if (BP_GET_COMPRESS(bp) >= ZIO_COMPRESS_FUNCTIONS || + BP_GET_COMPRESS(bp) <= ZIO_COMPRESS_ON) { + printf("blkptr at %p has invalid COMPRESS %llu\n", + bp, (longlong_t)BP_GET_COMPRESS(bp)); + return (false); + } + if (BP_GET_LSIZE(bp) > SPA_MAXBLOCKSIZE) { + printf("blkptr at %p has invalid LSIZE %llu\n", + bp, (longlong_t)BP_GET_LSIZE(bp)); + return (false); + } + if (BP_GET_PSIZE(bp) > SPA_MAXBLOCKSIZE) { + printf("blkptr at %p has invalid PSIZE %llu\n", + bp, (longlong_t)BP_GET_PSIZE(bp)); + return (false); + } + + if (BP_IS_EMBEDDED(bp)) { + if (BPE_GET_ETYPE(bp) > NUM_BP_EMBEDDED_TYPES) { + printf("blkptr at %p has invalid ETYPE %llu\n", + bp, (longlong_t)BPE_GET_ETYPE(bp)); + return (false); + } + } + + return (true); +} + boolean_t zfs_dva_valid(spa_t *spa, const dva_t *dva, const blkptr_t *bp) { @@ -876,8 +918,6 @@ zio_read(zio_t *pio, spa_t *spa, const blkptr_t *b { zio_t *zio; - zfs_blkptr_verify(spa, bp); - zio = zio_create(pio, spa, BP_PHYSICAL_BIRTH(bp), bp, data, size, size, done, private, ZIO_TYPE_READ, priority, flags, NULL, 0, zb, @@ -3182,6 +3222,13 @@ zio_vdev_io_start(zio_t *zio) if (!(zio->io_flags & ZIO_FLAG_CONFIG_WRITER)) spa_config_enter(spa, SCL_ZIO, zio, RW_READER); + if (zio->io_type == ZIO_TYPE_READ && + !zfs_blkptr_valid(spa, zio->io_bp)) { + zio->io_error = EIO; + zio->io_vsd = NULL; + return (zio); + } + /* * The mirror_ops handle multiple DVAs in a single BP. */