^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2014 Sergey Senozhatsky.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/crypto.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "zcomp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static const char * const backends[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) "lzo",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) "lzo-rle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #if IS_ENABLED(CONFIG_CRYPTO_LZ4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) "lz4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #if IS_ENABLED(CONFIG_CRYPTO_LZ4HC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) "lz4hc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #if IS_ENABLED(CONFIG_CRYPTO_842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) "842",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #if IS_ENABLED(CONFIG_CRYPTO_ZSTD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) "zstd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static void zcomp_strm_free(struct zcomp_strm *zstrm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (!IS_ERR_OR_NULL(zstrm->tfm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) crypto_free_comp(zstrm->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) free_pages((unsigned long)zstrm->buffer, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) zstrm->tfm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) zstrm->buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Initialize zcomp_strm structure with ->tfm initialized by backend, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * ->buffer. Return a negative value on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int zcomp_strm_init(struct zcomp_strm *zstrm, struct zcomp *comp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) zstrm->tfm = crypto_alloc_comp(comp->name, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * allocate 2 pages. 1 for compressed data, plus 1 extra for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * case when compressed size is larger than the original one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (IS_ERR_OR_NULL(zstrm->tfm) || !zstrm->buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) zcomp_strm_free(zstrm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) bool zcomp_available_algorithm(const char *comp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) i = sysfs_match_string(backends, comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * Crypto does not ignore a trailing new line symbol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * so make sure you don't supply a string containing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * This also means that we permit zcomp initialisation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * with any compressing algorithm known to crypto api.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return crypto_has_comp(comp, 0, 0) == 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* show available compressors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ssize_t zcomp_available_show(const char *comp, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) bool known_algorithm = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ssize_t sz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) for (i = 0; i < ARRAY_SIZE(backends); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (!strcmp(comp, backends[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) known_algorithm = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) "[%s] ", backends[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) "%s ", backends[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * Out-of-tree module known to crypto api or a missing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * entry in `backends'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (!known_algorithm && crypto_has_comp(comp, 0, 0) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) "[%s] ", comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct zcomp_strm *zcomp_stream_get(struct zcomp *comp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) local_lock(&comp->stream->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return this_cpu_ptr(comp->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) void zcomp_stream_put(struct zcomp *comp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) local_unlock(&comp->stream->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int zcomp_compress(struct zcomp_strm *zstrm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) const void *src, unsigned int *dst_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * Our dst memory (zstrm->buffer) is always `2 * PAGE_SIZE' sized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * because sometimes we can endup having a bigger compressed data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * due to various reasons: for example compression algorithms tend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * to add some padding to the compressed buffer. Speaking of padding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * comp algorithm `842' pads the compressed length to multiple of 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * and returns -ENOSP when the dst memory is not big enough, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * is not something that ZRAM wants to see. We can handle the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * `compressed_size > PAGE_SIZE' case easily in ZRAM, but when we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * receive -ERRNO from the compressing backend we can't help it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * anymore. To make `842' happy we need to tell the exact size of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * the dst buffer, zram_drv will take care of the fact that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * compressed buffer is too big.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *dst_len = PAGE_SIZE * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return crypto_comp_compress(zstrm->tfm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) src, PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) zstrm->buffer, dst_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int zcomp_decompress(struct zcomp_strm *zstrm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) const void *src, unsigned int src_len, void *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned int dst_len = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return crypto_comp_decompress(zstrm->tfm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) src, src_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) dst, &dst_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct zcomp *comp = hlist_entry(node, struct zcomp, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct zcomp_strm *zstrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) zstrm = per_cpu_ptr(comp->stream, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) local_lock_init(&zstrm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ret = zcomp_strm_init(zstrm, comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) pr_err("Can't allocate a compression stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int zcomp_cpu_dead(unsigned int cpu, struct hlist_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct zcomp *comp = hlist_entry(node, struct zcomp, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct zcomp_strm *zstrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) zstrm = per_cpu_ptr(comp->stream, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) zcomp_strm_free(zstrm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int zcomp_init(struct zcomp *comp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) comp->stream = alloc_percpu(struct zcomp_strm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (!comp->stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ret = cpuhp_state_add_instance(CPUHP_ZCOMP_PREPARE, &comp->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) free_percpu(comp->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) void zcomp_destroy(struct zcomp *comp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) cpuhp_state_remove_instance(CPUHP_ZCOMP_PREPARE, &comp->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) free_percpu(comp->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) kfree(comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * search available compressors for requested algorithm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * allocate new zcomp and initialize it. return compressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * backend pointer or ERR_PTR if things went bad. ERR_PTR(-EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * if requested algorithm is not supported, ERR_PTR(-ENOMEM) in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * case of allocation error, or any other error potentially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * returned by zcomp_init().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct zcomp *zcomp_create(const char *compress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct zcomp *comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (!zcomp_available_algorithm(compress))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) comp = kzalloc(sizeof(struct zcomp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (!comp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) comp->name = compress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) error = zcomp_init(comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) kfree(comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }