aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/compr.c
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 /fs/jffs2/compr.c
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>
Diffstat (limited to 'fs/jffs2/compr.c')
-rw-r--r--fs/jffs2/compr.c45
1 files changed, 40 insertions, 5 deletions
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