Skip to content
Permalink
Browse files

Add ZStandard compression support

Signed-off-by: Allan Jude <allanjude@freebsd.org>
  • Loading branch information...
allanjude committed Jul 12, 2019
1 parent ec7b6ce commit 74b1fedd7c48b6869a008820b2cb94aacafc702f
@@ -87,7 +87,8 @@ commitcheck:
fi

cstyle:
@find ${top_srcdir} -name '*.[hc]' ! -name 'zfs_config.*' \
@find ${top_srcdir} -path ./contrib/zstd -prune -o \
-name '*.[hc]' ! -name 'zfs_config.*' \
! -name '*.mod.c' -type f \
-exec ${top_srcdir}/scripts/cstyle.pl -cpP {} \+

@@ -343,7 +343,7 @@ def get_compstring(c):
"ZIO_COMPRESS_GZIP_6", "ZIO_COMPRESS_GZIP_7",
"ZIO_COMPRESS_GZIP_8", "ZIO_COMPRESS_GZIP_9",
"ZIO_COMPRESS_ZLE", "ZIO_COMPRESS_LZ4",
"ZIO_COMPRESS_FUNCTION"]
"ZIO_COMPRESS_ZSTD", "ZIO_COMPRESS_FUNCTION"]

# If "-rr" option is used, don't convert to string representation
if raw > 1:
@@ -143,6 +143,7 @@ AC_CONFIG_FILES([
module/lua/Makefile
module/icp/Makefile
module/spl/Makefile
module/zstd_zfs/Makefile
include/Makefile
include/linux/Makefile
include/spl/Makefile
@@ -186,6 +186,7 @@ typedef enum {
ZFS_PROP_IVSET_GUID, /* not exposed to the user */
ZFS_PROP_REDACTED,
ZFS_PROP_REDACT_SNAPS,
ZFS_PROP_COMPRESS_LEVEL, /* not exposed to the user */
ZFS_NUM_PROPS
} zfs_prop_t;

@@ -393,6 +393,8 @@ void procfs_list_add(procfs_list_t *procfs_list, void *p);
#define KM_SLEEP UMEM_NOFAIL
#define KM_PUSHPAGE KM_SLEEP
#define KM_NOSLEEP UMEM_DEFAULT
/* supposed to zero the allocation, ignore for userspace */
#define KM_ZERO 0
#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */
#define KMC_NODEBUG UMC_NODEBUG
#define KMC_KMEM 0x0
@@ -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)

/*
@@ -117,7 +117,7 @@ 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_REDACTED | DMU_BACKUP_FEATURE_ZSTD)

/* Are all features in the given flag word currently supported? */
#define DMU_STREAM_SUPPORTED(x) (!((x) & ~DMU_BACKUP_FEATURE_MASK))
@@ -154,6 +154,7 @@ 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)

@@ -51,12 +51,70 @@ enum zio_compress {
ZIO_COMPRESS_GZIP_9,
ZIO_COMPRESS_ZLE,
ZIO_COMPRESS_LZ4,
ZIO_COMPRESS_ZSTD,
ZIO_COMPRESS_FUNCTIONS
};

#define ZIO_COMPLEVEL_INHERIT 0
#define ZIO_COMPLEVEL_DEFAULT 255

