2 * JFFS2 -- Journalling Flash File System, Version 2.
4 * Copyright © 2001-2007 Red Hat, Inc.
5 * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
6 * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
7 * University of Szeged, Hungary
9 * Created by Arjan van de Ven <arjan@infradead.org>
11 * For licensing information, see the file 'LICENCE' in this directory.
17 static DEFINE_SPINLOCK(jffs2_compressor_list_lock
);
19 /* Available compressors are on this list */
20 static LIST_HEAD(jffs2_compressor_list
);
22 /* Actual compression mode */
23 static int jffs2_compression_mode
= JFFS2_COMPR_MODE_PRIORITY
;
25 /* Statistics for blocks stored without compression */
26 static uint32_t none_stat_compr_blocks
=0,none_stat_decompr_blocks
=0,none_stat_compr_size
=0;
30 * Return 1 to use this compression
32 static int jffs2_is_best_compression(struct jffs2_compressor
*this,
33 struct jffs2_compressor
*best
, uint32_t size
, uint32_t bestsize
)
35 switch (jffs2_compression_mode
) {
36 case JFFS2_COMPR_MODE_SIZE
:
40 case JFFS2_COMPR_MODE_FAVOURLZO
:
41 if ((this->compr
== JFFS2_COMPR_LZO
) && (bestsize
> size
))
43 if ((best
->compr
!= JFFS2_COMPR_LZO
) && (bestsize
> size
))
45 if ((this->compr
== JFFS2_COMPR_LZO
) && (bestsize
> (size
* FAVOUR_LZO_PERCENT
/ 100)))
47 if ((bestsize
* FAVOUR_LZO_PERCENT
/ 100) > size
)
52 /* Shouldn't happen */
57 * jffs2_selected_compress:
58 * @compr: Explicit compression type to use (ie, JFFS2_COMPR_ZLIB).
59 * If 0, just take the first available compression mode.
60 * @data_in: Pointer to uncompressed data
61 * @cpage_out: Pointer to returned pointer to buffer for compressed data
62 * @datalen: On entry, holds the amount of data available for compression.
63 * On exit, expected to hold the amount of data actually compressed.
64 * @cdatalen: On entry, holds the amount of space available for compressed
65 * data. On exit, expected to hold the actual size of the compressed
68 * Returns: the compression type used. Zero is used to show that the data
69 * could not be compressed; probably because we couldn't find the requested
72 static int jffs2_selected_compress(u8 compr
, unsigned char *data_in
,
73 unsigned char **cpage_out
, u32
*datalen
, u32
*cdatalen
)
75 struct jffs2_compressor
*this;
76 int err
, ret
= JFFS2_COMPR_NONE
;
77 uint32_t orig_slen
, orig_dlen
;
80 output_buf
= kmalloc(*cdatalen
, GFP_KERNEL
);
82 printk(KERN_WARNING
"JFFS2: No memory for compressor allocation. Compression failed.\n");
86 orig_dlen
= *cdatalen
;
87 spin_lock(&jffs2_compressor_list_lock
);
88 list_for_each_entry(this, &jffs2_compressor_list
, list
) {
89 /* Skip decompress-only and disabled modules */
90 if (!this->compress
|| this->disabled
)
93 /* Skip if not the desired compression type */
94 if (compr
&& (compr
!= this->compr
))
98 * Either compression type was unspecified, or we found our
99 * compressor; either way, we're good to go.
102 spin_unlock(&jffs2_compressor_list_lock
);
104 *datalen
= orig_slen
;
105 *cdatalen
= orig_dlen
;
106 err
= this->compress(data_in
, output_buf
, datalen
, cdatalen
);
108 spin_lock(&jffs2_compressor_list_lock
);
113 this->stat_compr_blocks
++;
114 this->stat_compr_orig_size
+= *datalen
;
115 this->stat_compr_new_size
+= *cdatalen
;
119 spin_unlock(&jffs2_compressor_list_lock
);
120 if (ret
== JFFS2_COMPR_NONE
)
123 *cpage_out
= output_buf
;
129 * @data_in: Pointer to uncompressed data
130 * @cpage_out: Pointer to returned pointer to buffer for compressed data
131 * @datalen: On entry, holds the amount of data available for compression.
132 * On exit, expected to hold the amount of data actually compressed.
133 * @cdatalen: On entry, holds the amount of space available for compressed
134 * data. On exit, expected to hold the actual size of the compressed
137 * Returns: Lower byte to be stored with data indicating compression type used.
138 * Zero is used to show that the data could not be compressed - the
139 * compressed version was actually larger than the original.
140 * Upper byte will be used later. (soon)
142 * If the cdata buffer isn't large enough to hold all the uncompressed data,
143 * jffs2_compress should compress as much as will fit, and should set
144 * *datalen accordingly to show the amount of data which were compressed.
146 uint16_t jffs2_compress(struct jffs2_sb_info
*c
, struct jffs2_inode_info
*f
,
147 unsigned char *data_in
, unsigned char **cpage_out
,
148 uint32_t *datalen
, uint32_t *cdatalen
)
150 int ret
= JFFS2_COMPR_NONE
;
152 struct jffs2_compressor
*this, *best
=NULL
;
153 unsigned char *output_buf
= NULL
, *tmp_buf
;
154 uint32_t orig_slen
, orig_dlen
;
155 uint32_t best_slen
=0, best_dlen
=0;
157 if (c
->mount_opts
.override_compr
)
158 mode
= c
->mount_opts
.compr
;
160 mode
= jffs2_compression_mode
;
163 case JFFS2_COMPR_MODE_NONE
:
165 case JFFS2_COMPR_MODE_PRIORITY
:
166 ret
= jffs2_selected_compress(0, data_in
, cpage_out
, datalen
,
169 case JFFS2_COMPR_MODE_SIZE
:
170 case JFFS2_COMPR_MODE_FAVOURLZO
:
171 orig_slen
= *datalen
;
172 orig_dlen
= *cdatalen
;
173 spin_lock(&jffs2_compressor_list_lock
);
174 list_for_each_entry(this, &jffs2_compressor_list
, list
) {
175 /* Skip decompress-only backwards-compatibility and disabled modules */
176 if ((!this->compress
)||(this->disabled
))
178 /* Allocating memory for output buffer if necessary */
179 if ((this->compr_buf_size
< orig_slen
) && (this->compr_buf
)) {
180 spin_unlock(&jffs2_compressor_list_lock
);
181 kfree(this->compr_buf
);
182 spin_lock(&jffs2_compressor_list_lock
);
183 this->compr_buf_size
=0;
184 this->compr_buf
=NULL
;
186 if (!this->compr_buf
) {
187 spin_unlock(&jffs2_compressor_list_lock
);
188 tmp_buf
= kmalloc(orig_slen
, GFP_KERNEL
);
189 spin_lock(&jffs2_compressor_list_lock
);
191 printk(KERN_WARNING
"JFFS2: No memory for compressor allocation. (%d bytes)\n", orig_slen
);
195 this->compr_buf
= tmp_buf
;
196 this->compr_buf_size
= orig_slen
;
200 spin_unlock(&jffs2_compressor_list_lock
);
201 *datalen
= orig_slen
;
202 *cdatalen
= orig_dlen
;
203 compr_ret
= this->compress(data_in
, this->compr_buf
, datalen
, cdatalen
);
204 spin_lock(&jffs2_compressor_list_lock
);
207 if (((!best_dlen
) || jffs2_is_best_compression(this, best
, *cdatalen
, best_dlen
))
208 && (*cdatalen
< *datalen
)) {
209 best_dlen
= *cdatalen
;
210 best_slen
= *datalen
;
216 *cdatalen
= best_dlen
;
217 *datalen
= best_slen
;
218 output_buf
= best
->compr_buf
;
219 best
->compr_buf
= NULL
;
220 best
->compr_buf_size
= 0;
221 best
->stat_compr_blocks
++;
222 best
->stat_compr_orig_size
+= best_slen
;
223 best
->stat_compr_new_size
+= best_dlen
;
225 *cpage_out
= output_buf
;
227 spin_unlock(&jffs2_compressor_list_lock
);
229 case JFFS2_COMPR_MODE_FORCELZO
:
230 ret
= jffs2_selected_compress(JFFS2_COMPR_LZO
, data_in
,
231 cpage_out
, datalen
, cdatalen
);
233 case JFFS2_COMPR_MODE_FORCEZLIB
:
234 ret
= jffs2_selected_compress(JFFS2_COMPR_ZLIB
, data_in
,
235 cpage_out
, datalen
, cdatalen
);
238 printk(KERN_ERR
"JFFS2: unknown compression mode.\n");
241 if (ret
== JFFS2_COMPR_NONE
) {
242 *cpage_out
= data_in
;
243 *datalen
= *cdatalen
;
244 none_stat_compr_blocks
++;
245 none_stat_compr_size
+= *datalen
;
250 int jffs2_decompress(struct jffs2_sb_info
*c
, struct jffs2_inode_info
*f
,
251 uint16_t comprtype
, unsigned char *cdata_in
,
252 unsigned char *data_out
, uint32_t cdatalen
, uint32_t datalen
)
254 struct jffs2_compressor
*this;
257 /* Older code had a bug where it would write non-zero 'usercompr'
258 fields. Deal with it. */
259 if ((comprtype
& 0xff) <= JFFS2_COMPR_ZLIB
)
262 switch (comprtype
& 0xff) {
263 case JFFS2_COMPR_NONE
:
264 /* This should be special-cased elsewhere, but we might as well deal with it */
265 memcpy(data_out
, cdata_in
, datalen
);
266 none_stat_decompr_blocks
++;
268 case JFFS2_COMPR_ZERO
:
269 memset(data_out
, 0, datalen
);
272 spin_lock(&jffs2_compressor_list_lock
);
273 list_for_each_entry(this, &jffs2_compressor_list
, list
) {
274 if (comprtype
== this->compr
) {
276 spin_unlock(&jffs2_compressor_list_lock
);
277 ret
= this->decompress(cdata_in
, data_out
, cdatalen
, datalen
);
278 spin_lock(&jffs2_compressor_list_lock
);
280 printk(KERN_WARNING
"Decompressor \"%s\" returned %d\n", this->name
, ret
);
283 this->stat_decompr_blocks
++;
286 spin_unlock(&jffs2_compressor_list_lock
);
290 printk(KERN_WARNING
"JFFS2 compression type 0x%02x not available.\n", comprtype
);
291 spin_unlock(&jffs2_compressor_list_lock
);
297 int jffs2_register_compressor(struct jffs2_compressor
*comp
)
299 struct jffs2_compressor
*this;
302 printk(KERN_WARNING
"NULL compressor name at registering JFFS2 compressor. Failed.\n");
305 comp
->compr_buf_size
=0;
306 comp
->compr_buf
=NULL
;
308 comp
->stat_compr_orig_size
=0;
309 comp
->stat_compr_new_size
=0;
310 comp
->stat_compr_blocks
=0;
311 comp
->stat_decompr_blocks
=0;
312 D1(printk(KERN_DEBUG
"Registering JFFS2 compressor \"%s\"\n", comp
->name
));
314 spin_lock(&jffs2_compressor_list_lock
);
316 list_for_each_entry(this, &jffs2_compressor_list
, list
) {
317 if (this->priority
< comp
->priority
) {
318 list_add(&comp
->list
, this->list
.prev
);
322 list_add_tail(&comp
->list
, &jffs2_compressor_list
);
324 D2(list_for_each_entry(this, &jffs2_compressor_list
, list
) {
325 printk(KERN_DEBUG
"Compressor \"%s\", prio %d\n", this->name
, this->priority
);
328 spin_unlock(&jffs2_compressor_list_lock
);
333 int jffs2_unregister_compressor(struct jffs2_compressor
*comp
)
335 D2(struct jffs2_compressor
*this;)
337 D1(printk(KERN_DEBUG
"Unregistering JFFS2 compressor \"%s\"\n", comp
->name
));
339 spin_lock(&jffs2_compressor_list_lock
);
341 if (comp
->usecount
) {
342 spin_unlock(&jffs2_compressor_list_lock
);
343 printk(KERN_WARNING
"JFFS2: Compressor modul is in use. Unregister failed.\n");
346 list_del(&comp
->list
);
348 D2(list_for_each_entry(this, &jffs2_compressor_list
, list
) {
349 printk(KERN_DEBUG
"Compressor \"%s\", prio %d\n", this->name
, this->priority
);
351 spin_unlock(&jffs2_compressor_list_lock
);
355 void jffs2_free_comprbuf(unsigned char *comprbuf
, unsigned char *orig
)
357 if (orig
!= comprbuf
)
361 int __init
jffs2_compressors_init(void)
363 /* Registering compressors */
364 #ifdef CONFIG_JFFS2_ZLIB
367 #ifdef CONFIG_JFFS2_RTIME
370 #ifdef CONFIG_JFFS2_RUBIN
371 jffs2_rubinmips_init();
372 jffs2_dynrubin_init();
374 #ifdef CONFIG_JFFS2_LZO
377 /* Setting default compression mode */
378 #ifdef CONFIG_JFFS2_CMODE_NONE
379 jffs2_compression_mode
= JFFS2_COMPR_MODE_NONE
;
380 D1(printk(KERN_INFO
"JFFS2: default compression mode: none\n");)
382 #ifdef CONFIG_JFFS2_CMODE_SIZE
383 jffs2_compression_mode
= JFFS2_COMPR_MODE_SIZE
;
384 D1(printk(KERN_INFO
"JFFS2: default compression mode: size\n");)
386 #ifdef CONFIG_JFFS2_CMODE_FAVOURLZO
387 jffs2_compression_mode
= JFFS2_COMPR_MODE_FAVOURLZO
;
388 D1(printk(KERN_INFO
"JFFS2: default compression mode: favourlzo\n");)
390 D1(printk(KERN_INFO
"JFFS2: default compression mode: priority\n");)
397 int jffs2_compressors_exit(void)
399 /* Unregistering compressors */
400 #ifdef CONFIG_JFFS2_LZO
403 #ifdef CONFIG_JFFS2_RUBIN
404 jffs2_dynrubin_exit();
405 jffs2_rubinmips_exit();
407 #ifdef CONFIG_JFFS2_RTIME
410 #ifdef CONFIG_JFFS2_ZLIB