diff options
-rw-r--r-- | fs/Kconfig | 7 | ||||
-rw-r--r-- | fs/jffs2/compr.c | 45 | ||||
-rw-r--r-- | fs/jffs2/compr.h | 3 |
3 files changed, 50 insertions, 5 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index a2ec0b375dff..42cfb7dc95b5 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -1364,6 +1364,13 @@ config JFFS2_CMODE_SIZE | |||
1364 | Tries all compressors and chooses the one which has the smallest | 1364 | Tries all compressors and chooses the one which has the smallest |
1365 | result. | 1365 | result. |
1366 | 1366 | ||
1367 | config JFFS2_CMODE_FAVOURLZO | ||
1368 | bool "Favour LZO" | ||
1369 | help | ||
1370 | Tries all compressors and chooses the one which has the smallest | ||
1371 | result but gives some preference to LZO (which has faster | ||
1372 | decompression) at the expense of size. | ||
1373 | |||
1367 | endchoice | 1374 | endchoice |
1368 | 1375 | ||
1369 | config CRAMFS | 1376 | config CRAMFS |
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c index bcc28d266a12..86739ee53b37 100644 --- a/fs/jffs2/compr.c +++ b/fs/jffs2/compr.c | |||
@@ -24,6 +24,34 @@ static int jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY; | |||
24 | /* Statistics for blocks stored without compression */ | 24 | /* Statistics for blocks stored without compression */ |
25 | static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_compr_size=0; | 25 | static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_compr_size=0; |
26 | 26 | ||
27 | |||
28 | /* | ||
29 | * Return 1 to use this compression | ||
30 | */ | ||
31 | static int jffs2_is_best_compression(struct jffs2_compressor *this, | ||
32 | struct jffs2_compressor *best, uint32_t size, uint32_t bestsize) | ||
33 | { | ||
34 | switch (jffs2_compression_mode) { | ||
35 | case JFFS2_COMPR_MODE_SIZE: | ||
36 | if (bestsize > size) | ||
37 | return 1; | ||
38 | return 0; | ||
39 | case JFFS2_COMPR_MODE_FAVOURLZO: | ||
40 | if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > size)) | ||
41 | return 1; | ||
42 | if ((best->compr != JFFS2_COMPR_LZO) && (bestsize > size)) | ||
43 | return 1; | ||
44 | if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > (size * FAVOUR_LZO_PERCENT / 100))) | ||
45 | return 1; | ||
46 | if ((bestsize * FAVOUR_LZO_PERCENT / 100) > size) | ||
47 | return 1; | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | /* Shouldn't happen */ | ||
52 | return 0; | ||
53 | } | ||
54 | |||
27 | /* jffs2_compress: | 55 | /* jffs2_compress: |
28 | * @data: Pointer to uncompressed data | 56 | * @data: Pointer to uncompressed data |
29 | * @cdata: Pointer to returned pointer to buffer for compressed data | 57 | * @cdata: Pointer to returned pointer to buffer for compressed data |
@@ -90,6 +118,7 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
90 | kfree(output_buf); | 118 | kfree(output_buf); |
91 | break; | 119 | break; |
92 | case JFFS2_COMPR_MODE_SIZE: | 120 | case JFFS2_COMPR_MODE_SIZE: |
121 | case JFFS2_COMPR_MODE_FAVOURLZO: | ||
93 | orig_slen = *datalen; | 122 | orig_slen = *datalen; |
94 | orig_dlen = *cdatalen; | 123 | orig_dlen = *cdatalen; |
95 | spin_lock(&jffs2_compressor_list_lock); | 124 | spin_lock(&jffs2_compressor_list_lock); |
@@ -98,7 +127,7 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
98 | if ((!this->compress)||(this->disabled)) | 127 | if ((!this->compress)||(this->disabled)) |
99 | continue; | 128 | continue; |
100 | /* Allocating memory for output buffer if necessary */ | 129 | /* Allocating memory for output buffer if necessary */ |
101 | if ((this->compr_buf_size<orig_dlen)&&(this->compr_buf)) { | 130 | if ((this->compr_buf_size < orig_slen) && (this->compr_buf)) { |
102 | spin_unlock(&jffs2_compressor_list_lock); | 131 | spin_unlock(&jffs2_compressor_list_lock); |
103 | kfree(this->compr_buf); | 132 | kfree(this->compr_buf); |
104 | spin_lock(&jffs2_compressor_list_lock); | 133 | spin_lock(&jffs2_compressor_list_lock); |
@@ -107,15 +136,15 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
107 | } | 136 | } |
108 | if (!this->compr_buf) { | 137 | if (!this->compr_buf) { |
109 | spin_unlock(&jffs2_compressor_list_lock); | 138 | spin_unlock(&jffs2_compressor_list_lock); |
110 | tmp_buf = kmalloc(orig_dlen,GFP_KERNEL); | 139 | tmp_buf = kmalloc(orig_slen, GFP_KERNEL); |
111 | spin_lock(&jffs2_compressor_list_lock); | 140 | spin_lock(&jffs2_compressor_list_lock); |
112 | if (!tmp_buf) { | 141 | if (!tmp_buf) { |
113 | printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n",orig_dlen); | 142 | printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n", orig_slen); |
114 | continue; | 143 | continue; |
115 | } | 144 | } |
116 | else { | 145 | else { |
117 | this->compr_buf = tmp_buf; | 146 | this->compr_buf = tmp_buf; |
118 | this->compr_buf_size = orig_dlen; | 147 | this->compr_buf_size = orig_slen; |
119 | } | 148 | } |
120 | } | 149 | } |
121 | this->usecount++; | 150 | this->usecount++; |
@@ -126,7 +155,8 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
126 | spin_lock(&jffs2_compressor_list_lock); | 155 | spin_lock(&jffs2_compressor_list_lock); |
127 | this->usecount--; | 156 | this->usecount--; |
128 | if (!compr_ret) { | 157 | if (!compr_ret) { |
129 | if ((!best_dlen)||(best_dlen>*cdatalen)) { | 158 | if (((!best_dlen) || jffs2_is_best_compression(this, best, *cdatalen, best_dlen)) |
159 | && (*cdatalen < *datalen)) { | ||
130 | best_dlen = *cdatalen; | 160 | best_dlen = *cdatalen; |
131 | best_slen = *datalen; | 161 | best_slen = *datalen; |
132 | best = this; | 162 | best = this; |
@@ -298,9 +328,14 @@ int __init jffs2_compressors_init(void) | |||
298 | jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; | 328 | jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; |
299 | D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");) | 329 | D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");) |
300 | #else | 330 | #else |
331 | #ifdef CONFIG_JFFS2_CMODE_FAVOURLZO | ||
332 | jffs2_compression_mode = JFFS2_COMPR_MODE_FAVOURLZO; | ||
333 | D1(printk(KERN_INFO "JFFS2: default compression mode: favourlzo\n");) | ||
334 | #else | ||
301 | D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");) | 335 | D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");) |
302 | #endif | 336 | #endif |
303 | #endif | 337 | #endif |
338 | #endif | ||
304 | return 0; | 339 | return 0; |
305 | } | 340 | } |
306 | 341 | ||
diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h index a54828a4e9c6..e1b7efb70aa4 100644 --- a/fs/jffs2/compr.h +++ b/fs/jffs2/compr.h | |||
@@ -38,6 +38,9 @@ | |||
38 | #define JFFS2_COMPR_MODE_NONE 0 | 38 | #define JFFS2_COMPR_MODE_NONE 0 |
39 | #define JFFS2_COMPR_MODE_PRIORITY 1 | 39 | #define JFFS2_COMPR_MODE_PRIORITY 1 |
40 | #define JFFS2_COMPR_MODE_SIZE 2 | 40 | #define JFFS2_COMPR_MODE_SIZE 2 |
41 | #define JFFS2_COMPR_MODE_FAVOURLZO 3 | ||
42 | |||
43 | #define FAVOUR_LZO_PERCENT 80 | ||
41 | 44 | ||
42 | struct jffs2_compressor { | 45 | struct jffs2_compressor { |
43 | struct list_head list; | 46 | struct list_head list; |