enum zio_zstd_levels {
ZIO_ZSTDLVL_INHERIT = 0,
ZIO_ZSTDLVL_1,
#define ZIO_ZSTD_LEVEL_MIN ZIO_ZSTDLVL_1
ZIO_ZSTDLVL_2,
ZIO_ZSTDLVL_3,
#define ZIO_ZSTD_LEVEL_DEFAULT ZIO_ZSTDLVL_3
ZIO_ZSTDLVL_4,
ZIO_ZSTDLVL_5,
ZIO_ZSTDLVL_6,
ZIO_ZSTDLVL_7,
ZIO_ZSTDLVL_8,
ZIO_ZSTDLVL_9,
ZIO_ZSTDLVL_10,
ZIO_ZSTDLVL_11,
ZIO_ZSTDLVL_12,
ZIO_ZSTDLVL_13,
ZIO_ZSTDLVL_14,
ZIO_ZSTDLVL_15,
ZIO_ZSTDLVL_16,
ZIO_ZSTDLVL_17,
ZIO_ZSTDLVL_18,
ZIO_ZSTDLVL_19,
#define ZIO_ZSTD_LEVEL_MAX ZIO_ZSTDLVL_19
#define ZIO_ZSTDLVL_MAX ZIO_ZSTDLVL_19
ZIO_ZSTDLVL_RESERVE = 101, /* Leave room for new positive levels */
ZIO_ZSTDLVL_FAST, /* Fast levels are negative */
ZIO_ZSTDLVL_FAST_1,
ZIO_ZSTDLVL_FAST_2,
ZIO_ZSTDLVL_FAST_3,
ZIO_ZSTDLVL_FAST_4,
ZIO_ZSTDLVL_FAST_5,
ZIO_ZSTDLVL_FAST_6,
ZIO_ZSTDLVL_FAST_7,
ZIO_ZSTDLVL_FAST_8,
ZIO_ZSTDLVL_FAST_9,
ZIO_ZSTDLVL_FAST_10,
ZIO_ZSTDLVL_FAST_20,
ZIO_ZSTDLVL_FAST_30,
ZIO_ZSTDLVL_FAST_40,
ZIO_ZSTDLVL_FAST_50,
ZIO_ZSTDLVL_FAST_60,
ZIO_ZSTDLVL_FAST_70,
ZIO_ZSTDLVL_FAST_80,
ZIO_ZSTDLVL_FAST_90,
ZIO_ZSTDLVL_FAST_100,
ZIO_ZSTDLVL_FAST_500,
ZIO_ZSTDLVL_FAST_1000,
#define ZIO_ZSTDLVL_FAST_MAX ZIO_ZSTDLVL_FAST_1000
ZIO_ZSTDLVL_DEFAULT = 250, /* Allow the default level to change */
ZIO_ZSTDLVL_AUTO = 251, /* Reserved for future use */
ZIO_ZSTDLVL_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);
@@ -117,6 +175,14 @@ extern size_t lz4_compress_zfs(void *src, void *dst, size_t s_len, size_t d_len,
extern int lz4_decompress_zfs(void *src, void *dst, size_t s_len, size_t d_len,
int level);

extern size_t zstd_compress(void *src, void *dst, size_t s_len, size_t d_len,
int level);
extern int zstd_decompress(void *src, void *dst, size_t s_len, size_t d_len,
int level);
extern int zstd_decompress_level(void *src, void *dst, size_t s_len,
size_t d_len, uint8_t *level);
extern int zstd_get_level(void *src, size_t s_len, uint8_t *level);

/*
* Compress and decompress data if necessary.
*/
@@ -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
@@ -70,6 +70,7 @@ typedef enum spa_feature {
SPA_FEATURE_REDACTION_BOOKMARKS,
SPA_FEATURE_REDACTED_DATASETS,
SPA_FEATURE_BOOKMARK_WRITTEN,
SPA_FEATURE_ZSTD_COMPRESS,
SPA_FEATURES
} spa_feature_t;

@@ -4,6 +4,10 @@ VPATH = \
$(top_srcdir)/module/zfs \
$(top_srcdir)/module/zcommon \
$(top_srcdir)/module/lua \
$(top_srcdir)/contrib/zstd/zstd-1.4.0/lib/common \
$(top_srcdir)/contrib/zstd/zstd-1.4.0/lib/compress \
$(top_srcdir)/contrib/zstd/zstd-1.4.0/lib/decompress \
$(top_srcdir)/module/zstd_zfs \
$(top_srcdir)/lib/libzpool

# Suppress unused but set variable warnings often due to ASSERTs
@@ -12,11 +16,15 @@ AM_CFLAGS += $(NO_UNUSED_BUT_SET_VARIABLE)
# Includes kernel code generate warnings for large stack frames
AM_CFLAGS += $(FRAME_LARGER_THAN)

AM_CFLAGS += -DLIB_ZPOOL_BUILD
AM_CFLAGS += -DLIB_ZPOOL_BUILD -Wframe-larger-than=20480

DEFAULT_INCLUDES += \
-I$(top_srcdir)/include \
-I$(top_srcdir)/lib/libspl/include
-I$(top_srcdir)/lib/libspl/include \
-I$(top_srcdir)/contrib/zstd/zstd-1.4.0/lib \
-I$(top_srcdir)/contrib/zstd/zstd-1.4.0/lib/common \
-I$(top_srcdir)/contrib/zstd/zstd-1.4.0/lib/compress \
-I$(top_srcdir)/contrib/zstd/zstd-1.4.0/lib/decompress

lib_LTLIBRARIES = libzpool.la

@@ -160,6 +168,27 @@ KERNEL_C = \
zrlock.c \
zthr.c

ZSTD_C = \
zstd_common.c \
fse_decompress.c \
entropy_common.c \
xxhash.c \
error_private.c \
zstd_compress.c \
fse_compress.c \
hist.c \
huf_compress.c \
zstd_double_fast.c \
zstd_fast.c \
zstd_lazy.c \
zstd_ldm.c \
zstd_opt.c \
zstd_ddict.c \
zstd_decompress.c \
zstd_decompress_block.c \
huf_decompress.c \
zstd.c

LUA_C = \
lapi.c \
lauxlib.c \
@@ -189,7 +218,8 @@ LUA_C = \
nodist_libzpool_la_SOURCES = \
$(USER_C) \
$(KERNEL_C) \
$(LUA_C)
$(LUA_C) \
$(ZSTD_C)

libzpool_la_LIBADD = \
$(top_builddir)/lib/libicp/libicp.la \
@@ -884,5 +884,37 @@ The feature will only return back to being \fBenabled\fR when the pool
is rewound or the checkpoint has been discarded.
.RE

.sp
.ne 2
.na
\fBzstd_compress\fR
.ad
.RS 4n
.TS
l l .
GUID org.freebsd:zstd_compress
READ\-ONLY COMPATIBLE no
DEPENDENCIES none
.TE

\fBzstd\fR is a high-performance compression algorithm that features a
combination of high compression ratios and high speed.
Compared to \fBgzip\fR, \fBzstd\fR offers slighty better compression at much
higher speeds.
Compared to \fBlz4\fR, \fBzstd\fR offers much better compression while being
only modestly slower.
Typically, \fBzstd\fR compression speed ranges from 250 - 500
megabytes/second/thread, and decompression speed is over 1
gigabyte/second/thread.
Booting off of \fBzstd\fR-compressed root pools is not yet supported.

When the \fBzstd\fR feature is set to \fBenabled\fR, the administrator can turn
on \fBzstd\fR compression of any dataset by running
`zfs set compress=zstd <pool/fs>`.
This feature becomes \fBactive\fR once a \fBcompress\fR property has been set to
\fBzstd\fR, and will return to being \fBenabled\fR once all filesystems that
have ever had their compress property set to \fBzstd\fR are destroyed.
.RE

.SH "SEE ALSO"
zpool(8)
@@ -1219,7 +1219,8 @@ for more information on these algorithms.
Changing this property affects only newly-written data.
.It Xo
.Sy compression Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Sy gzip Ns | Ns
.Sy gzip- Ns Em N Ns | Ns Sy lz4 Ns | Ns Sy lzjb Ns | Ns Sy zle
.Sy gzip- Ns Em N Ns | Ns Sy lz4 Ns | Ns Sy lzjb Ns | Ns Sy zle Ns | Ns
.Sy zstd Ns | Ns Sy zstd- Ns Em N Ns | Ns Sy zstd-fast- Ns Em N Ns
.Xc
Controls the compression algorithm used for this dataset.
.Pp
@@ -6,6 +6,7 @@ subdir-m += spl
subdir-m += unicode
subdir-m += zcommon
subdir-m += zfs
subdir-m += zstd_zfs

INSTALL_MOD_DIR ?= extra

@@ -14,6 +15,11 @@ ZFS_MODULE_CFLAGS += @KERNEL_DEBUG_CFLAGS@
ZFS_MODULE_CFLAGS += -include @abs_top_builddir@/zfs_config.h
ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/include/spl
ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/include
ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/contrib/zstd/zstd-1.4.0/lib
ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/contrib/zstd/zstd-1.4.0/lib/common
ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/contrib/zstd/zstd-1.4.0/lib/compress
ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/contrib/zstd/zstd-1.4.0/lib/decompress
ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/module/zstd_zfs/include

ZFS_MODULE_CPPFLAGS += -D_KERNEL
ZFS_MODULE_CPPFLAGS += @KERNEL_DEBUG_CPPFLAGS@
@@ -23,7 +29,7 @@ ZFS_MODULE_CPPFLAGS += @KERNEL_DEBUG_CPPFLAGS@

export ZFS_MODULE_CFLAGS ZFS_MODULE_CPPFLAGS

SUBDIR_TARGETS = icp lua
SUBDIR_TARGETS = icp lua zstd_zfs

modules:
list='$(SUBDIR_TARGETS)'; for targetdir in $$list; do \
@@ -528,6 +528,17 @@ zpool_feature_init(void)
"com.datto:resilver_defer", "resilver_defer",
"Support for defering new resilvers when one is already running.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL);

{
static const spa_feature_t zstd_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_ZSTD_COMPRESS,
"org.freebsd:zstd_compress", "zstd_compress",
"zstd compression algorithm support.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN, zstd_deps);
}
}

#if defined(_KERNEL)

0 comments on commit 74b1fed

Please sign in to comment.
You can’t perform that action at this time.