diff options
Diffstat (limited to 'sys/contrib/openzfs/module/zfs/zio_compress.c')
-rw-r--r-- | sys/contrib/openzfs/module/zfs/zio_compress.c | 130 |
1 files changed, 52 insertions, 78 deletions
diff --git a/sys/contrib/openzfs/module/zfs/zio_compress.c b/sys/contrib/openzfs/module/zfs/zio_compress.c index 717395dcf456..9f0ac1b63146 100644 --- a/sys/contrib/openzfs/module/zfs/zio_compress.c +++ b/sys/contrib/openzfs/module/zfs/zio_compress.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: CDDL-1.0 /* * CDDL HEADER START * @@ -6,7 +7,7 @@ * 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. + * or https://opensource.org/licenses/CDDL-1.0. * See the License for the specific language governing permissions * and limitations under the License. * @@ -22,15 +23,11 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - */ -/* * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. - */ - -/* * Copyright (c) 2013, 2018 by Delphix. All rights reserved. - * Copyright (c) 2019, Klara Inc. + * Copyright (c) 2019, 2024, Klara, Inc. * Copyright (c) 2019, Allan Jude + * Copyright (c) 2021, 2024 by George Melikov. All rights reserved. */ #include <sys/zfs_context.h> @@ -44,30 +41,42 @@ * If nonzero, every 1/X decompression attempts will fail, simulating * an undetected memory error. */ -unsigned long zio_decompress_fail_fraction = 0; +static unsigned long zio_decompress_fail_fraction = 0; /* * Compression vectors. */ -const zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = { - {"inherit", 0, NULL, NULL, NULL}, - {"on", 0, NULL, NULL, NULL}, - {"uncompressed", 0, NULL, NULL, NULL}, - {"lzjb", 0, lzjb_compress, lzjb_decompress, NULL}, - {"empty", 0, NULL, NULL, NULL}, - {"gzip-1", 1, gzip_compress, gzip_decompress, NULL}, - {"gzip-2", 2, gzip_compress, gzip_decompress, NULL}, - {"gzip-3", 3, gzip_compress, gzip_decompress, NULL}, - {"gzip-4", 4, gzip_compress, gzip_decompress, NULL}, - {"gzip-5", 5, gzip_compress, gzip_decompress, NULL}, - {"gzip-6", 6, gzip_compress, gzip_decompress, NULL}, - {"gzip-7", 7, gzip_compress, gzip_decompress, NULL}, - {"gzip-8", 8, gzip_compress, gzip_decompress, NULL}, - {"gzip-9", 9, gzip_compress, gzip_decompress, NULL}, - {"zle", 64, zle_compress, zle_decompress, NULL}, - {"lz4", 0, lz4_compress_zfs, lz4_decompress_zfs, NULL}, - {"zstd", ZIO_ZSTD_LEVEL_DEFAULT, zfs_zstd_compress_wrap, - zfs_zstd_decompress, zfs_zstd_decompress_level}, +zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = { + {"inherit", 0, NULL, NULL, NULL}, + {"on", 0, NULL, NULL, NULL}, + {"uncompressed", 0, NULL, NULL, NULL}, + {"lzjb", 0, + zfs_lzjb_compress, zfs_lzjb_decompress, NULL}, + {"empty", 0, NULL, NULL, NULL}, + {"gzip-1", 1, + zfs_gzip_compress, zfs_gzip_decompress, NULL}, + {"gzip-2", 2, + zfs_gzip_compress, zfs_gzip_decompress, NULL}, + {"gzip-3", 3, + zfs_gzip_compress, zfs_gzip_decompress, NULL}, + {"gzip-4", 4, + zfs_gzip_compress, zfs_gzip_decompress, NULL}, + {"gzip-5", 5, + zfs_gzip_compress, zfs_gzip_decompress, NULL}, + {"gzip-6", 6, + zfs_gzip_compress, zfs_gzip_decompress, NULL}, + {"gzip-7", 7, + zfs_gzip_compress, zfs_gzip_decompress, NULL}, + {"gzip-8", 8, + zfs_gzip_compress, zfs_gzip_decompress, NULL}, + {"gzip-9", 9, + zfs_gzip_compress, zfs_gzip_decompress, NULL}, + {"zle", 64, + zfs_zle_compress, zfs_zle_decompress, NULL}, + {"lz4", 0, + zfs_lz4_compress, zfs_lz4_decompress, NULL}, + {"zstd", ZIO_ZSTD_LEVEL_DEFAULT, + zfs_zstd_compress, zfs_zstd_decompress, zfs_zstd_decompress_level}, }; uint8_t @@ -111,42 +120,16 @@ zio_compress_select(spa_t *spa, enum zio_compress child, return (result); } -static int -zio_compress_zeroed_cb(void *data, size_t len, void *private) -{ - (void) private; - - uint64_t *end = (uint64_t *)((char *)data + len); - for (uint64_t *word = (uint64_t *)data; word < end; word++) - if (*word != 0) - return (1); - - return (0); -} - size_t -zio_compress_data(enum zio_compress c, abd_t *src, void *dst, size_t s_len, - uint8_t level) +zio_compress_data(enum zio_compress c, abd_t *src, abd_t **dst, size_t s_len, + size_t d_len, uint8_t level) { - size_t c_len, d_len; + size_t c_len; uint8_t complevel; zio_compress_info_t *ci = &zio_compress_table[c]; - ASSERT((uint_t)c < ZIO_COMPRESS_FUNCTIONS); - ASSERT((uint_t)c == ZIO_COMPRESS_EMPTY || ci->ci_compress != NULL); - - /* - * If the data is all zeroes, we don't even need to allocate - * 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) - return (0); - - if (c == ZIO_COMPRESS_EMPTY) - return (s_len); - - /* Compress at least 12.5% */ - d_len = s_len - (s_len >> 3); + ASSERT3U(ci->ci_compress, !=, NULL); + ASSERT3U(s_len, >, 0); complevel = ci->ci_level; @@ -163,39 +146,30 @@ zio_compress_data(enum zio_compress c, abd_t *src, void *dst, size_t s_len, ASSERT3U(complevel, !=, ZIO_COMPLEVEL_INHERIT); } - /* No compression algorithms can read from ABDs directly */ - void *tmp = abd_borrow_buf_copy(src, s_len); - c_len = ci->ci_compress(tmp, dst, s_len, d_len, complevel); - abd_return_buf(src, tmp, s_len); + if (*dst == NULL) + *dst = abd_alloc_sametype(src, s_len); + + c_len = ci->ci_compress(src, *dst, s_len, d_len, complevel); if (c_len > d_len) return (s_len); - ASSERT3U(c_len, <=, d_len); return (c_len); } int -zio_decompress_data_buf(enum zio_compress c, void *src, void *dst, +zio_decompress_data(enum zio_compress c, abd_t *src, abd_t *dst, size_t s_len, size_t d_len, uint8_t *level) { zio_compress_info_t *ci = &zio_compress_table[c]; if ((uint_t)c >= ZIO_COMPRESS_FUNCTIONS || ci->ci_decompress == NULL) return (SET_ERROR(EINVAL)); + int err; if (ci->ci_decompress_level != NULL && level != NULL) - return (ci->ci_decompress_level(src, dst, s_len, d_len, level)); - - return (ci->ci_decompress(src, dst, s_len, d_len, ci->ci_level)); -} - -int -zio_decompress_data(enum zio_compress c, abd_t *src, void *dst, - size_t s_len, size_t d_len, uint8_t *level) -{ - void *tmp = abd_borrow_buf_copy(src, s_len); - int ret = zio_decompress_data_buf(c, tmp, dst, s_len, d_len, level); - abd_return_buf(src, tmp, s_len); + err = ci->ci_decompress_level(src, dst, s_len, d_len, level); + else + err = ci->ci_decompress(src, dst, s_len, d_len, ci->ci_level); /* * Decompression shouldn't fail, because we've already verified @@ -204,9 +178,9 @@ zio_decompress_data(enum zio_compress c, abd_t *src, void *dst, */ if (zio_decompress_fail_fraction != 0 && random_in_range(zio_decompress_fail_fraction) == 0) - ret = SET_ERROR(EINVAL); + err = SET_ERROR(EINVAL); - return (ret); + return (err); } int |