diff options
author | James Morris <jmorris@namei.org> | 2010-03-30 21:39:27 (GMT) |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-03-30 21:39:27 (GMT) |
commit | d25d6fa1a95f465ff1ec4458ca15e30b2c8dffec (patch) | |
tree | 7362b182dedd825fc762ef7706830837e42943af /fs/logfs/compr.c | |
parent | 225a9be24d799aa16d543c31fb09f0c9ed1d9caa (diff) | |
parent | 2eaa9cfdf33b8d7fb7aff27792192e0019ae8fc6 (diff) | |
download | linux-fsl-qoriq-d25d6fa1a95f465ff1ec4458ca15e30b2c8dffec.tar.xz |
Merge branch 'master' into next
Diffstat (limited to 'fs/logfs/compr.c')
-rw-r--r-- | fs/logfs/compr.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/fs/logfs/compr.c b/fs/logfs/compr.c new file mode 100644 index 0000000..44bbfd2 --- /dev/null +++ b/fs/logfs/compr.c @@ -0,0 +1,95 @@ +/* + * fs/logfs/compr.c - compression routines + * + * As should be obvious for Linux kernel code, license is GPLv2 + * + * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org> + */ +#include "logfs.h" +#include <linux/vmalloc.h> +#include <linux/zlib.h> + +#define COMPR_LEVEL 3 + +static DEFINE_MUTEX(compr_mutex); +static struct z_stream_s stream; + +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 logfs_uncompress(void *in, void *out, size_t inlen, size_t outlen) +{ + int err, ret; + + ret = -EIO; + mutex_lock(&compr_mutex); + err = zlib_inflateInit(&stream); + 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_inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) + goto error; + + err = zlib_inflateEnd(&stream); + if (err != Z_OK) + goto error; + + ret = 0; +error: + mutex_unlock(&compr_mutex); + return ret; +} + +int __init logfs_compr_init(void) +{ + size_t size = max(zlib_deflate_workspacesize(), + zlib_inflate_workspacesize()); + stream.workspace = vmalloc(size); + if (!stream.workspace) + return -ENOMEM; + return 0; +} + +void logfs_compr_exit(void) +{ + vfree(stream.workspace); +} |