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"
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
,
17 assert("edward-1316", inode
!= NULL
);
18 assert("edward-1317", plugin
!= NULL
);
19 assert("edward-1318", is_reiser4_inode(inode
));
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
)
32 return aset_set_unsafe(&reiser4_inode_data(inode
)->pset
,
33 PSET_COMPRESSION
, plugin
);
36 static reiser4_plugin_ops compression_plugin_ops
= {
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)
59 warning("edward-1337", "Zlib not compiled into kernel");
63 static int gzip1_overrun(unsigned src_len UNUSED_ARG
)
68 static coa_t
gzip1_alloc(tfm_action act
)
74 case TFMA_WRITE
: /* compress */
75 coa
= reiser4_vmalloc(zlib_deflate_workspacesize());
81 case TFMA_READ
: /* decompress */
82 coa
= reiser4_vmalloc(zlib_inflate_workspacesize());
89 impossible("edward-767",
90 "trying to alloc workspace for unknown tfm action");
94 "alloc workspace for gzip1 (tfm action = %d) failed\n",
102 static void gzip1_free(coa_t coa
, tfm_action act
)
104 assert("edward-769", coa
!= NULL
);
107 case TFMA_WRITE
: /* compress */
110 case TFMA_READ
: /* decompress */
114 impossible("edward-770", "unknown tfm action");
119 static int gzip1_min_size_deflate(void)
125 gzip1_compress(coa_t coa
, __u8
* src_first
, unsigned src_len
,
126 __u8
* dst_first
, unsigned *dst_len
)
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
,
140 warning("edward-771", "zlib_deflateInit2 returned %d\n", ret
);
143 ret
= zlib_deflateReset(&stream
);
145 warning("edward-772", "zlib_deflateReset returned %d\n", ret
);
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
) {
156 warning("edward-773",
157 "zlib_deflate returned %d\n", ret
);
160 *dst_len
= stream
.total_out
;
169 gzip1_decompress(coa_t coa
, __u8
* src_first
, unsigned src_len
,
170 __u8
* dst_first
, unsigned *dst_len
)
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
);
182 warning("edward-774", "zlib_inflateInit2 returned %d\n", ret
);
185 ret
= zlib_inflateReset(&stream
);
187 warning("edward-775", "zlib_inflateReset returned %d\n", ret
);
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.
202 if (ret
== Z_OK
&& !stream
.avail_in
&& stream
.avail_out
) {
204 stream
.next_in
= &zerostuff
;
206 ret
= zlib_inflate(&stream
, Z_FINISH
);
208 if (ret
!= Z_STREAM_END
) {
209 warning("edward-776", "zlib_inflate returned %d\n", ret
);
212 *dst_len
= stream
.total_out
;
217 /******************************************************************************/
218 /* lzo1 compression */
219 /******************************************************************************/
221 static int lzo1_init(void)
226 static int lzo1_overrun(unsigned in_len
)
228 return in_len
/ 64 + 16 + 3;
231 static coa_t
lzo1_alloc(tfm_action act
)
237 case TFMA_WRITE
: /* compress */
238 coa
= reiser4_vmalloc(LZO1X_1_MEM_COMPRESS
);
243 case TFMA_READ
: /* decompress */
246 impossible("edward-877",
247 "trying to alloc workspace for unknown tfm action");
250 warning("edward-878",
251 "alloc workspace for lzo1 (tfm action = %d) failed\n",
258 static void lzo1_free(coa_t coa
, tfm_action act
)
260 assert("edward-879", coa
!= NULL
);
263 case TFMA_WRITE
: /* compress */
266 case TFMA_READ
: /* decompress */
267 impossible("edward-1304",
268 "trying to free non-allocated workspace");
270 impossible("edward-880", "unknown tfm action");
275 static int lzo1_min_size_deflate(void)
281 lzo1_compress(coa_t coa
, __u8
* src_first
, unsigned src_len
,
282 __u8
* dst_first
, unsigned *dst_len
)
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");
294 if (*dst_len
>= src_len
) {
295 //warning("edward-850", "lzo1x_1_compress: incompressible data\n");
305 lzo1_decompress(coa_t coa
, __u8
* src_first
, unsigned src_len
,
306 __u8
* dst_first
, unsigned *dst_len
)
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");
319 compression_plugin compression_plugins
[LAST_COMPRESSION_ID
] = {
320 [LZO1_COMPRESSION_ID
] = {
322 .type_id
= REISER4_COMPRESSION_PLUGIN_TYPE
,
323 .id
= LZO1_COMPRESSION_ID
,
324 .pops
= &compression_plugin_ops
,
326 .desc
= "lzo1 compression transform",
327 .linkage
= {NULL
, NULL
}
330 .overrun
= lzo1_overrun
,
333 .min_size_deflate
= lzo1_min_size_deflate
,
334 .checksum
= reiser4_adler32
,
335 .compress
= lzo1_compress
,
336 .decompress
= lzo1_decompress
338 [GZIP1_COMPRESSION_ID
] = {
340 .type_id
= REISER4_COMPRESSION_PLUGIN_TYPE
,
341 .id
= GZIP1_COMPRESSION_ID
,
342 .pops
= &compression_plugin_ops
,
344 .desc
= "gzip1 compression transform",
345 .linkage
= {NULL
, NULL
}
348 .overrun
= gzip1_overrun
,
349 .alloc
= gzip1_alloc
,
351 .min_size_deflate
= gzip1_min_size_deflate
,
352 .checksum
= reiser4_adler32
,
353 .compress
= gzip1_compress
,
354 .decompress
= gzip1_decompress
360 c-indentation-style: "K&R"