1*eda14cbcSMatt Macy /* 2*eda14cbcSMatt Macy * CDDL HEADER START 3*eda14cbcSMatt Macy * 4*eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 5*eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 6*eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 7*eda14cbcSMatt Macy * 8*eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*eda14cbcSMatt Macy * or http://www.opensolaris.org/os/licensing. 10*eda14cbcSMatt Macy * See the License for the specific language governing permissions 11*eda14cbcSMatt Macy * and limitations under the License. 12*eda14cbcSMatt Macy * 13*eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 14*eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 16*eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 17*eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 18*eda14cbcSMatt Macy * 19*eda14cbcSMatt Macy * CDDL HEADER END 20*eda14cbcSMatt Macy */ 21*eda14cbcSMatt Macy 22*eda14cbcSMatt Macy /* 23*eda14cbcSMatt Macy * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*eda14cbcSMatt Macy * Use is subject to license terms. 25*eda14cbcSMatt Macy */ 26*eda14cbcSMatt Macy /* 27*eda14cbcSMatt Macy * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. 28*eda14cbcSMatt Macy */ 29*eda14cbcSMatt Macy 30*eda14cbcSMatt Macy /* 31*eda14cbcSMatt Macy * Copyright (c) 2013, 2018 by Delphix. All rights reserved. 32*eda14cbcSMatt Macy * Copyright (c) 2019, Klara Inc. 33*eda14cbcSMatt Macy * Copyright (c) 2019, Allan Jude 34*eda14cbcSMatt Macy */ 35*eda14cbcSMatt Macy 36*eda14cbcSMatt Macy #include <sys/zfs_context.h> 37*eda14cbcSMatt Macy #include <sys/spa.h> 38*eda14cbcSMatt Macy #include <sys/zfeature.h> 39*eda14cbcSMatt Macy #include <sys/zio.h> 40*eda14cbcSMatt Macy #include <sys/zio_compress.h> 41*eda14cbcSMatt Macy #include <sys/zstd/zstd.h> 42*eda14cbcSMatt Macy 43*eda14cbcSMatt Macy /* 44*eda14cbcSMatt Macy * If nonzero, every 1/X decompression attempts will fail, simulating 45*eda14cbcSMatt Macy * an undetected memory error. 46*eda14cbcSMatt Macy */ 47*eda14cbcSMatt Macy unsigned long zio_decompress_fail_fraction = 0; 48*eda14cbcSMatt Macy 49*eda14cbcSMatt Macy /* 50*eda14cbcSMatt Macy * Compression vectors. 51*eda14cbcSMatt Macy */ 52*eda14cbcSMatt Macy zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = { 53*eda14cbcSMatt Macy {"inherit", 0, NULL, NULL, NULL}, 54*eda14cbcSMatt Macy {"on", 0, NULL, NULL, NULL}, 55*eda14cbcSMatt Macy {"uncompressed", 0, NULL, NULL, NULL}, 56*eda14cbcSMatt Macy {"lzjb", 0, lzjb_compress, lzjb_decompress, NULL}, 57*eda14cbcSMatt Macy {"empty", 0, NULL, NULL, NULL}, 58*eda14cbcSMatt Macy {"gzip-1", 1, gzip_compress, gzip_decompress, NULL}, 59*eda14cbcSMatt Macy {"gzip-2", 2, gzip_compress, gzip_decompress, NULL}, 60*eda14cbcSMatt Macy {"gzip-3", 3, gzip_compress, gzip_decompress, NULL}, 61*eda14cbcSMatt Macy {"gzip-4", 4, gzip_compress, gzip_decompress, NULL}, 62*eda14cbcSMatt Macy {"gzip-5", 5, gzip_compress, gzip_decompress, NULL}, 63*eda14cbcSMatt Macy {"gzip-6", 6, gzip_compress, gzip_decompress, NULL}, 64*eda14cbcSMatt Macy {"gzip-7", 7, gzip_compress, gzip_decompress, NULL}, 65*eda14cbcSMatt Macy {"gzip-8", 8, gzip_compress, gzip_decompress, NULL}, 66*eda14cbcSMatt Macy {"gzip-9", 9, gzip_compress, gzip_decompress, NULL}, 67*eda14cbcSMatt Macy {"zle", 64, zle_compress, zle_decompress, NULL}, 68*eda14cbcSMatt Macy {"lz4", 0, lz4_compress_zfs, lz4_decompress_zfs, NULL}, 69*eda14cbcSMatt Macy {"zstd", ZIO_ZSTD_LEVEL_DEFAULT, zfs_zstd_compress, 70*eda14cbcSMatt Macy zfs_zstd_decompress, zfs_zstd_decompress_level}, 71*eda14cbcSMatt Macy }; 72*eda14cbcSMatt Macy 73*eda14cbcSMatt Macy uint8_t 74*eda14cbcSMatt Macy zio_complevel_select(spa_t *spa, enum zio_compress compress, uint8_t child, 75*eda14cbcSMatt Macy uint8_t parent) 76*eda14cbcSMatt Macy { 77*eda14cbcSMatt Macy uint8_t result; 78*eda14cbcSMatt Macy 79*eda14cbcSMatt Macy if (!ZIO_COMPRESS_HASLEVEL(compress)) 80*eda14cbcSMatt Macy return (0); 81*eda14cbcSMatt Macy 82*eda14cbcSMatt Macy result = child; 83*eda14cbcSMatt Macy if (result == ZIO_COMPLEVEL_INHERIT) 84*eda14cbcSMatt Macy result = parent; 85*eda14cbcSMatt Macy 86*eda14cbcSMatt Macy return (result); 87*eda14cbcSMatt Macy } 88*eda14cbcSMatt Macy 89*eda14cbcSMatt Macy enum zio_compress 90*eda14cbcSMatt Macy zio_compress_select(spa_t *spa, enum zio_compress child, 91*eda14cbcSMatt Macy enum zio_compress parent) 92*eda14cbcSMatt Macy { 93*eda14cbcSMatt Macy enum zio_compress result; 94*eda14cbcSMatt Macy 95*eda14cbcSMatt Macy ASSERT(child < ZIO_COMPRESS_FUNCTIONS); 96*eda14cbcSMatt Macy ASSERT(parent < ZIO_COMPRESS_FUNCTIONS); 97*eda14cbcSMatt Macy ASSERT(parent != ZIO_COMPRESS_INHERIT); 98*eda14cbcSMatt Macy 99*eda14cbcSMatt Macy result = child; 100*eda14cbcSMatt Macy if (result == ZIO_COMPRESS_INHERIT) 101*eda14cbcSMatt Macy result = parent; 102*eda14cbcSMatt Macy 103*eda14cbcSMatt Macy if (result == ZIO_COMPRESS_ON) { 104*eda14cbcSMatt Macy if (spa_feature_is_active(spa, SPA_FEATURE_LZ4_COMPRESS)) 105*eda14cbcSMatt Macy result = ZIO_COMPRESS_LZ4_ON_VALUE; 106*eda14cbcSMatt Macy else 107*eda14cbcSMatt Macy result = ZIO_COMPRESS_LEGACY_ON_VALUE; 108*eda14cbcSMatt Macy } 109*eda14cbcSMatt Macy 110*eda14cbcSMatt Macy return (result); 111*eda14cbcSMatt Macy } 112*eda14cbcSMatt Macy 113*eda14cbcSMatt Macy /*ARGSUSED*/ 114*eda14cbcSMatt Macy static int 115*eda14cbcSMatt Macy zio_compress_zeroed_cb(void *data, size_t len, void *private) 116*eda14cbcSMatt Macy { 117*eda14cbcSMatt Macy uint64_t *end = (uint64_t *)((char *)data + len); 118*eda14cbcSMatt Macy for (uint64_t *word = (uint64_t *)data; word < end; word++) 119*eda14cbcSMatt Macy if (*word != 0) 120*eda14cbcSMatt Macy return (1); 121*eda14cbcSMatt Macy 122*eda14cbcSMatt Macy return (0); 123*eda14cbcSMatt Macy } 124*eda14cbcSMatt Macy 125*eda14cbcSMatt Macy size_t 126*eda14cbcSMatt Macy zio_compress_data(enum zio_compress c, abd_t *src, void *dst, size_t s_len, 127*eda14cbcSMatt Macy uint8_t level) 128*eda14cbcSMatt Macy { 129*eda14cbcSMatt Macy size_t c_len, d_len; 130*eda14cbcSMatt Macy uint8_t complevel; 131*eda14cbcSMatt Macy zio_compress_info_t *ci = &zio_compress_table[c]; 132*eda14cbcSMatt Macy 133*eda14cbcSMatt Macy ASSERT((uint_t)c < ZIO_COMPRESS_FUNCTIONS); 134*eda14cbcSMatt Macy ASSERT((uint_t)c == ZIO_COMPRESS_EMPTY || ci->ci_compress != NULL); 135*eda14cbcSMatt Macy 136*eda14cbcSMatt Macy /* 137*eda14cbcSMatt Macy * If the data is all zeroes, we don't even need to allocate 138*eda14cbcSMatt Macy * a block for it. We indicate this by returning zero size. 139*eda14cbcSMatt Macy */ 140*eda14cbcSMatt Macy if (abd_iterate_func(src, 0, s_len, zio_compress_zeroed_cb, NULL) == 0) 141*eda14cbcSMatt Macy return (0); 142*eda14cbcSMatt Macy 143*eda14cbcSMatt Macy if (c == ZIO_COMPRESS_EMPTY) 144*eda14cbcSMatt Macy return (s_len); 145*eda14cbcSMatt Macy 146*eda14cbcSMatt Macy /* Compress at least 12.5% */ 147*eda14cbcSMatt Macy d_len = s_len - (s_len >> 3); 148*eda14cbcSMatt Macy 149*eda14cbcSMatt Macy complevel = ci->ci_level; 150*eda14cbcSMatt Macy 151*eda14cbcSMatt Macy if (c == ZIO_COMPRESS_ZSTD) { 152*eda14cbcSMatt Macy /* If we don't know the level, we can't compress it */ 153*eda14cbcSMatt Macy if (level == ZIO_COMPLEVEL_INHERIT) 154*eda14cbcSMatt Macy return (s_len); 155*eda14cbcSMatt Macy 156*eda14cbcSMatt Macy if (level == ZIO_COMPLEVEL_DEFAULT) 157*eda14cbcSMatt Macy complevel = ZIO_ZSTD_LEVEL_DEFAULT; 158*eda14cbcSMatt Macy else 159*eda14cbcSMatt Macy complevel = level; 160*eda14cbcSMatt Macy 161*eda14cbcSMatt Macy ASSERT3U(complevel, !=, ZIO_COMPLEVEL_INHERIT); 162*eda14cbcSMatt Macy } 163*eda14cbcSMatt Macy 164*eda14cbcSMatt Macy /* No compression algorithms can read from ABDs directly */ 165*eda14cbcSMatt Macy void *tmp = abd_borrow_buf_copy(src, s_len); 166*eda14cbcSMatt Macy c_len = ci->ci_compress(tmp, dst, s_len, d_len, complevel); 167*eda14cbcSMatt Macy abd_return_buf(src, tmp, s_len); 168*eda14cbcSMatt Macy 169*eda14cbcSMatt Macy if (c_len > d_len) 170*eda14cbcSMatt Macy return (s_len); 171*eda14cbcSMatt Macy 172*eda14cbcSMatt Macy ASSERT3U(c_len, <=, d_len); 173*eda14cbcSMatt Macy return (c_len); 174*eda14cbcSMatt Macy } 175*eda14cbcSMatt Macy 176*eda14cbcSMatt Macy int 177*eda14cbcSMatt Macy zio_decompress_data_buf(enum zio_compress c, void *src, void *dst, 178*eda14cbcSMatt Macy size_t s_len, size_t d_len, uint8_t *level) 179*eda14cbcSMatt Macy { 180*eda14cbcSMatt Macy zio_compress_info_t *ci = &zio_compress_table[c]; 181*eda14cbcSMatt Macy if ((uint_t)c >= ZIO_COMPRESS_FUNCTIONS || ci->ci_decompress == NULL) 182*eda14cbcSMatt Macy return (SET_ERROR(EINVAL)); 183*eda14cbcSMatt Macy 184*eda14cbcSMatt Macy if (ci->ci_decompress_level != NULL && level != NULL) 185*eda14cbcSMatt Macy return (ci->ci_decompress_level(src, dst, s_len, d_len, level)); 186*eda14cbcSMatt Macy 187*eda14cbcSMatt Macy return (ci->ci_decompress(src, dst, s_len, d_len, ci->ci_level)); 188*eda14cbcSMatt Macy } 189*eda14cbcSMatt Macy 190*eda14cbcSMatt Macy int 191*eda14cbcSMatt Macy zio_decompress_data(enum zio_compress c, abd_t *src, void *dst, 192*eda14cbcSMatt Macy size_t s_len, size_t d_len, uint8_t *level) 193*eda14cbcSMatt Macy { 194*eda14cbcSMatt Macy void *tmp = abd_borrow_buf_copy(src, s_len); 195*eda14cbcSMatt Macy int ret = zio_decompress_data_buf(c, tmp, dst, s_len, d_len, level); 196*eda14cbcSMatt Macy abd_return_buf(src, tmp, s_len); 197*eda14cbcSMatt Macy 198*eda14cbcSMatt Macy /* 199*eda14cbcSMatt Macy * Decompression shouldn't fail, because we've already verified 200*eda14cbcSMatt Macy * the checksum. However, for extra protection (e.g. against bitflips 201*eda14cbcSMatt Macy * in non-ECC RAM), we handle this error (and test it). 202*eda14cbcSMatt Macy */ 203*eda14cbcSMatt Macy if (zio_decompress_fail_fraction != 0 && 204*eda14cbcSMatt Macy spa_get_random(zio_decompress_fail_fraction) == 0) 205*eda14cbcSMatt Macy ret = SET_ERROR(EINVAL); 206*eda14cbcSMatt Macy 207*eda14cbcSMatt Macy return (ret); 208*eda14cbcSMatt Macy } 209*eda14cbcSMatt Macy 210*eda14cbcSMatt Macy int 211*eda14cbcSMatt Macy zio_compress_to_feature(enum zio_compress comp) 212*eda14cbcSMatt Macy { 213*eda14cbcSMatt Macy switch (comp) { 214*eda14cbcSMatt Macy case ZIO_COMPRESS_ZSTD: 215*eda14cbcSMatt Macy return (SPA_FEATURE_ZSTD_COMPRESS); 216*eda14cbcSMatt Macy default: 217*eda14cbcSMatt Macy /* fallthru */; 218*eda14cbcSMatt Macy } 219*eda14cbcSMatt Macy return (SPA_FEATURE_NONE); 220*eda14cbcSMatt Macy } 221