aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@openedhand.com>2007-07-10 05:28:42 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2007-07-11 10:04:38 -0400
commit3b23c1f5fa7e4c99e9451958a1004ef7434a71f0 (patch)
tree2442c774918a422dee47b44d92515fcfb1897f35
parentc799aca31bfe61ba3a91133acf5a13a0773087d4 (diff)
[JFFS2] Add a "favourlzo" compression mode
Add a "favourlzo" compression mode to jffs2 which tries to optimise by size but gives lzo an advantage when comparing sizes. This means the faster lzo algorithm can be preferred when there isn't much difference in compressed size (the exact threshold can be changed). Signed-off-by: Richard Purdie <rpurdie@openedhand.com> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r--fs/Kconfig7
-rw-r--r--fs/jffs2/compr.c45
-rw-r--r--fs/jffs2/compr.h3
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
1367config 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
1367endchoice 1374endchoice
1368 1375
1369config CRAMFS 1376config 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 */
25static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_compr_size=0; 25static 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 */
31static 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
42struct jffs2_compressor { 45struct jffs2_compressor {
43 struct list_head list; 46 struct list_head list;