diff options
Diffstat (limited to 'include/sys')
-rw-r--r-- | include/sys/Makefile.am | 2 | ||||
-rw-r--r-- | include/sys/arc.h | 12 | ||||
-rw-r--r-- | include/sys/arc_impl.h | 6 | ||||
-rw-r--r-- | include/sys/dmu_objset.h | 1 | ||||
-rw-r--r-- | include/sys/dsl_dataset.h | 2 | ||||
-rw-r--r-- | include/sys/spa.h | 3 | ||||
-rw-r--r-- | include/sys/zfs_context.h | 6 | ||||
-rw-r--r-- | include/sys/zfs_ioctl.h | 5 | ||||
-rw-r--r-- | include/sys/zio.h | 15 | ||||
-rw-r--r-- | include/sys/zio_compress.h | 81 | ||||
-rw-r--r-- | include/sys/zio_impl.h | 6 | ||||
-rw-r--r-- | include/sys/zstd/Makefile.am | 18 | ||||
-rw-r--r-- | include/sys/zstd/zstd.h | 98 |
13 files changed, 241 insertions, 14 deletions
diff --git a/include/sys/Makefile.am b/include/sys/Makefile.am index cbe21b791..c2bc3be03 100644 --- a/include/sys/Makefile.am +++ b/include/sys/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = fm fs crypto lua sysevent +SUBDIRS = fm fs crypto lua sysevent zstd COMMON_H = \ abd.h \ diff --git a/include/sys/arc.h b/include/sys/arc.h index 3fdf36e2a..a0852b4d5 100644 --- a/include/sys/arc.h +++ b/include/sys/arc.h @@ -22,6 +22,8 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. + * Copyright (c) 2019, Allan Jude + * Copyright (c) 2019, Klara Inc. */ #ifndef _SYS_ARC_H @@ -252,18 +254,20 @@ void arc_convert_to_raw(arc_buf_t *buf, uint64_t dsobj, boolean_t byteorder, arc_buf_t *arc_alloc_buf(spa_t *spa, void *tag, arc_buf_contents_t type, int32_t size); arc_buf_t *arc_alloc_compressed_buf(spa_t *spa, void *tag, - uint64_t psize, uint64_t lsize, enum zio_compress compression_type); + uint64_t psize, uint64_t lsize, enum zio_compress compression_type, + uint8_t complevel); arc_buf_t *arc_alloc_raw_buf(spa_t *spa, void *tag, uint64_t dsobj, boolean_t byteorder, const uint8_t *salt, const uint8_t *iv, const uint8_t *mac, dmu_object_type_t ot, uint64_t psize, uint64_t lsize, - enum zio_compress compression_type); + enum zio_compress compression_type, uint8_t complevel); +uint8_t arc_get_complevel(arc_buf_t *buf); arc_buf_t *arc_loan_buf(spa_t *spa, boolean_t is_metadata, int size); arc_buf_t *arc_loan_compressed_buf(spa_t *spa, uint64_t psize, uint64_t lsize, - enum zio_compress compression_type); + enum zio_compress compression_type, uint8_t complevel); arc_buf_t *arc_loan_raw_buf(spa_t *spa, uint64_t dsobj, boolean_t byteorder, const uint8_t *salt, const uint8_t *iv, const uint8_t *mac, dmu_object_type_t ot, uint64_t psize, uint64_t lsize, - enum zio_compress compression_type); + enum zio_compress compression_type, uint8_t complevel); void arc_return_buf(arc_buf_t *buf, void *tag); void arc_loan_inuse_buf(arc_buf_t *buf, void *tag); void arc_buf_destroy(arc_buf_t *buf, void *tag); diff --git a/include/sys/arc_impl.h b/include/sys/arc_impl.h index d07791d07..9051fd2bf 100644 --- a/include/sys/arc_impl.h +++ b/include/sys/arc_impl.h @@ -269,12 +269,13 @@ typedef struct l2arc_log_ent_phys { */ uint64_t le_prop; uint64_t le_daddr; /* buf location on l2dev */ + uint64_t le_complevel; /* * We pad the size of each entry to a power of 2 so that the size of * l2arc_log_blk_phys_t is power-of-2 aligned with SPA_MINBLOCKSHIFT, * because of the L2ARC_SET_*SIZE macros. */ - const uint64_t le_pad[3]; /* pad to 64 bytes */ + const uint64_t le_pad[2]; /* pad to 64 bytes */ } l2arc_log_ent_phys_t; #define L2ARC_LOG_BLK_MAX_ENTRIES (1022) @@ -460,6 +461,9 @@ struct arc_buf_hdr { uint64_t b_birth; arc_buf_contents_t b_type; + uint8_t b_complevel; + uint8_t b_reserved1; /* used for 4 byte alignment */ + uint16_t b_reserved2; /* used for 4 byte alignment */ arc_buf_hdr_t *b_hash_next; arc_flags_t b_flags; diff --git a/include/sys/dmu_objset.h b/include/sys/dmu_objset.h index a77131ef1..1af69832c 100644 --- a/include/sys/dmu_objset.h +++ b/include/sys/dmu_objset.h @@ -118,6 +118,7 @@ struct objset { uint64_t os_dnodesize; /* default dnode size for new objects */ enum zio_checksum os_checksum; enum zio_compress os_compress; + uint8_t os_complevel; uint8_t os_copies; enum zio_checksum os_dedup_checksum; boolean_t os_dedup_verify; diff --git a/include/sys/dsl_dataset.h b/include/sys/dsl_dataset.h index 90cb68927..f5816a934 100644 --- a/include/sys/dsl_dataset.h +++ b/include/sys/dsl_dataset.h @@ -435,6 +435,8 @@ int dsl_dataset_set_refquota(const char *dsname, zprop_source_t source, uint64_t quota); int dsl_dataset_set_refreservation(const char *dsname, zprop_source_t source, uint64_t reservation); +int dsl_dataset_set_compression(const char *dsname, zprop_source_t source, + uint64_t compression); boolean_t dsl_dataset_is_before(dsl_dataset_t *later, dsl_dataset_t *earlier, uint64_t earlier_txg); diff --git a/include/sys/spa.h b/include/sys/spa.h index 67de57980..e53d0d64c 100644 --- a/include/sys/spa.h +++ b/include/sys/spa.h @@ -28,6 +28,8 @@ * Copyright 2017 Joyent, Inc. * Copyright (c) 2017, 2019, Datto Inc. All rights reserved. * Copyright (c) 2017, Intel Corporation. + * Copyright (c) 2019, Allan Jude + * Copyright (c) 2019, Klara Inc. */ #ifndef _SYS_SPA_H @@ -120,6 +122,7 @@ struct dsl_crypto_params; #define SPA_COMPRESSBITS 7 #define SPA_VDEVBITS 24 +#define SPA_COMPRESSMASK ((1U << SPA_COMPRESSBITS) - 1) /* * All SPA data is represented by 128-bit data virtual addresses (DVAs). diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 0d41941dd..16df302c8 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -748,6 +748,12 @@ extern int kmem_cache_reap_active(void); #define ____cacheline_aligned +/* + * Kernel modules + */ +#define __init +#define __exit + #endif /* _KERNEL */ #ifdef __cplusplus diff --git a/include/sys/zfs_ioctl.h b/include/sys/zfs_ioctl.h index bfaf81038..136075a1f 100644 --- a/include/sys/zfs_ioctl.h +++ b/include/sys/zfs_ioctl.h @@ -105,7 +105,7 @@ typedef enum drr_headertype { #define DMU_BACKUP_FEATURE_COMPRESSED (1 << 22) #define DMU_BACKUP_FEATURE_LARGE_DNODE (1 << 23) #define DMU_BACKUP_FEATURE_RAW (1 << 24) -/* flag #25 is reserved for the ZSTD compression feature */ +#define DMU_BACKUP_FEATURE_ZSTD (1 << 25) #define DMU_BACKUP_FEATURE_HOLDS (1 << 26) /* * The SWITCH_TO_LARGE_BLOCKS feature indicates that we can receive @@ -132,7 +132,8 @@ typedef enum drr_headertype { DMU_BACKUP_FEATURE_RESUMING | DMU_BACKUP_FEATURE_LARGE_BLOCKS | \ DMU_BACKUP_FEATURE_COMPRESSED | DMU_BACKUP_FEATURE_LARGE_DNODE | \ DMU_BACKUP_FEATURE_RAW | DMU_BACKUP_FEATURE_HOLDS | \ - DMU_BACKUP_FEATURE_REDACTED | DMU_BACKUP_FEATURE_SWITCH_TO_LARGE_BLOCKS) + DMU_BACKUP_FEATURE_REDACTED | DMU_BACKUP_FEATURE_SWITCH_TO_LARGE_BLOCKS | \ + DMU_BACKUP_FEATURE_ZSTD) /* Are all features in the given flag word currently supported? */ #define DMU_STREAM_SUPPORTED(x) (!((x) & ~DMU_BACKUP_FEATURE_MASK)) diff --git a/include/sys/zio.h b/include/sys/zio.h index dc4942a5d..f3b5a1207 100644 --- a/include/sys/zio.h +++ b/include/sys/zio.h @@ -26,6 +26,9 @@ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright 2016 Toomas Soome <[email protected]> + * Copyright (c) 2019, Allan Jude + * Copyright (c) 2019, Klara Inc. + * Copyright (c) 2019-2020, Michael Niewöhner */ #ifndef _ZIO_H @@ -156,9 +159,18 @@ enum zio_encrypt { (compress) == ZIO_COMPRESS_GZIP_8 || \ (compress) == ZIO_COMPRESS_GZIP_9 || \ (compress) == ZIO_COMPRESS_ZLE || \ + (compress) == ZIO_COMPRESS_ZSTD || \ (compress) == ZIO_COMPRESS_ON || \ (compress) == ZIO_COMPRESS_OFF) + +#define ZIO_COMPRESS_ALGO(x) (x & SPA_COMPRESSMASK) +#define ZIO_COMPRESS_LEVEL(x) ((x & ~SPA_COMPRESSMASK) >> SPA_COMPRESSBITS) +#define ZIO_COMPRESS_RAW(type, level) (type | ((level) << SPA_COMPRESSBITS)) + +#define ZIO_COMPLEVEL_ZSTD(level) \ + ZIO_COMPRESS_RAW(ZIO_COMPRESS_ZSTD, level) + #define ZIO_FAILURE_MODE_WAIT 0 #define ZIO_FAILURE_MODE_CONTINUE 1 #define ZIO_FAILURE_MODE_PANIC 2 @@ -329,6 +341,7 @@ struct zbookmark_phys { typedef struct zio_prop { enum zio_checksum zp_checksum; enum zio_compress zp_compress; + uint8_t zp_complevel; dmu_object_type_t zp_type; uint8_t zp_level; uint8_t zp_copies; @@ -627,6 +640,8 @@ extern enum zio_checksum zio_checksum_dedup_select(spa_t *spa, enum zio_checksum child, enum zio_checksum parent); extern enum zio_compress zio_compress_select(spa_t *spa, enum zio_compress child, enum zio_compress parent); +extern uint8_t zio_complevel_select(spa_t *spa, enum zio_compress compress, + uint8_t child, uint8_t parent); extern void zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t); extern int zio_resume(spa_t *spa); diff --git a/include/sys/zio_compress.h b/include/sys/zio_compress.h index 208117eee..4a22ad2a2 100644 --- a/include/sys/zio_compress.h +++ b/include/sys/zio_compress.h @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2019, Allan Jude + * Copyright (c) 2019, Klara Inc. * Use is subject to license terms. * Copyright (c) 2015, 2016 by Delphix. All rights reserved. */ @@ -51,15 +53,86 @@ enum zio_compress { ZIO_COMPRESS_GZIP_9, ZIO_COMPRESS_ZLE, ZIO_COMPRESS_LZ4, + ZIO_COMPRESS_ZSTD, ZIO_COMPRESS_FUNCTIONS }; +/* Compression algorithms that have levels */ +#define ZIO_COMPRESS_HASLEVEL(compress) ((compress == ZIO_COMPRESS_ZSTD || \ + (compress >= ZIO_COMPRESS_GZIP_1 && \ + compress <= ZIO_COMPRESS_GZIP_9))) + +#define ZIO_COMPLEVEL_INHERIT 0 +#define ZIO_COMPLEVEL_DEFAULT 255 + +enum zio_zstd_levels { + ZIO_ZSTD_LEVEL_INHERIT = 0, + ZIO_ZSTD_LEVEL_1, +#define ZIO_ZSTD_LEVEL_MIN ZIO_ZSTD_LEVEL_1 + ZIO_ZSTD_LEVEL_2, + ZIO_ZSTD_LEVEL_3, +#define ZIO_ZSTD_LEVEL_DEFAULT ZIO_ZSTD_LEVEL_3 + ZIO_ZSTD_LEVEL_4, + ZIO_ZSTD_LEVEL_5, + ZIO_ZSTD_LEVEL_6, + ZIO_ZSTD_LEVEL_7, + ZIO_ZSTD_LEVEL_8, + ZIO_ZSTD_LEVEL_9, + ZIO_ZSTD_LEVEL_10, + ZIO_ZSTD_LEVEL_11, + ZIO_ZSTD_LEVEL_12, + ZIO_ZSTD_LEVEL_13, + ZIO_ZSTD_LEVEL_14, + ZIO_ZSTD_LEVEL_15, + ZIO_ZSTD_LEVEL_16, + ZIO_ZSTD_LEVEL_17, + ZIO_ZSTD_LEVEL_18, + ZIO_ZSTD_LEVEL_19, +#define ZIO_ZSTD_LEVEL_MAX ZIO_ZSTD_LEVEL_19 + ZIO_ZSTD_LEVEL_RESERVE = 101, /* Leave room for new positive levels */ + ZIO_ZSTD_LEVEL_FAST, /* Fast levels are negative */ + ZIO_ZSTD_LEVEL_FAST_1, +#define ZIO_ZSTD_LEVEL_FAST_DEFAULT ZIO_ZSTD_LEVEL_FAST_1 + ZIO_ZSTD_LEVEL_FAST_2, + ZIO_ZSTD_LEVEL_FAST_3, + ZIO_ZSTD_LEVEL_FAST_4, + ZIO_ZSTD_LEVEL_FAST_5, + ZIO_ZSTD_LEVEL_FAST_6, + ZIO_ZSTD_LEVEL_FAST_7, + ZIO_ZSTD_LEVEL_FAST_8, + ZIO_ZSTD_LEVEL_FAST_9, + ZIO_ZSTD_LEVEL_FAST_10, + ZIO_ZSTD_LEVEL_FAST_20, + ZIO_ZSTD_LEVEL_FAST_30, + ZIO_ZSTD_LEVEL_FAST_40, + ZIO_ZSTD_LEVEL_FAST_50, + ZIO_ZSTD_LEVEL_FAST_60, + ZIO_ZSTD_LEVEL_FAST_70, + ZIO_ZSTD_LEVEL_FAST_80, + ZIO_ZSTD_LEVEL_FAST_90, + ZIO_ZSTD_LEVEL_FAST_100, + ZIO_ZSTD_LEVEL_FAST_500, + ZIO_ZSTD_LEVEL_FAST_1000, +#define ZIO_ZSTD_LEVEL_FAST_MAX ZIO_ZSTD_LEVEL_FAST_1000 + ZIO_ZSTD_LEVEL_AUTO = 251, /* Reserved for future use */ + ZIO_ZSTD_LEVEL_LEVELS +}; + +/* Forward Declaration to avoid visibility problems */ +struct zio_prop; + /* Common signature for all zio compress functions. */ typedef size_t zio_compress_func_t(void *src, void *dst, size_t s_len, size_t d_len, int); /* Common signature for all zio decompress functions. */ typedef int zio_decompress_func_t(void *src, void *dst, size_t s_len, size_t d_len, int); +/* Common signature for all zio decompress and get level functions. */ +typedef int zio_decompresslevel_func_t(void *src, void *dst, + size_t s_len, size_t d_len, uint8_t *level); +/* Common signature for all zio get-compression-level functions. */ +typedef int zio_getlevel_func_t(void *src, size_t s_len, uint8_t *level); + /* * Common signature for all zio decompress functions using an ABD as input. @@ -76,6 +149,7 @@ typedef const struct zio_compress_info { int ci_level; zio_compress_func_t *ci_compress; zio_decompress_func_t *ci_decompress; + zio_decompresslevel_func_t *ci_decompress_level; } zio_compress_info_t; extern zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS]; @@ -110,11 +184,12 @@ extern int lz4_decompress_zfs(void *src, void *dst, size_t s_len, size_t d_len, * Compress and decompress data if necessary. */ extern size_t zio_compress_data(enum zio_compress c, abd_t *src, void *dst, - size_t s_len); + size_t s_len, uint8_t level); extern int zio_decompress_data(enum zio_compress c, abd_t *src, void *dst, - size_t s_len, size_t d_len); + size_t s_len, size_t d_len, uint8_t *level); extern int zio_decompress_data_buf(enum zio_compress c, void *src, void *dst, - size_t s_len, size_t d_len); + size_t s_len, size_t d_len, uint8_t *level); +extern int zio_compress_to_feature(enum zio_compress comp); #ifdef __cplusplus } diff --git a/include/sys/zio_impl.h b/include/sys/zio_impl.h index 8ca124631..4c9985716 100644 --- a/include/sys/zio_impl.h +++ b/include/sys/zio_impl.h @@ -73,9 +73,9 @@ extern "C" { * the supported transformations: * * Compression: - * ZFS supports three different flavors of compression -- gzip, lzjb, and - * zle. Compression occurs as part of the write pipeline and is performed - * in the ZIO_STAGE_WRITE_BP_INIT stage. + * ZFS supports five different flavors of compression -- gzip, lzjb, lz4, zle, + * and zstd. Compression occurs as part of the write pipeline and is + * performed in the ZIO_STAGE_WRITE_BP_INIT stage. * * Dedup: * Dedup reads are handled by the ZIO_STAGE_DDT_READ_START and diff --git a/include/sys/zstd/Makefile.am b/include/sys/zstd/Makefile.am new file mode 100644 index 000000000..16666fe63 --- /dev/null +++ b/include/sys/zstd/Makefile.am @@ -0,0 +1,18 @@ +COMMON_H = \ + $(top_srcdir)/include/sys/zstd/zstd.h + +KERNEL_H = + +USER_H = + +EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H) + +if CONFIG_USER +libzfsdir = $(includedir)/libzfs/sys/zstd +libzfs_HEADERS = $(COMMON_H) $(USER_H) +endif + +if CONFIG_KERNEL +kerneldir = @prefix@/src/zfs-$(VERSION)/include/sys/zstd +kernel_HEADERS = $(COMMON_H) $(KERNEL_H) +endif diff --git a/include/sys/zstd/zstd.h b/include/sys/zstd/zstd.h new file mode 100644 index 000000000..db1f27716 --- /dev/null +++ b/include/sys/zstd/zstd.h @@ -0,0 +1,98 @@ +/* + * BSD 3-Clause New License (https://spdx.org/licenses/BSD-3-Clause.html) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2016-2018, Klara Inc. + * Copyright (c) 2016-2018, Allan Jude + * Copyright (c) 2018-2020, Sebastian Gottschall + * Copyright (c) 2019-2020, Michael Niewöhner + * Copyright (c) 2020, The FreeBSD Foundation [1] + * + * [1] Portions of this software were developed by Allan Jude + * under sponsorship from the FreeBSD Foundation. + */ + +#ifndef _ZFS_ZSTD_H +#define _ZFS_ZSTD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * ZSTD block header + * NOTE: all fields in this header are in big endian order. + */ +typedef struct zfs_zstd_header { + /* Compressed size of data */ + uint32_t c_len; + + /* + * Version and compression level + * We use a union to be able to big endian encode a single 32 bit + * unsigned integer, but still access the individual bitmasked + * components easily. + */ + union { + uint32_t raw_version_level; + struct { + uint32_t version : 24; + uint8_t level; + }; + }; + + char data[]; +} zfs_zstdhdr_t; + +/* + * kstat helper macros + */ +#define ZSTDSTAT(stat) (zstd_stats.stat.value.ui64) +#define ZSTDSTAT_INCR(stat, val) \ + atomic_add_64(&zstd_stats.stat.value.ui64, (val)) +#define ZSTDSTAT_BUMP(stat) ZSTDSTAT_INCR(stat, 1) + +/* (de)init for user space / kernel emulation */ +int zstd_init(void); +void zstd_fini(void); + +size_t zstd_compress(void *s_start, void *d_start, size_t s_len, size_t d_len, + int level); +int zstd_get_level(void *s_start, size_t s_len, uint8_t *level); +int zstd_decompress_level(void *s_start, void *d_start, size_t s_len, + size_t d_len, uint8_t *level); +int zstd_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, + int n); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZFS_ZSTD_H */ |