diff options
Diffstat (limited to 'compr.c')
-rw-r--r-- | compr.c | 52 |
1 files changed, 49 insertions, 3 deletions
@@ -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; } |