Index: Makefile.inc1 =================================================================== --- Makefile.inc1 +++ Makefile.inc1 @@ -2398,7 +2398,7 @@ ${_cddl_lib_libctf} \ lib/libutil lib/libpjdlog ${_lib_libypclnt} lib/libz lib/msun \ ${_secure_lib_libcrypto} ${_lib_libldns} \ - ${_secure_lib_libssh} ${_secure_lib_libssl} + ${_secure_lib_libssh} ${_secure_lib_libssl} lib/libzstd .if ${MK_GNUCXX} != "no" _prebuild_libs+= gnu/lib/libstdc++ gnu/lib/libsupc++ Index: cddl/lib/libzfs/Makefile =================================================================== --- cddl/lib/libzfs/Makefile +++ cddl/lib/libzfs/Makefile @@ -7,7 +7,7 @@ .PATH: ${SRCTOP}/cddl/contrib/opensolaris/lib/libcmdutils/common LIB= zfs -LIBADD= md pthread umem util uutil m avl bsdxml geom nvpair z zfs_core +LIBADD= md pthread umem util uutil m avl bsdxml geom nvpair z zfs_core zstd SRCS= deviceid.c \ fsshare.c \ mkdirp.c \ Index: cddl/lib/libzpool/Makefile =================================================================== --- cddl/lib/libzpool/Makefile +++ cddl/lib/libzpool/Makefile @@ -62,8 +62,10 @@ CFLAGS+= -I${SRCTOP}/lib/libpthread/thread CFLAGS+= -I${SRCTOP}/lib/libpthread/sys CFLAGS+= -I${SRCTOP}/lib/libthr/arch/${MACHINE_CPUARCH}/include +CFLAGS+= -I${SRCTOP}/sys/contrib/zstd/lib +CFLAGS+= -I${SRCTOP}/sys/contrib/zstd/lib/common -LIBADD= md pthread z nvpair avl umem +LIBADD= md pthread z nvpair avl umem zstd # atomic.S doesn't like profiling. MK_PROFILE= no Index: rescue/rescue/Makefile =================================================================== --- rescue/rescue/Makefile +++ rescue/rescue/Makefile @@ -126,7 +126,7 @@ CRUNCH_LIBS+= -l80211 -lalias -lcam -lncursesw -ldevstat -lipsec -llzma .if ${MK_ZFS} != "no" -CRUNCH_LIBS+= -lavl -lzpool -lzfs_core -lzfs -lnvpair -lpthread -luutil -lumem +CRUNCH_LIBS+= -lavl -lzpool -lzfs_core -lzfs -lnvpair -lpthread -luutil -lumem -lprivatezstd .else # liblzma needs pthread CRUNCH_LIBS+= -lpthread Index: share/mk/src.libnames.mk =================================================================== --- share/mk/src.libnames.mk +++ share/mk/src.libnames.mk @@ -325,9 +325,9 @@ _DP_fifolog= z _DP_ipf= kvm _DP_zfs= md pthread umem util uutil m nvpair avl bsdxml geom nvpair z \ - zfs_core + zfs_core zstd _DP_zfs_core= nvpair -_DP_zpool= md pthread z nvpair avl umem +_DP_zpool= md pthread z nvpair avl umem zstd # OFED support .if ${MK_OFED} != "no" Index: stand/efi/boot1/Makefile =================================================================== --- stand/efi/boot1/Makefile +++ stand/efi/boot1/Makefile @@ -29,6 +29,7 @@ CFLAGS.zfs_module.c+= -I${ZFSSRC} CFLAGS.zfs_module.c+= -I${SYSDIR}/cddl/boot/zfs CFLAGS.zfs_module.c+= -I${SYSDIR}/crypto/skein +CFLAGS+= -I${SYSDIR}/contrib/zstd/lib CFLAGS+= -DEFI_ZFS_BOOT LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a .endif Index: stand/efi/boot1/boot1.c =================================================================== --- stand/efi/boot1/boot1.c +++ stand/efi/boot1/boot1.c @@ -73,6 +73,18 @@ return (NULL); } +void * +Calloc(size_t number, size_t len, const char *file __unused, int line __unused) +{ + uintptr_t bytes = (uintptr_t)number * (uintptr_t)len; + void *out; + + if ((out = Malloc(bytes, file, line)) != NULL) + bzero(out, bytes); + + return(out); +} + void Free(void *buf, const char *file __unused, int line __unused) { Index: stand/i386/gptzfsboot/Makefile =================================================================== --- stand/i386/gptzfsboot/Makefile +++ stand/i386/gptzfsboot/Makefile @@ -32,6 +32,7 @@ -I${ZFSSRC} \ -I${SYSDIR}/crypto/skein \ -I${SYSDIR}/cddl/boot/zfs \ + -I${SYSDIR}/contrib/zstd/lib \ -I${BOOTSRC}/i386/btx/lib \ -I${BOOTSRC}/i386/boot2 \ -Wall -Waggregate-return -Wbad-function-cast \ Index: stand/i386/zfsboot/Makefile =================================================================== --- stand/i386/zfsboot/Makefile +++ stand/i386/zfsboot/Makefile @@ -31,6 +31,7 @@ -I${ZFSSRC} \ -I${SYSDIR}/crypto/skein \ -I${SYSDIR}/cddl/boot/zfs \ + -I${SYSDIR}/contrib/zstd/lib \ -I${BOOTSRC}/i386/boot2 \ -Wall -Waggregate-return -Wbad-function-cast -Wno-cast-align \ -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \ Index: stand/libsa/Makefile =================================================================== --- stand/libsa/Makefile +++ stand/libsa/Makefile @@ -81,6 +81,31 @@ .PATH: ${SASRC}/${LIBSA_CPUARCH} SRCS+= _setjmp.S +# decompression functionality from libzstd +.PATH: ${SRCTOP}/sys/contrib/zstd/lib +CFLAGS+= -I${SRCTOP}/sys/contrib/zstd/lib +.PATH: ${SRCTOP}/sys/contrib/zstd/lib/common +CFLAGS+= -I${SRCTOP}/sys/contrib/zstd/lib/common +.PATH: ${SRCTOP}/sys/contrib/zstd/lib/compress +CFLAGS+= -I${SRCTOP}/sys/contrib/zstd/lib/compress +.PATH: ${SRCTOP}/sys/contrib/zstd/lib/decompress +CFLAGS+= -I${SRCTOP}/sys/contrib/zstd/lib/decompress +.for file in zstd_common.c fse_decompress.c entropy_common.c error_private.c \ + xxhash.c zstd_compress.c fse_compress.c huf_compress.c \ + zstd_double_fast.c zstd_fast.c zstd_lazy.c zstd_ldm.c zstd_opt.c \ + zstd_decompress.c huf_decompress.c +SRCS+= _${file} +CLEANFILES+= _${file} + +_${file}: ${file} + sed -e 's||"stand.h"|' \ + -e 's||"stand.h"|' \ + -e 's||"stand.h"|' \ + -e 's||"stand.h"|' \ + -e 's||"stand.h"|' \ + ${.ALLSRC} > ${.TARGET} +.endfor + # decompression functionality from libbz2 # NOTE: to actually test this functionality after libbz2 upgrade compile # loader(8) with LOADER_BZIP2_SUPPORT defined Index: stand/zfs/Makefile =================================================================== --- stand/zfs/Makefile +++ stand/zfs/Makefile @@ -13,6 +13,7 @@ CFLAGS+= -DBOOTPROG=\"zfsloader\" CFLAGS+= -I${LDRSRC} CFLAGS+= -I${SYSDIR}/cddl/boot/zfs +CFLAGS+= -I${SYSDIR}/contrib/zstd/lib CFLAGS+= -I${SYSDIR}/crypto/skein CFLAGS+= -Wformat -Wall Index: sys/cddl/boot/zfs/zfsimpl.h =================================================================== --- sys/cddl/boot/zfs/zfsimpl.h +++ sys/cddl/boot/zfs/zfsimpl.h @@ -561,6 +561,7 @@ ZIO_COMPRESS_GZIP_9, ZIO_COMPRESS_ZLE, ZIO_COMPRESS_LZ4, + ZIO_COMPRESS_ZSTD, ZIO_COMPRESS_FUNCTIONS }; Index: sys/cddl/boot/zfs/zfssubr.c =================================================================== --- sys/cddl/boot/zfs/zfssubr.c +++ sys/cddl/boot/zfs/zfssubr.c @@ -162,6 +162,7 @@ #include "lzjb.c" #include "zle.c" #include "lz4.c" +#include "zstd.c" /* * Compression vectors. @@ -183,6 +184,7 @@ {NULL, NULL, 9, "gzip-9"}, {NULL, zle_decompress, 64, "zle"}, {NULL, lz4_decompress, 0, "lz4"}, + {NULL, zstd_decompress, 0, "zstd"}, }; static void Index: sys/cddl/boot/zfs/zstd.c =================================================================== --- /dev/null +++ sys/cddl/boot/zfs/zstd.c @@ -0,0 +1,87 @@ +/* + * 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://www.opensolaris.org/os/licensing. + * 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 (c) 2016-2017 by ScaleEngine Inc. All rights reserved. + * Copyright (c) 2017 Allan Jude . All rights reserved. + */ + +#include + +#define ZSTD_STATIC_LINKING_ONLY +#include + +#define ZSTD_COOKIE_SHIFT 26 +#define ZSTD_COOKIE_MASK ((1U<= s_len); + + /* invalid compressed buffer size encoded at start */ + if (bufsiz + sizeof (cookie) > s_len) { + printf("ZFS: Failed to decode ZSTD decompression header\n"); + return (1); + } + + /* + * Returns 0 on success (decompression function returned non-negative) + * and non-zero on failure (decompression function returned negative. + */ + ZSTD_DCtx *dctx; + + if (dctxbuf == NULL) { + dctxsize = ZSTD_estimateDCtxSize(); + dctxbuf = malloc(dctxsize + 8); + if (dctxbuf == NULL) { + printf("ZFS: memory allocation failure\n"); + return (1); + } + /* Pointer must be 8 byte aligned */ + dctxbuf = (char *)roundup2((uintptr_t)dctxbuf, 8); + } + + dctx = ZSTD_initStaticDCtx(dctxbuf, dctxsize); + if (dctx == NULL) { + printf("ZFS: failed to initialize ZSTD decompress context\n"); + return (1); + } + + result = ZSTD_decompressDCtx(dctx, d_start, d_len, + &src[sizeof (cookie)], bufsiz); + if (ZSTD_isError(result)) { + printf("ZFS: Failed to decompress block: %s\n", + ZSTD_getErrorName(result)); + return (1); + } + + return (0); +} Index: sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h =================================================================== --- sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h +++ sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h @@ -57,6 +57,7 @@ #ifdef illumos SPA_FEATURE_EDONR, #endif + SPA_FEATURE_ZSTD_COMPRESS, SPA_FEATURES } spa_feature_t; Index: sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c =================================================================== --- sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c +++ sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c @@ -247,4 +247,10 @@ "Edon-R hash algorithm.", ZFEATURE_FLAG_PER_DATASET, NULL); #endif + + zfeature_register(SPA_FEATURE_ZSTD_COMPRESS, + "org.freebsd:zstd_compress", "zstd_compress", + "zstd compression algorithm support.", + ZFEATURE_FLAG_PER_DATASET, NULL); + } Index: sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c =================================================================== --- sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c +++ sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c @@ -116,6 +116,52 @@ { "gzip-9", ZIO_COMPRESS_GZIP_9 }, { "zle", ZIO_COMPRESS_ZLE }, { "lz4", ZIO_COMPRESS_LZ4 }, + { "zstd", ZIO_COMPRESS_ZSTD }, + /* + * ZSTD 1-19 are synthetic. We store the compression level in a + * separate hidden property to avoid wasting a large amount of + * space in the ZIO_COMPRESS enum. We do not need to know the + * compression level at decompress time, so it does not need + * to be stored on disk in the block pointer. + */ + { "zstd-1", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_1 << SPA_COMPRESSBITS) }, + { "zstd-2", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_2 << SPA_COMPRESSBITS) }, + { "zstd-3", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_3 << SPA_COMPRESSBITS) }, + { "zstd-4", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_4 << SPA_COMPRESSBITS) }, + { "zstd-5", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_5 << SPA_COMPRESSBITS) }, + { "zstd-6", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_6 << SPA_COMPRESSBITS) }, + { "zstd-7", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_7 << SPA_COMPRESSBITS) }, + { "zstd-8", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_8 << SPA_COMPRESSBITS) }, + { "zstd-9", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_9 << SPA_COMPRESSBITS) }, + { "zstd-10", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_10 << SPA_COMPRESSBITS) }, + { "zstd-11", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_11 << SPA_COMPRESSBITS) }, + { "zstd-12", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_12 << SPA_COMPRESSBITS) }, + { "zstd-13", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_13 << SPA_COMPRESSBITS) }, + { "zstd-14", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_14 << SPA_COMPRESSBITS) }, + { "zstd-15", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_15 << SPA_COMPRESSBITS) }, + { "zstd-16", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_16 << SPA_COMPRESSBITS) }, + { "zstd-17", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_17 << SPA_COMPRESSBITS) }, + { "zstd-18", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_18 << SPA_COMPRESSBITS) }, + { "zstd-19", ZIO_COMPRESS_ZSTD | + (ZIO_ZSTDLVL_19 << SPA_COMPRESSBITS) }, { NULL } }; @@ -250,7 +296,8 @@ zprop_register_index(ZFS_PROP_COMPRESSION, "compression", ZIO_COMPRESS_DEFAULT, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, - "on | off | lzjb | gzip | gzip-[1-9] | zle | lz4", + "on | off | lzjb | gzip | gzip-[1-9] | zle | lz4" + " | zstd | zstd-[1-19]", "COMPRESS", compress_table); zprop_register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN, PROP_INHERIT, ZFS_TYPE_FILESYSTEM, @@ -460,6 +507,9 @@ PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "PREVSNAP"); /* oddball properties */ + zprop_register_impl(ZFS_PROP_ZSTD_LEVEL, "zstd_compress_level", + PROP_TYPE_NUMBER, ZIO_ZSTDLVL_DEFAULT, NULL, PROP_INHERIT, + ZFS_TYPE_DATASET, "[1-19]", "ZSTDLEVEL", B_TRUE, B_TRUE, NULL); zprop_register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0, NULL, PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "", "CREATION", B_FALSE, B_TRUE, NULL); Index: sys/cddl/contrib/opensolaris/uts/common/Makefile.files =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/Makefile.files +++ sys/cddl/contrib/opensolaris/uts/common/Makefile.files @@ -144,7 +144,8 @@ zio_compress.o \ zio_inject.o \ zle.o \ - zrlock.o + zrlock.o \ + zstd.o ZFS_SHARED_OBJS += \ zfeature_common.o \ Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -1021,6 +1021,7 @@ arc_buf_contents_t b_type; arc_buf_hdr_t *b_hash_next; arc_flags_t b_flags; + enum zio_zstd_levels b_complevel; /* * This field stores the size of the data buffer after @@ -1857,11 +1858,23 @@ uint64_t lsize = HDR_GET_LSIZE(hdr); uint64_t csize; - abd_t *cdata = abd_alloc_linear(HDR_GET_PSIZE(hdr), B_TRUE); + abd_t *cdata = abd_alloc_linear(lsize, B_TRUE); csize = zio_compress_data(compress, zio->io_abd, - abd_to_buf(cdata), lsize); + abd_to_buf(cdata), lsize, &zio->io_prop); - ASSERT3U(csize, <=, HDR_GET_PSIZE(hdr)); + if (csize == 0 || csize == lsize) { + /* Compression has failed */ + /* XXX: Should we retry here? */ + return (B_FALSE); + } + + if (csize > HDR_GET_PSIZE(hdr)) { + /* + * Compression produced a larger output, the checksum + * cannot possibly match. + */ + return (B_FALSE); + } if (csize < HDR_GET_PSIZE(hdr)) { /* * Compressed blocks are always a multiple of the @@ -5068,6 +5081,9 @@ } else { hdr->b_l1hdr.b_byteswap = DMU_BSWAP_NUMFUNCS; } + if (BP_GET_COMPRESS(zio->io_bp) == ZIO_COMPRESS_ZSTD) { + hdr->b_complevel = zio->io_prop.zp_zstd_level; + } } arc_hdr_clear_flags(hdr, ARC_FLAG_L2_EVICTED); @@ -6053,6 +6069,9 @@ * the pre-compressed buffer's compression algorithm. */ localprop.zp_compress = HDR_GET_COMPRESS(hdr); + if (localprop.zp_compress == ZIO_COMPRESS_ZSTD) { + localprop.zp_zstd_level = hdr->b_complevel; + } ASSERT3U(HDR_GET_LSIZE(hdr), !=, arc_buf_size(buf)); zio_flags |= ZIO_FLAG_RAW; @@ -7154,6 +7173,9 @@ zio->io_bp_copy = cb->l2rcb_bp; /* XXX fix in L2ARC 2.0 */ zio->io_bp = &zio->io_bp_copy; /* XXX fix in L2ARC 2.0 */ + if (BP_GET_COMPRESS(zio->io_bp) == ZIO_COMPRESS_ZSTD) { + zio->io_prop.zp_zstd_level = hdr->b_complevel; + } valid_cksum = arc_cksum_is_equal(hdr, zio); if (valid_cksum && zio->io_error == 0 && !HDR_L2_EVICTED(hdr)) { mutex_exit(hash_lock); Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c @@ -2194,6 +2194,7 @@ (wp & WP_SPILL)); enum zio_checksum checksum = os->os_checksum; enum zio_compress compress = os->os_compress; + enum zio_zstd_levels zstd_level = os->os_zstd_level; enum zio_checksum dedup_checksum = os->os_dedup_checksum; boolean_t dedup = B_FALSE; boolean_t nopwrite = B_FALSE; @@ -2288,6 +2289,8 @@ zp->zp_checksum = checksum; zp->zp_compress = compress; ASSERT3U(zp->zp_compress, !=, ZIO_COMPRESS_INHERIT); + zp->zp_zstd_level = zstd_level; + ASSERT3U(zp->zp_zstd_level, !=, ZIO_ZSTDLVL_INHERIT); zp->zp_type = (wp & WP_SPILL) ? dn->dn_bonustype : type; zp->zp_level = level; Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c @@ -178,6 +178,20 @@ } static void +zstd_level_changed_cb(void *arg, uint64_t newval) +{ + objset_t *os = arg; + + /* + * Inheritance and range checking should have been done by now. + */ + ASSERT(newval != ZIO_ZSTDLVL_INHERIT); + + os->os_zstd_level = zio_zstd_level_select(os->os_spa, newval, + ZIO_ZSTDLVL_DEFAULT); +} + +static void copies_changed_cb(void *arg, uint64_t newval) { objset_t *os = arg; @@ -435,6 +449,11 @@ } if (err == 0) { err = dsl_prop_register(ds, + zfs_prop_to_name(ZFS_PROP_ZSTD_LEVEL), + zstd_level_changed_cb, os); + } + if (err == 0) { + err = dsl_prop_register(ds, zfs_prop_to_name(ZFS_PROP_COPIES), copies_changed_cb, os); } @@ -476,6 +495,7 @@ /* It's the meta-objset. */ os->os_checksum = ZIO_CHECKSUM_FLETCHER_4; os->os_compress = ZIO_COMPRESS_ON; + os->os_zstd_level = ZIO_ZSTDLVL_DEFAULT; os->os_copies = spa_max_replication(spa); os->os_dedup_checksum = ZIO_CHECKSUM_OFF; os->os_dedup_verify = B_FALSE; Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c @@ -2019,6 +2019,7 @@ metaslab_alloc_trace_init(); zio_init(); lz4_init(); + zstd_init(); dmu_init(); zil_init(); vdev_cache_stat_init(); @@ -2047,6 +2048,7 @@ zil_fini(); dmu_fini(); lz4_fini(); + zstd_fini(); zio_fini(); metaslab_alloc_trace_fini(); range_tree_fini(); Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h @@ -91,6 +91,7 @@ /* can change, under dsl_dir's locks: */ enum zio_checksum os_checksum; enum zio_compress os_compress; + enum zio_zstd_levels os_zstd_level; uint8_t os_copies; enum zio_checksum os_dedup_checksum; boolean_t os_dedup_verify; Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h @@ -152,6 +152,7 @@ #define SPA_ASIZEBITS 24 /* ASIZE up to 64 times larger */ #define SPA_COMPRESSBITS 7 +#define SPA_COMPRESSMASK ((1U<