diff options
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 000000000000..44bbfd249abc --- /dev/null +++ b/fs/logfs/compr.c | |||
| @@ -0,0 +1,95 @@ | |||
| 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 | |||
| 14 | static DEFINE_MUTEX(compr_mutex); | ||
| 15 | static struct z_stream_s stream; | ||
| 16 | |||
| 17 | int 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; | ||
| 46 | error: | ||
| 47 | mutex_unlock(&compr_mutex); | ||
| 48 | return ret; | ||
| 49 | } | ||
| 50 | |||
| 51 | int 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; | ||
| 77 | error: | ||
| 78 | mutex_unlock(&compr_mutex); | ||
| 79 | return ret; | ||
| 80 | } | ||
| 81 | |||
| 82 | int __init logfs_compr_init(void) | ||
| 83 | { | ||
| 84 | size_t size = max(zlib_deflate_workspacesize(), | ||
| 85 | zlib_inflate_workspacesize()); | ||
| 86 | stream.workspace = vmalloc(size); | ||
| 87 | if (!stream.workspace) | ||
| 88 | return -ENOMEM; | ||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | |||
| 92 | void logfs_compr_exit(void) | ||
| 93 | { | ||
| 94 | vfree(stream.workspace); | ||
| 95 | } | ||
