summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@openedhand.com>2007-07-10 16:03:47 +0100
committerJosh Boyer <jwboyer@gmail.com>2007-07-23 08:11:52 -0500
commit826c6adca21edd413ea32126be25ecf22cc13417 (patch)
tree8b476d2e61e5b6b8c3fcc255cb4f3078450c366c
parent82f09a8b4e214e51c394ed9ff8882d1e736e205b (diff)
Add favourlzo compression mode
Add a favourlzo compression mode to mtd-utils This allows lzo compression to be used in the cases where the compression ratio isn't quite as good zlib. This can make sense in certain use cases because LZO decompression is much faster than zlib. Signed-off-by: Richard Purdie <rpurdie@openedhand.com> Signed-off-by: Josh Boyer <jwboyer@gmail.com>
-rw-r--r--compr.c52
-rw-r--r--compr.h1
2 files changed, 50 insertions, 3 deletions
diff --git a/compr.c b/compr.c
index 5b5d145..7ad0c41 100644
--- a/compr.c
+++ b/compr.c
@@ -16,6 +16,8 @@
#include <stdlib.h>
#include <linux/jffs2.h>
+#define FAVOUR_LZO_PERCENT 80
+
extern int page_size;
/* LIST IMPLEMENTATION (from linux/list.h) */
@@ -166,6 +168,33 @@ static void jffs2_decompression_test(struct jffs2_compressor *compr,
}
}
+/*
+ * Return 1 to use this compression
+ */
+static int jffs2_is_best_compression(struct jffs2_compressor *this,
+ struct jffs2_compressor *best, uint32_t size, uint32_t bestsize)
+{
+ switch (jffs2_compression_mode) {
+ case JFFS2_COMPR_MODE_SIZE:
+ if (bestsize > size)
+ return 1;
+ return 0;
+ case JFFS2_COMPR_MODE_FAVOURLZO:
+ if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > size))
+ return 1;
+ if ((best->compr != JFFS2_COMPR_LZO) && (bestsize > size))
+ return 1;
+ if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > (size * FAVOUR_LZO_PERCENT / 100)))
+ return 1;
+ if ((bestsize * FAVOUR_LZO_PERCENT / 100) > size)
+ return 1;
+
+ return 0;
+ }
+ /* Shouldn't happen */
+ return 0;
+}
+
/* jffs2_compress:
* @data: Pointer to uncompressed data
* @cdata: Pointer to returned pointer to buffer for compressed data
@@ -231,21 +260,29 @@ uint16_t jffs2_compress( unsigned char *data_in, unsigned char **cpage_out,
}
if (ret == JFFS2_COMPR_NONE) free(output_buf);
break;
+ case JFFS2_COMPR_MODE_FAVOURLZO:
case JFFS2_COMPR_MODE_SIZE:
orig_slen = *datalen;
orig_dlen = *cdatalen;
list_for_each_entry(this, &jffs2_compressor_list, list) {
+ uint32_t needed_buf_size;
+
+ if (jffs2_compression_mode == JFFS2_COMPR_MODE_FAVOURLZO)
+ needed_buf_size = orig_slen + jffs2_compression_check;
+ else
+ needed_buf_size = orig_dlen + jffs2_compression_check;
+
/* Skip decompress-only backwards-compatibility and disabled modules */
if ((!this->compress)||(this->disabled))
continue;
/* Allocating memory for output buffer if necessary */
- if ((this->compr_buf_size<orig_dlen+jffs2_compression_check)&&(this->compr_buf)) {
+ if ((this->compr_buf_size < needed_buf_size) && (this->compr_buf)) {
free(this->compr_buf);
this->compr_buf_size=0;
this->compr_buf=NULL;
}
if (!this->compr_buf) {
- tmp_buf = malloc(orig_dlen+jffs2_compression_check);
+ tmp_buf = malloc(needed_buf_size);
if (!tmp_buf) {
fprintf(stderr,"mkfs.jffs2: No memory for compressor allocation. (%d bytes)\n",orig_dlen);
continue;
@@ -265,7 +302,8 @@ uint16_t jffs2_compress( unsigned char *data_in, unsigned char **cpage_out,
if (!compr_ret) {
if (jffs2_compression_check)
jffs2_decompression_test(this, data_in, this->compr_buf, *cdatalen, *datalen, this->compr_buf_size);
- if ((!best_dlen)||(best_dlen>*cdatalen)) {
+ if (((!best_dlen) || jffs2_is_best_compression(this, best, *cdatalen, best_dlen))
+ && (*cdatalen < *datalen)) {
best_dlen = *cdatalen;
best_slen = *datalen;
best = this;
@@ -377,6 +415,9 @@ char *jffs2_stats(void)
case JFFS2_COMPR_MODE_SIZE:
act_buf += sprintf(act_buf,"size");
break;
+ case JFFS2_COMPR_MODE_FAVOURLZO:
+ act_buf += sprintf(act_buf, "favourlzo");
+ break;
default:
act_buf += sprintf(act_buf,"unkown");
break;
@@ -413,6 +454,11 @@ int jffs2_set_compression_mode_name(const char *name)
jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE;
return 0;
}
+ if (!strcmp("favourlzo", name)) {
+ jffs2_compression_mode = JFFS2_COMPR_MODE_FAVOURLZO;
+ return 0;
+ }
+
return 1;
}
diff --git a/compr.h b/compr.h
index 597e3c8..c4e199a 100644
--- a/compr.h
+++ b/compr.h
@@ -32,6 +32,7 @@
#define JFFS2_COMPR_MODE_NONE 0
#define JFFS2_COMPR_MODE_PRIORITY 1
#define JFFS2_COMPR_MODE_SIZE 2
+#define JFFS2_COMPR_MODE_FAVOURLZO 3
#define kmalloc(a,b) malloc(a)
#define kfree(a) free(a)