Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / fs / logfs / compr.c
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 }