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
logfs_compress(void * in,void * out,size_t inlen,size_t outlen)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
logfs_uncompress(void * in,void * out,size_t inlen,size_t outlen)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
logfs_compr_init(void)82 int __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
logfs_compr_exit(void)92 void logfs_compr_exit(void)
93 {
94 vfree(stream.workspace);
95 }
96