diff --git a/stand/libsa/zfs/Makefile.inc b/stand/libsa/zfs/Makefile.inc index 3f28c39c69da..314f74c903f1 100644 --- a/stand/libsa/zfs/Makefile.inc +++ b/stand/libsa/zfs/Makefile.inc @@ -7,8 +7,10 @@ .PATH: ${OZFS}/module/zstd/lib/common .PATH: ${OZFS}/module/zstd/lib/compress .PATH: ${OZFS}/module/zstd/lib/decompress +.PATH: ${OZFS}/module/icp/algs/blake3 ZFS_SRC= zfs.c nvlist.c skein.c skein_block.c list.c ZFS_SRC+= zfs_zstd.c +ZFS_SRC+= blake3.c blake3_generic.c blake3_impl_hack.c ZSTD_SRC+= entropy_common.c error_private.c ZSTD_SRC+= fse_compress.c fse_decompress.c hist.c ZSTD_SRC+= huf_compress.c huf_decompress.c pool.c xxhash.c @@ -35,6 +37,9 @@ CFLAGS.$i+= -include ${ZFSOSINC}/spl/sys/ccompile.h -Wformat -Wall -I${OZFS}/inc -DNEED_SOLARIS_BOOLEAN .endfor +CFLAGS_EARLY.blake3.c+= ${ZFS_EARLY} +CFLAGS_EARLY.blake3_generic.c+= ${ZFS_EARLY} +CFLAGS_EARLY.blake3_impl_hack.c+= ${ZFS_EARLY} CFLAGS_EARLY.list.c+= ${ZFS_EARLY} CFLAGS_EARLY.zfs_zstd.c+= ${ZFS_EARLY} @@ -58,3 +63,6 @@ CFLAGS.zfs_zstd.c+= -DIN_BASE -DIN_LIBSA # Do not unroll skein loops, reduce code size CFLAGS.skein_block.c+= -DSKEIN_LOOP=111 + +# To puck up blake3_impl.c... +CFLAGS.blake3_impl_hack.c+= -I${OZFS}/module/icp/algs/blake3 diff --git a/stand/libsa/zfs/blake3_impl_hack.c b/stand/libsa/zfs/blake3_impl_hack.c new file mode 100644 index 000000000000..709ce510dad6 --- /dev/null +++ b/stand/libsa/zfs/blake3_impl_hack.c @@ -0,0 +1,28 @@ +/* + * Copyright 2022, Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Hack for aarch64... There's no way to tell it omit the SIMD + * versions, so we fake it here. + */ +#include "blake3_impl.c" + +static inline boolean_t blake3_is_not_supported(void) +{ + return (B_FALSE); +} + +const blake3_impl_ops_t blake3_sse2_impl = { + .is_supported = blake3_is_not_supported, + .degree = 4, + .name = "fakesse2" +}; + +const blake3_impl_ops_t blake3_sse41_impl = { + .is_supported = blake3_is_not_supported, + .degree = 4, + .name = "fakesse41" +}; diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c index 865294dafed4..6b961f3110ae 100644 --- a/stand/libsa/zfs/zfsimpl.c +++ b/stand/libsa/zfs/zfsimpl.c @@ -140,6 +140,7 @@ static const char *features_for_read[] = { "org.freebsd:zstd_compress", "com.delphix:bookmark_written", "com.delphix:head_errlog", + "org.openzfs:blake3", NULL }; diff --git a/sys/cddl/boot/zfs/blake3_zfs.c b/sys/cddl/boot/zfs/blake3_zfs.c new file mode 100644 index 000000000000..0b2e1a014f62 --- /dev/null +++ b/sys/cddl/boot/zfs/blake3_zfs.c @@ -0,0 +1,97 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2022 Tino Reichardt + */ + +#include + +/* + * Computes a native 256-bit BLAKE3 MAC checksum. Please note that this + * function requires the presence of a ctx_template that should be allocated + * using zio_checksum_blake3_tmpl_init. + */ +static void +zio_checksum_blake3_native(const void *buf, uint64_t size, + const void *ctx_template, zio_cksum_t *zcp) +{ + BLAKE3_CTX ctx; + + ASSERT(ctx_template != 0); + + memcpy(&ctx, ctx_template, sizeof(ctx)); + Blake3_Update(&ctx, buf, size); + Blake3_Final(&ctx, (uint8_t *)zcp); + + memset(&ctx, 0, sizeof (ctx)); +} + +/* + * Byteswapped version of zio_checksum_blake3_native. This just invokes + * the native checksum function and byteswaps the resulting checksum (since + * BLAKE3 is internally endian-insensitive). + */ +static void +zio_checksum_blake3_byteswap(const void *buf, uint64_t size, + const void *ctx_template, zio_cksum_t *zcp) +{ + zio_cksum_t tmp; + + ASSERT(ctx_template != 0); + + zio_checksum_blake3_native(buf, size, ctx_template, &tmp); + zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]); + zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]); + zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]); + zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]); +} + +/* + * Allocates a BLAKE3 MAC template suitable for using in BLAKE3 MAC checksum + * computations and returns a pointer to it. + */ +static void * +zio_checksum_blake3_tmpl_init(const zio_cksum_salt_t *salt) +{ + BLAKE3_CTX *ctx; + + ASSERT(sizeof (salt->zcs_bytes) == 32); + + /* init reference object */ + ctx = calloc(1, sizeof(*ctx)); + Blake3_InitKeyed(ctx, salt->zcs_bytes); + + return (ctx); +} + +/* + * Frees a BLAKE3 context template previously allocated using + * zio_checksum_blake3_tmpl_init. + */ +static void +zio_checksum_blake3_tmpl_free(void *ctx_template) +{ + BLAKE3_CTX *ctx = ctx_template; + + memset(ctx, 0, sizeof(*ctx)); + free(ctx); +} diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h index 9b09b3436c8e..d6e8900f6a97 100644 --- a/sys/cddl/boot/zfs/zfsimpl.h +++ b/sys/cddl/boot/zfs/zfsimpl.h @@ -602,6 +602,7 @@ enum zio_checksum { ZIO_CHECKSUM_SHA512, ZIO_CHECKSUM_SKEIN, ZIO_CHECKSUM_EDONR, + ZIO_CHECKSUM_BLAKE3, ZIO_CHECKSUM_FUNCTIONS }; diff --git a/sys/cddl/boot/zfs/zfssubr.c b/sys/cddl/boot/zfs/zfssubr.c index 2e309fc10be4..c5ee4fda4579 100644 --- a/sys/cddl/boot/zfs/zfssubr.c +++ b/sys/cddl/boot/zfs/zfssubr.c @@ -102,6 +102,7 @@ typedef struct zio_checksum_info { #include "blkptr.c" #include "fletcher.c" +#include "blake3_zfs.c" #include "sha256.c" #include "skein_zfs.c" @@ -140,7 +141,11 @@ static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "skein"}, /* no edonr for now */ {{NULL, NULL}, NULL, NULL, ZCHECKSUM_FLAG_METADATA | - ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "edonr"} + ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "edonr"}, + {{zio_checksum_blake3_native, zio_checksum_blake3_byteswap}, + zio_checksum_blake3_tmpl_init, zio_checksum_blake3_tmpl_free, + ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_DEDUP | + ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "blake3"} }; /*