1/* 2 * fs/logfs/compr.c - compression routines 3 * 4 * As should be obvious for Linux kernel code, license is GPLv2 5 * 6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org> 7 */ 8#include "logfs.h" 9#include <linux/vmalloc.h> 10#include <linux/zlib.h> 11 12#define COMPR_LEVEL 3 13 14static DEFINE_MUTEX(compr_mutex); 15static struct z_stream_s stream; 16 17int logfs_compress(void *in, void *out, size_t inlen, size_t outlen) 18{ 19 int err, ret; 20 21 ret = -EIO; 22 mutex_lock(&compr_mutex); 23 err = zlib_deflateInit(&stream, COMPR_LEVEL); 24 if (err != Z_OK) 25 goto error; 26 27 stream.next_in = in; 28 stream.avail_in = inlen; 29 stream.total_in = 0; 30 stream.next_out = out; 31 stream.avail_out = outlen; 32 stream.total_out = 0; 33 34 err = zlib_deflate(&stream, Z_FINISH); 35 if (err != Z_STREAM_END) 36 goto error; 37 38 err = zlib_deflateEnd(&stream); 39 if (err != Z_OK) 40 goto error; 41 42 if (stream.total_out >= stream.total_in) 43 goto error; 44 45 ret = stream.total_out; 46error: 47 mutex_unlock(&compr_mutex); 48 return ret; 49} 50 51int logfs_uncompress(void *in, void *out, size_t inlen, size_t outlen) 52{ 53 int err, ret; 54 55 ret = -EIO; 56 mutex_lock(&compr_mutex); 57 err = zlib_inflateInit(&stream); 58 if (err != Z_OK) 59 goto error; 60 61 stream.next_in = in; 62 stream.avail_in = inlen; 63 stream.total_in = 0; 64 stream.next_out = out; 65 stream.avail_out = outlen; 66 stream.total_out = 0; 67 68 err = zlib_inflate(&stream, Z_FINISH); 69 if (err != Z_STREAM_END) 70 goto error; 71 72 err = zlib_inflateEnd(&stream); 73 if (err != Z_OK) 74 goto error; 75 76 ret = 0; 77error: 78 mutex_unlock(&compr_mutex); 79 return ret; 80} 81 82int __init logfs_compr_init(void) 83{ 84 size_t size = max(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL), 85 zlib_inflate_workspacesize()); 86 stream.workspace = vmalloc(size); 87 if (!stream.workspace) 88 return -ENOMEM; 89 return 0; 90} 91 92void logfs_compr_exit(void) 93{ 94 vfree(stream.workspace); 95} 96