aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/module/zfs/zio_compress.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/openzfs/module/zfs/zio_compress.c')
-rw-r--r--sys/contrib/openzfs/module/zfs/zio_compress.c130
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