static int deflate_comp_init(struct deflate_ctx *ctx, int format) { int ret = 0; struct z_stream_s *stream = &ctx->comp_stream; stream->workspace = vzalloc(zlib_deflate_workspacesize( MAX_WBITS, MAX_MEM_LEVEL)); if (!stream->workspace) { ret = -ENOMEM; goto out; } if (format) ret = zlib_deflateInit(stream, 3); else ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED, -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL, Z_DEFAULT_STRATEGY); if (ret != Z_OK) { ret = -EINVAL; goto out_free; } out: return ret; out_free: vfree(stream->workspace); goto out; }
int logfs_compress(void *in, void *out, size_t inlen, size_t outlen) { int err, ret; ret = -EIO; mutex_lock(&compr_mutex); err = zlib_deflateInit(&stream, COMPR_LEVEL); if (err != Z_OK) goto error; stream.next_in = in; stream.avail_in = inlen; stream.total_in = 0; stream.next_out = out; stream.avail_out = outlen; stream.total_out = 0; err = zlib_deflate(&stream, Z_FINISH); if (err != Z_STREAM_END) goto error; err = zlib_deflateEnd(&stream); if (err != Z_OK) goto error; if (stream.total_out >= stream.total_in) goto error; ret = stream.total_out; error: mutex_unlock(&compr_mutex); return ret; }
int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen) { z_stream strm; int ret; if (*dstlen <= STREAM_END_SPACE) return -1; down(&deflate_sem); strm.workspace = deflate_workspace; if (Z_OK != zlib_deflateInit(&strm, 3)) { printk(KERN_WARNING "deflateInit failed\n"); up(&deflate_sem); return -1; } strm.next_in = data_in; strm.total_in = 0; strm.next_out = cpage_out; strm.total_out = 0; while (strm.total_out < *dstlen - STREAM_END_SPACE && strm.total_in < *sourcelen) { strm.avail_out = *dstlen - (strm.total_out + STREAM_END_SPACE); strm.avail_in = min((unsigned)(*sourcelen-strm.total_in), strm.avail_out); D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n", strm.avail_in, strm.avail_out)); ret = zlib_deflate(&strm, Z_PARTIAL_FLUSH); D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n", strm.avail_in, strm.avail_out, strm.total_in, strm.total_out)); if (ret != Z_OK) { D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret)); zlib_deflateEnd(&strm); up(&deflate_sem); return -1; } } strm.avail_out += STREAM_END_SPACE; strm.avail_in = 0; ret = zlib_deflate(&strm, Z_FINISH); zlib_deflateEnd(&strm); up(&deflate_sem); if (ret != Z_STREAM_END) { D1(printk(KERN_DEBUG "final deflate returned %d\n", ret)); return -1; } D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n", strm.total_in, strm.total_out)); if (strm.total_out >= strm.total_in) return -1; *dstlen = strm.total_out; *sourcelen = strm.total_in; return 0; }
/* * Compresses the source buffer into the destination buffer. The level * parameter has the same meaning as in deflateInit. sourceLen is the byte * length of the source buffer. Upon entry, destLen is the total size of the * destination buffer, which must be at least 0.1% larger than sourceLen plus * 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. * * compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough * memory, Z_BUF_ERROR if there was not enough room in the output buffer, * Z_STREAM_ERROR if the level parameter is invalid. */ int z_compress_level(void *dest, size_t *destLen, const void *source, size_t sourceLen, int level) { z_stream stream; int err; stream.next_in = (Byte *)source; stream.avail_in = (uInt)sourceLen; stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((size_t)stream.avail_out != *destLen) return Z_BUF_ERROR; stream.workspace = zlib_workspace_alloc(KM_SLEEP); if (!stream.workspace) return Z_MEM_ERROR; err = zlib_deflateInit(&stream, level); if (err != Z_OK) { zlib_workspace_free(stream.workspace); return err; } err = zlib_deflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { zlib_deflateEnd(&stream); zlib_workspace_free(stream.workspace); return err == Z_OK ? Z_BUF_ERROR : err; } *destLen = stream.total_out; err = zlib_deflateEnd(&stream); zlib_workspace_free(stream.workspace); return err; }