summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)