Changeset View
Changeset View
Standalone View
Standalone View
sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_compress.c
Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
#define ZCOMPSTAT_BUMP(stat) ZCOMPSTAT_INCR(stat, 1); | #define ZCOMPSTAT_BUMP(stat) ZCOMPSTAT_INCR(stat, 1); | ||||
kstat_t *zcomp_ksp; | kstat_t *zcomp_ksp; | ||||
/* | /* | ||||
* Compression vectors. | * Compression vectors. | ||||
*/ | */ | ||||
zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = { | zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = { | ||||
{"inherit", 0, NULL, NULL}, | {"inherit", 0, NULL, NULL, NULL}, | ||||
{"on", 0, NULL, NULL}, | {"on", 0, NULL, NULL, NULL}, | ||||
{"uncompressed", 0, NULL, NULL}, | {"uncompressed", 0, NULL, NULL, NULL}, | ||||
{"lzjb", 0, lzjb_compress, lzjb_decompress}, | {"lzjb", 0, lzjb_compress, lzjb_decompress, NULL}, | ||||
{"empty", 0, NULL, NULL}, | {"empty", 0, NULL, NULL, NULL}, | ||||
{"gzip-1", 1, gzip_compress, gzip_decompress}, | {"gzip-1", 1, gzip_compress, gzip_decompress, NULL}, | ||||
{"gzip-2", 2, gzip_compress, gzip_decompress}, | {"gzip-2", 2, gzip_compress, gzip_decompress, NULL}, | ||||
{"gzip-3", 3, gzip_compress, gzip_decompress}, | {"gzip-3", 3, gzip_compress, gzip_decompress, NULL}, | ||||
{"gzip-4", 4, gzip_compress, gzip_decompress}, | {"gzip-4", 4, gzip_compress, gzip_decompress, NULL}, | ||||
{"gzip-5", 5, gzip_compress, gzip_decompress}, | {"gzip-5", 5, gzip_compress, gzip_decompress, NULL}, | ||||
{"gzip-6", 6, gzip_compress, gzip_decompress}, | {"gzip-6", 6, gzip_compress, gzip_decompress, NULL}, | ||||
{"gzip-7", 7, gzip_compress, gzip_decompress}, | {"gzip-7", 7, gzip_compress, gzip_decompress, NULL}, | ||||
{"gzip-8", 8, gzip_compress, gzip_decompress}, | {"gzip-8", 8, gzip_compress, gzip_decompress, NULL}, | ||||
{"gzip-9", 9, gzip_compress, gzip_decompress}, | {"gzip-9", 9, gzip_compress, gzip_decompress, NULL}, | ||||
{"zle", 64, zle_compress, zle_decompress}, | {"zle", 64, zle_compress, zle_decompress, NULL}, | ||||
{"lz4", 0, lz4_compress, lz4_decompress} | {"lz4", 0, lz4_compress, lz4_decompress, NULL}, | ||||
{"zstd", 0, zstd_compress, zstd_decompress, zstd_getlevel}, | |||||
}; | }; | ||||
enum zio_zstd_levels | |||||
zio_zstd_level_select(spa_t *spa, enum zio_zstd_levels child, | |||||
enum zio_zstd_levels parent) | |||||
{ | |||||
enum zio_zstd_levels result; | |||||
ASSERT(child < ZIO_ZSTDLVL_LEVELS); | |||||
ASSERT(parent < ZIO_ZSTDLVL_LEVELS); | |||||
ASSERT(parent != ZIO_ZSTDLVL_INHERIT); | |||||
result = child; | |||||
if (result == ZIO_ZSTDLVL_INHERIT) | |||||
result = parent; | |||||
return (result); | |||||
} | |||||
enum zio_compress | enum zio_compress | ||||
zio_compress_select(spa_t *spa, enum zio_compress child, | zio_compress_select(spa_t *spa, enum zio_compress child, | ||||
enum zio_compress parent) | enum zio_compress parent) | ||||
{ | { | ||||
enum zio_compress result; | enum zio_compress result; | ||||
ASSERT(child < ZIO_COMPRESS_FUNCTIONS); | ASSERT(child < ZIO_COMPRESS_FUNCTIONS); | ||||
ASSERT(parent < ZIO_COMPRESS_FUNCTIONS); | ASSERT(parent < ZIO_COMPRESS_FUNCTIONS); | ||||
Show All 21 Lines | zio_compress_zeroed_cb(void *data, size_t len, void *private) | ||||
for (uint64_t *word = (uint64_t *)data; word < end; word++) | for (uint64_t *word = (uint64_t *)data; word < end; word++) | ||||
if (*word != 0) | if (*word != 0) | ||||
return (1); | return (1); | ||||
return (0); | return (0); | ||||
} | } | ||||
size_t | size_t | ||||
zio_compress_data(enum zio_compress c, abd_t *src, void *dst, size_t s_len) | zio_compress_data(enum zio_compress c, abd_t *src, void *dst, size_t s_len, | ||||
zio_prop_t *zp) | |||||
{ | { | ||||
size_t c_len, d_len; | size_t c_len, d_len; | ||||
int level; | |||||
zio_compress_info_t *ci = &zio_compress_table[c]; | zio_compress_info_t *ci = &zio_compress_table[c]; | ||||
ASSERT((uint_t)c < ZIO_COMPRESS_FUNCTIONS); | ASSERT((uint_t)c < ZIO_COMPRESS_FUNCTIONS); | ||||
ASSERT((uint_t)c == ZIO_COMPRESS_EMPTY || ci->ci_compress != NULL); | ASSERT((uint_t)c == ZIO_COMPRESS_EMPTY || ci->ci_compress != NULL); | ||||
ZCOMPSTAT_BUMP(zcompstat_attempts); | ZCOMPSTAT_BUMP(zcompstat_attempts); | ||||
/* | /* | ||||
* If the data is all zeroes, we don't even need to allocate | * If the data is all zeroes, we don't even need to allocate | ||||
* a block for it. We indicate this by returning zero size. | * a block for it. We indicate this by returning zero size. | ||||
*/ | */ | ||||
if (abd_iterate_func(src, 0, s_len, zio_compress_zeroed_cb, NULL) == 0) { | if (abd_iterate_func(src, 0, s_len, zio_compress_zeroed_cb, NULL) == 0) { | ||||
ZCOMPSTAT_BUMP(zcompstat_empty); | ZCOMPSTAT_BUMP(zcompstat_empty); | ||||
return (0); | return (0); | ||||
} | } | ||||
if (c == ZIO_COMPRESS_EMPTY) | if (c == ZIO_COMPRESS_EMPTY) | ||||
return (s_len); | return (s_len); | ||||
/* Compress at least 12.5% */ | /* Compress at least 12.5% */ | ||||
d_len = s_len - (s_len >> 3); | d_len = s_len - (s_len >> 3); | ||||
level = ci->ci_level; | |||||
if (c == ZIO_COMPRESS_ZSTD) { | |||||
ASSERT(zp != NULL); | |||||
if (zp->zp_zstd_level == ZIO_ZSTDLVL_DEFAULT) | |||||
level = ZIO_ZSTD_LEVEL_DEFAULT; | |||||
else | |||||
level = zp->zp_zstd_level; | |||||
} | |||||
/* No compression algorithms can read from ABDs directly */ | /* No compression algorithms can read from ABDs directly */ | ||||
void *tmp = abd_borrow_buf_copy(src, s_len); | void *tmp = abd_borrow_buf_copy(src, s_len); | ||||
c_len = ci->ci_compress(tmp, dst, s_len, d_len, ci->ci_level); | c_len = ci->ci_compress(tmp, dst, s_len, d_len, level); | ||||
abd_return_buf(src, tmp, s_len); | abd_return_buf(src, tmp, s_len); | ||||
if (c_len > d_len) { | if (c_len > d_len) { | ||||
ZCOMPSTAT_BUMP(zcompstat_skipped_insufficient_gain); | ZCOMPSTAT_BUMP(zcompstat_skipped_insufficient_gain); | ||||
return (s_len); | return (s_len); | ||||
} | } | ||||
ASSERT3U(c_len, <=, d_len); | ASSERT3U(c_len, <=, d_len); | ||||
Show All 15 Lines | |||||
zio_decompress_data(enum zio_compress c, abd_t *src, void *dst, | 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) | ||||
{ | { | ||||
void *tmp = abd_borrow_buf_copy(src, s_len); | void *tmp = abd_borrow_buf_copy(src, s_len); | ||||
int ret = zio_decompress_data_buf(c, tmp, dst, s_len, d_len); | int ret = zio_decompress_data_buf(c, tmp, dst, s_len, d_len); | ||||
abd_return_buf(src, tmp, s_len); | abd_return_buf(src, tmp, s_len); | ||||
return (ret); | return (ret); | ||||
} | |||||
int | |||||
zio_getcomplevel(enum zio_compress c, abd_t *src, size_t s_len) | |||||
{ | |||||
void *tmp = abd_borrow_buf_copy(src, s_len); | |||||
zio_compress_info_t *ci = &zio_compress_table[c]; | |||||
int ret; | |||||
if ((uint_t)c >= ZIO_COMPRESS_FUNCTIONS || ci->ci_getlevel == NULL) | |||||
return (-1); | |||||
ret = ci->ci_getlevel(tmp, s_len); | |||||
abd_return_buf(src, tmp, s_len); | |||||
return (ret); | |||||
} | |||||
int | |||||
zio_decompress_getlevel(enum zio_compress c, abd_t *src, void *dst, | |||||
size_t s_len, size_t d_len, enum zio_zstd_levels *level) | |||||
{ | |||||
void *tmp = abd_borrow_buf_copy(src, s_len); | |||||
int ret = zio_decompress_data_buf(c, tmp, dst, s_len, d_len); | |||||
zio_compress_info_t *ci = &zio_compress_table[c]; | |||||
if ((uint_t)c >= ZIO_COMPRESS_FUNCTIONS || ci->ci_getlevel == NULL) | |||||
return (-1); | |||||
*level = ci->ci_getlevel(tmp, s_len); | |||||
abd_return_buf(src, tmp, s_len); | |||||
return (ret); | |||||
} | |||||
int | |||||
zio_compress_to_feature(enum zio_compress comp) | |||||
{ | |||||
switch (comp) { | |||||
case ZIO_COMPRESS_ZSTD: | |||||
return (SPA_FEATURE_ZSTD_COMPRESS); | |||||
} | |||||
return (SPA_FEATURE_NONE); | |||||
} | } | ||||
void | void | ||||
zio_compress_init(void) | zio_compress_init(void) | ||||
{ | { | ||||
zcomp_ksp = kstat_create("zfs", 0, "zcompstats", "misc", | zcomp_ksp = kstat_create("zfs", 0, "zcompstats", "misc", | ||||
KSTAT_TYPE_NAMED, sizeof (zcomp_stats) / sizeof (kstat_named_t), | KSTAT_TYPE_NAMED, sizeof (zcomp_stats) / sizeof (kstat_named_t), | ||||
Show All 16 Lines |