* Verify the block pointer fields contain reasonable values. This means * it only contains known object types, checksum/compression identifiers, * block sizes within the maximum allowed limits, valid DVAs, etc. * * If everything checks out B_TRUE is returned. The zfs_blkptr_verify * argument controls the behavior when an invalid field is detected. * * Modes for zfs_blkptr_verify: * 1)
| 965 | * 3) BLK_VERIFY_HALT (call zfs_panic_recover on error) |
| 966 | */ |
| 967 | boolean_t |
| 968 | zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp, boolean_t config_held, |
| 969 | enum blk_verify_flag blk_verify) |
| 970 | { |
| 971 | int errors = 0; |
| 972 | |
| 973 | if (!DMU_OT_IS_VALID(BP_GET_TYPE(bp))) { |
| 974 | errors += zfs_blkptr_verify_log(spa, bp, blk_verify, |
| 975 | "blkptr at %p has invalid TYPE %llu", |
| 976 | bp, (longlong_t)BP_GET_TYPE(bp)); |
| 977 | } |
| 978 | if (BP_GET_CHECKSUM(bp) >= ZIO_CHECKSUM_FUNCTIONS || |
| 979 | BP_GET_CHECKSUM(bp) <= ZIO_CHECKSUM_ON) { |
| 980 | errors += zfs_blkptr_verify_log(spa, bp, blk_verify, |
| 981 | "blkptr at %p has invalid CHECKSUM %llu", |
| 982 | bp, (longlong_t)BP_GET_CHECKSUM(bp)); |
| 983 | } |
| 984 | if (BP_GET_COMPRESS(bp) >= ZIO_COMPRESS_FUNCTIONS || |
| 985 | BP_GET_COMPRESS(bp) <= ZIO_COMPRESS_ON) { |
| 986 | errors += zfs_blkptr_verify_log(spa, bp, blk_verify, |
| 987 | "blkptr at %p has invalid COMPRESS %llu", |
| 988 | bp, (longlong_t)BP_GET_COMPRESS(bp)); |
| 989 | } |
| 990 | if (BP_GET_LSIZE(bp) > SPA_MAXBLOCKSIZE) { |
| 991 | errors += zfs_blkptr_verify_log(spa, bp, blk_verify, |
| 992 | "blkptr at %p has invalid LSIZE %llu", |
| 993 | bp, (longlong_t)BP_GET_LSIZE(bp)); |
| 994 | } |
| 995 | if (BP_GET_PSIZE(bp) > SPA_MAXBLOCKSIZE) { |
| 996 | errors += zfs_blkptr_verify_log(spa, bp, blk_verify, |
| 997 | "blkptr at %p has invalid PSIZE %llu", |
| 998 | bp, (longlong_t)BP_GET_PSIZE(bp)); |
| 999 | } |
| 1000 | |
| 1001 | if (BP_IS_EMBEDDED(bp)) { |
| 1002 | if (BPE_GET_ETYPE(bp) >= NUM_BP_EMBEDDED_TYPES) { |
| 1003 | errors += zfs_blkptr_verify_log(spa, bp, blk_verify, |
| 1004 | "blkptr at %p has invalid ETYPE %llu", |
| 1005 | bp, (longlong_t)BPE_GET_ETYPE(bp)); |
| 1006 | } |
| 1007 | } |
| 1008 | |
| 1009 | /* |
| 1010 | * Do not verify individual DVAs if the config is not trusted. This |
| 1011 | * will be done once the zio is executed in vdev_mirror_map_alloc. |
| 1012 | */ |
| 1013 | if (!spa->spa_trust_config) |
| 1014 | return (B_TRUE); |
| 1015 | |
| 1016 | if (!config_held) |
| 1017 | spa_config_enter(spa, SCL_VDEV, bp, RW_READER); |
| 1018 | else |
| 1019 | ASSERT(spa_config_held(spa, SCL_VDEV, RW_WRITER)); |
| 1020 | /* |
| 1021 | * Pool-specific checks. |
| 1022 | * |
| 1023 | * Note: it would be nice to verify that the blk_birth and |
| 1024 | * BP_PHYSICAL_BIRTH() are not too large. However, spa_freeze() |
no test coverage detected