]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * uncompress.c | |
3 | * | |
4 | * (C) Copyright 1999 Linus Torvalds | |
5 | * | |
6 | * cramfs interfaces to the uncompression library. There's really just | |
7 | * three entrypoints: | |
8 | * | |
9 | * - cramfs_uncompress_init() - called to initialize the thing. | |
10 | * - cramfs_uncompress_exit() - tell me when you're done | |
11 | * - cramfs_uncompress_block() - uncompress a block. | |
12 | * | |
13 | * NOTE NOTE NOTE! The uncompression is entirely single-threaded. We | |
14 | * only have one stream, and we'll initialize it only once even if it | |
15 | * then is used by multiple filesystems. | |
16 | */ | |
17 | ||
4f21e1ea FF |
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
19 | ||
1da177e4 LT |
20 | #include <linux/kernel.h> |
21 | #include <linux/errno.h> | |
22 | #include <linux/vmalloc.h> | |
23 | #include <linux/zlib.h> | |
f7f4f4dd | 24 | #include "internal.h" |
1da177e4 LT |
25 | |
26 | static z_stream stream; | |
27 | static int initialized; | |
28 | ||
29 | /* Returns length of decompressed data. */ | |
30 | int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen) | |
31 | { | |
32 | int err; | |
33 | ||
34 | stream.next_in = src; | |
35 | stream.avail_in = srclen; | |
36 | ||
37 | stream.next_out = dst; | |
38 | stream.avail_out = dstlen; | |
39 | ||
40 | err = zlib_inflateReset(&stream); | |
41 | if (err != Z_OK) { | |
f175ff81 | 42 | pr_err("zlib_inflateReset error %d\n", err); |
1da177e4 LT |
43 | zlib_inflateEnd(&stream); |
44 | zlib_inflateInit(&stream); | |
45 | } | |
46 | ||
47 | err = zlib_inflate(&stream, Z_FINISH); | |
48 | if (err != Z_STREAM_END) | |
49 | goto err; | |
50 | return stream.total_out; | |
51 | ||
52 | err: | |
f175ff81 FF |
53 | pr_err("Error %d while decompressing!\n", err); |
54 | pr_err("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen); | |
98310e58 | 55 | return -EIO; |
1da177e4 LT |
56 | } |
57 | ||
58 | int cramfs_uncompress_init(void) | |
59 | { | |
60 | if (!initialized++) { | |
61 | stream.workspace = vmalloc(zlib_inflate_workspacesize()); | |
31d92e55 | 62 | if (!stream.workspace) { |
1da177e4 LT |
63 | initialized = 0; |
64 | return -ENOMEM; | |
65 | } | |
66 | stream.next_in = NULL; | |
67 | stream.avail_in = 0; | |
68 | zlib_inflateInit(&stream); | |
69 | } | |
70 | return 0; | |
71 | } | |
72 | ||
368bdb3d | 73 | void cramfs_uncompress_exit(void) |
1da177e4 LT |
74 | { |
75 | if (!--initialized) { | |
76 | zlib_inflateEnd(&stream); | |
77 | vfree(stream.workspace); | |
78 | } | |
1da177e4 | 79 | } |