revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / plugin / compress / compress.c
blob99f310740dd84a14a54506c60c7d16bab97e5a46
1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */
2 /* reiser4 compression transform plugins */
4 #include "../../debug.h"
5 #include "../../inode.h"
6 #include "../plugin.h"
8 #include <linux/lzo.h>
9 #include <linux/zlib.h>
10 #include <linux/types.h>
11 #include <linux/hardirq.h>
13 static int change_compression(struct inode *inode,
14 reiser4_plugin * plugin,
15 pset_member memb)
17 assert("edward-1316", inode != NULL);
18 assert("edward-1317", plugin != NULL);
19 assert("edward-1318", is_reiser4_inode(inode));
20 assert("edward-1319",
21 plugin->h.type_id == REISER4_COMPRESSION_PLUGIN_TYPE);
23 /* cannot change compression plugin of already existing regular object */
24 if (!plugin_of_group(inode_file_plugin(inode), REISER4_DIRECTORY_FILE))
25 return RETERR(-EINVAL);
27 /* If matches, nothing to change. */
28 if (inode_hash_plugin(inode) != NULL &&
29 inode_hash_plugin(inode)->h.id == plugin->h.id)
30 return 0;
32 return aset_set_unsafe(&reiser4_inode_data(inode)->pset,
33 PSET_COMPRESSION, plugin);
36 static reiser4_plugin_ops compression_plugin_ops = {
37 .init = NULL,
38 .load = NULL,
39 .save_len = NULL,
40 .save = NULL,
41 .change = &change_compression
44 /******************************************************************************/
45 /* gzip1 compression */
46 /******************************************************************************/
48 #define GZIP1_DEF_LEVEL Z_BEST_SPEED
49 #define GZIP1_DEF_WINBITS 15
50 #define GZIP1_DEF_MEMLEVEL MAX_MEM_LEVEL
52 static int gzip1_init(void)
54 int ret = -EINVAL;
55 #if REISER4_ZLIB
56 ret = 0;
57 #endif
58 if (ret == -EINVAL)
59 warning("edward-1337", "Zlib not compiled into kernel");
60 return ret;
63 static int gzip1_overrun(unsigned src_len UNUSED_ARG)
65 return 0;
68 static coa_t gzip1_alloc(tfm_action act)
70 coa_t coa = NULL;
71 #if REISER4_ZLIB
72 int ret = 0;
73 switch (act) {
74 case TFMA_WRITE: /* compress */
75 coa = reiser4_vmalloc(zlib_deflate_workspacesize());
76 if (!coa) {
77 ret = -ENOMEM;
78 break;
80 break;
81 case TFMA_READ: /* decompress */
82 coa = reiser4_vmalloc(zlib_inflate_workspacesize());
83 if (!coa) {
84 ret = -ENOMEM;
85 break;
87 break;
88 default:
89 impossible("edward-767",
90 "trying to alloc workspace for unknown tfm action");
92 if (ret) {
93 warning("edward-768",
94 "alloc workspace for gzip1 (tfm action = %d) failed\n",
95 act);
96 return ERR_PTR(ret);
98 #endif
99 return coa;
102 static void gzip1_free(coa_t coa, tfm_action act)
104 assert("edward-769", coa != NULL);
106 switch (act) {
107 case TFMA_WRITE: /* compress */
108 vfree(coa);
109 break;
110 case TFMA_READ: /* decompress */
111 vfree(coa);
112 break;
113 default:
114 impossible("edward-770", "unknown tfm action");
116 return;
119 static int gzip1_min_size_deflate(void)
121 return 64;
124 static void
125 gzip1_compress(coa_t coa, __u8 * src_first, unsigned src_len,
126 __u8 * dst_first, unsigned *dst_len)
128 #if REISER4_ZLIB
129 int ret = 0;
130 struct z_stream_s stream;
132 assert("edward-842", coa != NULL);
133 assert("edward-875", src_len != 0);
135 stream.workspace = coa;
136 ret = zlib_deflateInit2(&stream, GZIP1_DEF_LEVEL, Z_DEFLATED,
137 -GZIP1_DEF_WINBITS, GZIP1_DEF_MEMLEVEL,
138 Z_DEFAULT_STRATEGY);
139 if (ret != Z_OK) {
140 warning("edward-771", "zlib_deflateInit2 returned %d\n", ret);
141 goto rollback;
143 ret = zlib_deflateReset(&stream);
144 if (ret != Z_OK) {
145 warning("edward-772", "zlib_deflateReset returned %d\n", ret);
146 goto rollback;
148 stream.next_in = src_first;
149 stream.avail_in = src_len;
150 stream.next_out = dst_first;
151 stream.avail_out = *dst_len;
153 ret = zlib_deflate(&stream, Z_FINISH);
154 if (ret != Z_STREAM_END) {
155 if (ret != Z_OK)
156 warning("edward-773",
157 "zlib_deflate returned %d\n", ret);
158 goto rollback;
160 *dst_len = stream.total_out;
161 return;
162 rollback:
163 *dst_len = src_len;
164 #endif
165 return;
168 static void
169 gzip1_decompress(coa_t coa, __u8 * src_first, unsigned src_len,
170 __u8 * dst_first, unsigned *dst_len)
172 #if REISER4_ZLIB
173 int ret = 0;
174 struct z_stream_s stream;
176 assert("edward-843", coa != NULL);
177 assert("edward-876", src_len != 0);
179 stream.workspace = coa;
180 ret = zlib_inflateInit2(&stream, -GZIP1_DEF_WINBITS);
181 if (ret != Z_OK) {
182 warning("edward-774", "zlib_inflateInit2 returned %d\n", ret);
183 return;
185 ret = zlib_inflateReset(&stream);
186 if (ret != Z_OK) {
187 warning("edward-775", "zlib_inflateReset returned %d\n", ret);
188 return;
191 stream.next_in = src_first;
192 stream.avail_in = src_len;
193 stream.next_out = dst_first;
194 stream.avail_out = *dst_len;
196 ret = zlib_inflate(&stream, Z_SYNC_FLUSH);
198 * Work around a bug in zlib, which sometimes wants to taste an extra
199 * byte when being used in the (undocumented) raw deflate mode.
200 * (From USAGI).
202 if (ret == Z_OK && !stream.avail_in && stream.avail_out) {
203 u8 zerostuff = 0;
204 stream.next_in = &zerostuff;
205 stream.avail_in = 1;
206 ret = zlib_inflate(&stream, Z_FINISH);
208 if (ret != Z_STREAM_END) {
209 warning("edward-776", "zlib_inflate returned %d\n", ret);
210 return;
212 *dst_len = stream.total_out;
213 #endif
214 return;
217 /******************************************************************************/
218 /* lzo1 compression */
219 /******************************************************************************/
221 static int lzo1_init(void)
223 return 0;
226 static int lzo1_overrun(unsigned in_len)
228 return in_len / 64 + 16 + 3;
231 static coa_t lzo1_alloc(tfm_action act)
233 int ret = 0;
234 coa_t coa = NULL;
236 switch (act) {
237 case TFMA_WRITE: /* compress */
238 coa = reiser4_vmalloc(LZO1X_1_MEM_COMPRESS);
239 if (!coa) {
240 ret = -ENOMEM;
241 break;
243 case TFMA_READ: /* decompress */
244 break;
245 default:
246 impossible("edward-877",
247 "trying to alloc workspace for unknown tfm action");
249 if (ret) {
250 warning("edward-878",
251 "alloc workspace for lzo1 (tfm action = %d) failed\n",
252 act);
253 return ERR_PTR(ret);
255 return coa;
258 static void lzo1_free(coa_t coa, tfm_action act)
260 assert("edward-879", coa != NULL);
262 switch (act) {
263 case TFMA_WRITE: /* compress */
264 vfree(coa);
265 break;
266 case TFMA_READ: /* decompress */
267 impossible("edward-1304",
268 "trying to free non-allocated workspace");
269 default:
270 impossible("edward-880", "unknown tfm action");
272 return;
275 static int lzo1_min_size_deflate(void)
277 return 256;
280 static void
281 lzo1_compress(coa_t coa, __u8 * src_first, unsigned src_len,
282 __u8 * dst_first, unsigned *dst_len)
284 int result;
286 assert("edward-846", coa != NULL);
287 assert("edward-847", src_len != 0);
289 result = lzo1x_1_compress(src_first, src_len, dst_first, dst_len, coa);
290 if (unlikely(result != LZO_E_OK)) {
291 warning("edward-849", "lzo1x_1_compress failed\n");
292 goto out;
294 if (*dst_len >= src_len) {
295 //warning("edward-850", "lzo1x_1_compress: incompressible data\n");
296 goto out;
298 return;
299 out:
300 *dst_len = src_len;
301 return;
304 static void
305 lzo1_decompress(coa_t coa, __u8 * src_first, unsigned src_len,
306 __u8 * dst_first, unsigned *dst_len)
308 int result;
310 assert("edward-851", coa == NULL);
311 assert("edward-852", src_len != 0);
313 result = lzo1x_decompress_safe(src_first, src_len, dst_first, dst_len);
314 if (result != LZO_E_OK)
315 warning("edward-853", "lzo1x_1_decompress failed\n");
316 return;
319 compression_plugin compression_plugins[LAST_COMPRESSION_ID] = {
320 [LZO1_COMPRESSION_ID] = {
321 .h = {
322 .type_id = REISER4_COMPRESSION_PLUGIN_TYPE,
323 .id = LZO1_COMPRESSION_ID,
324 .pops = &compression_plugin_ops,
325 .label = "lzo1",
326 .desc = "lzo1 compression transform",
327 .linkage = {NULL, NULL}
329 .init = lzo1_init,
330 .overrun = lzo1_overrun,
331 .alloc = lzo1_alloc,
332 .free = lzo1_free,
333 .min_size_deflate = lzo1_min_size_deflate,
334 .checksum = reiser4_adler32,
335 .compress = lzo1_compress,
336 .decompress = lzo1_decompress
338 [GZIP1_COMPRESSION_ID] = {
339 .h = {
340 .type_id = REISER4_COMPRESSION_PLUGIN_TYPE,
341 .id = GZIP1_COMPRESSION_ID,
342 .pops = &compression_plugin_ops,
343 .label = "gzip1",
344 .desc = "gzip1 compression transform",
345 .linkage = {NULL, NULL}
347 .init = gzip1_init,
348 .overrun = gzip1_overrun,
349 .alloc = gzip1_alloc,
350 .free = gzip1_free,
351 .min_size_deflate = gzip1_min_size_deflate,
352 .checksum = reiser4_adler32,
353 .compress = gzip1_compress,
354 .decompress = gzip1_decompress
359 Local variables:
360 c-indentation-style: "K&R"
361 mode-name: "LC"
362 c-basic-offset: 8
363 tab-width: 8
364 fill-column: 120
365 scroll-step: 1
366 End: