Changeset View
Changeset View
Standalone View
Standalone View
head/sys/cddl/boot/zfs/zfssubr.c
Show First 20 Lines • Show All 264 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
zio_checksum_verify(const spa_t *spa, const blkptr_t *bp, void *data) | zio_checksum_verify(const spa_t *spa, const blkptr_t *bp, void *data) | ||||
{ | { | ||||
uint64_t size; | uint64_t size; | ||||
unsigned int checksum; | unsigned int checksum; | ||||
zio_checksum_info_t *ci; | zio_checksum_info_t *ci; | ||||
void *ctx = NULL; | |||||
zio_cksum_t actual_cksum, expected_cksum, verifier; | zio_cksum_t actual_cksum, expected_cksum, verifier; | ||||
int byteswap; | int byteswap; | ||||
checksum = BP_GET_CHECKSUM(bp); | checksum = BP_GET_CHECKSUM(bp); | ||||
size = BP_GET_PSIZE(bp); | size = BP_GET_PSIZE(bp); | ||||
if (checksum >= ZIO_CHECKSUM_FUNCTIONS) | if (checksum >= ZIO_CHECKSUM_FUNCTIONS) | ||||
return (EINVAL); | return (EINVAL); | ||||
ci = &zio_checksum_table[checksum]; | ci = &zio_checksum_table[checksum]; | ||||
if (ci->ci_func[0] == NULL || ci->ci_func[1] == NULL) | if (ci->ci_func[0] == NULL || ci->ci_func[1] == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (spa != NULL) { | |||||
zio_checksum_template_init(checksum, (spa_t *) spa); | zio_checksum_template_init(checksum, (spa_t *) spa); | ||||
ctx = spa->spa_cksum_tmpls[checksum]; | |||||
} | |||||
if (ci->ci_flags & ZCHECKSUM_FLAG_EMBEDDED) { | if (ci->ci_flags & ZCHECKSUM_FLAG_EMBEDDED) { | ||||
zio_eck_t *eck; | zio_eck_t *eck; | ||||
ASSERT(checksum == ZIO_CHECKSUM_GANG_HEADER || | ASSERT(checksum == ZIO_CHECKSUM_GANG_HEADER || | ||||
checksum == ZIO_CHECKSUM_LABEL); | checksum == ZIO_CHECKSUM_LABEL); | ||||
eck = (zio_eck_t *)((char *)data + size) - 1; | eck = (zio_eck_t *)((char *)data + size) - 1; | ||||
if (checksum == ZIO_CHECKSUM_GANG_HEADER) | if (checksum == ZIO_CHECKSUM_GANG_HEADER) | ||||
zio_checksum_gang_verifier(&verifier, bp); | zio_checksum_gang_verifier(&verifier, bp); | ||||
else if (checksum == ZIO_CHECKSUM_LABEL) | else if (checksum == ZIO_CHECKSUM_LABEL) | ||||
zio_checksum_label_verifier(&verifier, | zio_checksum_label_verifier(&verifier, | ||||
DVA_GET_OFFSET(BP_IDENTITY(bp))); | DVA_GET_OFFSET(BP_IDENTITY(bp))); | ||||
else | else | ||||
verifier = bp->blk_cksum; | verifier = bp->blk_cksum; | ||||
byteswap = (eck->zec_magic == BSWAP_64(ZEC_MAGIC)); | byteswap = (eck->zec_magic == BSWAP_64(ZEC_MAGIC)); | ||||
if (byteswap) | if (byteswap) | ||||
byteswap_uint64_array(&verifier, sizeof (zio_cksum_t)); | byteswap_uint64_array(&verifier, sizeof (zio_cksum_t)); | ||||
expected_cksum = eck->zec_cksum; | expected_cksum = eck->zec_cksum; | ||||
eck->zec_cksum = verifier; | eck->zec_cksum = verifier; | ||||
ci->ci_func[byteswap](data, size, | ci->ci_func[byteswap](data, size, ctx, &actual_cksum); | ||||
spa->spa_cksum_tmpls[checksum], &actual_cksum); | |||||
eck->zec_cksum = expected_cksum; | eck->zec_cksum = expected_cksum; | ||||
if (byteswap) | if (byteswap) | ||||
byteswap_uint64_array(&expected_cksum, | byteswap_uint64_array(&expected_cksum, | ||||
sizeof (zio_cksum_t)); | sizeof (zio_cksum_t)); | ||||
} else { | } else { | ||||
expected_cksum = bp->blk_cksum; | expected_cksum = bp->blk_cksum; | ||||
ci->ci_func[0](data, size, spa->spa_cksum_tmpls[checksum], | ci->ci_func[0](data, size, ctx, &actual_cksum); | ||||
&actual_cksum); | |||||
} | } | ||||
if (!ZIO_CHECKSUM_EQUAL(actual_cksum, expected_cksum)) { | if (!ZIO_CHECKSUM_EQUAL(actual_cksum, expected_cksum)) { | ||||
/*printf("ZFS: read checksum %s failed\n", ci->ci_name);*/ | /*printf("ZFS: read checksum %s failed\n", ci->ci_name);*/ | ||||
return (EIO); | return (EIO); | ||||
} | } | ||||
return (0); | return (0); | ||||
▲ Show 20 Lines • Show All 1,457 Lines • Show Last 20 Lines |