162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * JFFS2 -- Journalling Flash File System, Version 2. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright © 2001-2007 Red Hat, Inc. 562306a36Sopenharmony_ci * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org> 662306a36Sopenharmony_ci * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, 762306a36Sopenharmony_ci * University of Szeged, Hungary 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Created by Arjan van de Ven <arjan@infradead.org> 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * For licensing information, see the file 'LICENCE' in this directory. 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include "compr.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistatic DEFINE_SPINLOCK(jffs2_compressor_list_lock); 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* Available compressors are on this list */ 2262306a36Sopenharmony_cistatic LIST_HEAD(jffs2_compressor_list); 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci/* Actual compression mode */ 2562306a36Sopenharmony_cistatic int jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* Statistics for blocks stored without compression */ 2862306a36Sopenharmony_cistatic uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_compr_size=0; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* 3262306a36Sopenharmony_ci * Return 1 to use this compression 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_cistatic int jffs2_is_best_compression(struct jffs2_compressor *this, 3562306a36Sopenharmony_ci struct jffs2_compressor *best, uint32_t size, uint32_t bestsize) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci switch (jffs2_compression_mode) { 3862306a36Sopenharmony_ci case JFFS2_COMPR_MODE_SIZE: 3962306a36Sopenharmony_ci if (bestsize > size) 4062306a36Sopenharmony_ci return 1; 4162306a36Sopenharmony_ci return 0; 4262306a36Sopenharmony_ci case JFFS2_COMPR_MODE_FAVOURLZO: 4362306a36Sopenharmony_ci if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > size)) 4462306a36Sopenharmony_ci return 1; 4562306a36Sopenharmony_ci if ((best->compr != JFFS2_COMPR_LZO) && (bestsize > size)) 4662306a36Sopenharmony_ci return 1; 4762306a36Sopenharmony_ci if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > (size * FAVOUR_LZO_PERCENT / 100))) 4862306a36Sopenharmony_ci return 1; 4962306a36Sopenharmony_ci if ((bestsize * FAVOUR_LZO_PERCENT / 100) > size) 5062306a36Sopenharmony_ci return 1; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci return 0; 5362306a36Sopenharmony_ci } 5462306a36Sopenharmony_ci /* Shouldn't happen */ 5562306a36Sopenharmony_ci return 0; 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci/* 5962306a36Sopenharmony_ci * jffs2_selected_compress: 6062306a36Sopenharmony_ci * @compr: Explicit compression type to use (ie, JFFS2_COMPR_ZLIB). 6162306a36Sopenharmony_ci * If 0, just take the first available compression mode. 6262306a36Sopenharmony_ci * @data_in: Pointer to uncompressed data 6362306a36Sopenharmony_ci * @cpage_out: Pointer to returned pointer to buffer for compressed data 6462306a36Sopenharmony_ci * @datalen: On entry, holds the amount of data available for compression. 6562306a36Sopenharmony_ci * On exit, expected to hold the amount of data actually compressed. 6662306a36Sopenharmony_ci * @cdatalen: On entry, holds the amount of space available for compressed 6762306a36Sopenharmony_ci * data. On exit, expected to hold the actual size of the compressed 6862306a36Sopenharmony_ci * data. 6962306a36Sopenharmony_ci * 7062306a36Sopenharmony_ci * Returns: the compression type used. Zero is used to show that the data 7162306a36Sopenharmony_ci * could not be compressed; probably because we couldn't find the requested 7262306a36Sopenharmony_ci * compression mode. 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_cistatic int jffs2_selected_compress(u8 compr, unsigned char *data_in, 7562306a36Sopenharmony_ci unsigned char **cpage_out, u32 *datalen, u32 *cdatalen) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci struct jffs2_compressor *this; 7862306a36Sopenharmony_ci int err, ret = JFFS2_COMPR_NONE; 7962306a36Sopenharmony_ci uint32_t orig_slen, orig_dlen; 8062306a36Sopenharmony_ci char *output_buf; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci output_buf = kmalloc(*cdatalen, GFP_KERNEL); 8362306a36Sopenharmony_ci if (!output_buf) { 8462306a36Sopenharmony_ci pr_warn("No memory for compressor allocation. Compression failed.\n"); 8562306a36Sopenharmony_ci return ret; 8662306a36Sopenharmony_ci } 8762306a36Sopenharmony_ci orig_slen = *datalen; 8862306a36Sopenharmony_ci orig_dlen = *cdatalen; 8962306a36Sopenharmony_ci spin_lock(&jffs2_compressor_list_lock); 9062306a36Sopenharmony_ci list_for_each_entry(this, &jffs2_compressor_list, list) { 9162306a36Sopenharmony_ci /* Skip decompress-only and disabled modules */ 9262306a36Sopenharmony_ci if (!this->compress || this->disabled) 9362306a36Sopenharmony_ci continue; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci /* Skip if not the desired compression type */ 9662306a36Sopenharmony_ci if (compr && (compr != this->compr)) 9762306a36Sopenharmony_ci continue; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci /* 10062306a36Sopenharmony_ci * Either compression type was unspecified, or we found our 10162306a36Sopenharmony_ci * compressor; either way, we're good to go. 10262306a36Sopenharmony_ci */ 10362306a36Sopenharmony_ci this->usecount++; 10462306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci *datalen = orig_slen; 10762306a36Sopenharmony_ci *cdatalen = orig_dlen; 10862306a36Sopenharmony_ci err = this->compress(data_in, output_buf, datalen, cdatalen); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci spin_lock(&jffs2_compressor_list_lock); 11162306a36Sopenharmony_ci this->usecount--; 11262306a36Sopenharmony_ci if (!err) { 11362306a36Sopenharmony_ci /* Success */ 11462306a36Sopenharmony_ci ret = this->compr; 11562306a36Sopenharmony_ci this->stat_compr_blocks++; 11662306a36Sopenharmony_ci this->stat_compr_orig_size += *datalen; 11762306a36Sopenharmony_ci this->stat_compr_new_size += *cdatalen; 11862306a36Sopenharmony_ci break; 11962306a36Sopenharmony_ci } 12062306a36Sopenharmony_ci } 12162306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 12262306a36Sopenharmony_ci if (ret == JFFS2_COMPR_NONE) 12362306a36Sopenharmony_ci kfree(output_buf); 12462306a36Sopenharmony_ci else 12562306a36Sopenharmony_ci *cpage_out = output_buf; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci return ret; 12862306a36Sopenharmony_ci} 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci/* jffs2_compress: 13162306a36Sopenharmony_ci * @data_in: Pointer to uncompressed data 13262306a36Sopenharmony_ci * @cpage_out: Pointer to returned pointer to buffer for compressed data 13362306a36Sopenharmony_ci * @datalen: On entry, holds the amount of data available for compression. 13462306a36Sopenharmony_ci * On exit, expected to hold the amount of data actually compressed. 13562306a36Sopenharmony_ci * @cdatalen: On entry, holds the amount of space available for compressed 13662306a36Sopenharmony_ci * data. On exit, expected to hold the actual size of the compressed 13762306a36Sopenharmony_ci * data. 13862306a36Sopenharmony_ci * 13962306a36Sopenharmony_ci * Returns: Lower byte to be stored with data indicating compression type used. 14062306a36Sopenharmony_ci * Zero is used to show that the data could not be compressed - the 14162306a36Sopenharmony_ci * compressed version was actually larger than the original. 14262306a36Sopenharmony_ci * Upper byte will be used later. (soon) 14362306a36Sopenharmony_ci * 14462306a36Sopenharmony_ci * If the cdata buffer isn't large enough to hold all the uncompressed data, 14562306a36Sopenharmony_ci * jffs2_compress should compress as much as will fit, and should set 14662306a36Sopenharmony_ci * *datalen accordingly to show the amount of data which were compressed. 14762306a36Sopenharmony_ci */ 14862306a36Sopenharmony_ciuint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 14962306a36Sopenharmony_ci unsigned char *data_in, unsigned char **cpage_out, 15062306a36Sopenharmony_ci uint32_t *datalen, uint32_t *cdatalen) 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci int ret = JFFS2_COMPR_NONE; 15362306a36Sopenharmony_ci int mode, compr_ret; 15462306a36Sopenharmony_ci struct jffs2_compressor *this, *best=NULL; 15562306a36Sopenharmony_ci unsigned char *output_buf = NULL, *tmp_buf; 15662306a36Sopenharmony_ci uint32_t orig_slen, orig_dlen; 15762306a36Sopenharmony_ci uint32_t best_slen=0, best_dlen=0; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci if (c->mount_opts.override_compr) 16062306a36Sopenharmony_ci mode = c->mount_opts.compr; 16162306a36Sopenharmony_ci else 16262306a36Sopenharmony_ci mode = jffs2_compression_mode; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci switch (mode) { 16562306a36Sopenharmony_ci case JFFS2_COMPR_MODE_NONE: 16662306a36Sopenharmony_ci break; 16762306a36Sopenharmony_ci case JFFS2_COMPR_MODE_PRIORITY: 16862306a36Sopenharmony_ci ret = jffs2_selected_compress(0, data_in, cpage_out, datalen, 16962306a36Sopenharmony_ci cdatalen); 17062306a36Sopenharmony_ci break; 17162306a36Sopenharmony_ci case JFFS2_COMPR_MODE_SIZE: 17262306a36Sopenharmony_ci case JFFS2_COMPR_MODE_FAVOURLZO: 17362306a36Sopenharmony_ci orig_slen = *datalen; 17462306a36Sopenharmony_ci orig_dlen = *cdatalen; 17562306a36Sopenharmony_ci spin_lock(&jffs2_compressor_list_lock); 17662306a36Sopenharmony_ci list_for_each_entry(this, &jffs2_compressor_list, list) { 17762306a36Sopenharmony_ci /* Skip decompress-only backwards-compatibility and disabled modules */ 17862306a36Sopenharmony_ci if ((!this->compress)||(this->disabled)) 17962306a36Sopenharmony_ci continue; 18062306a36Sopenharmony_ci /* Allocating memory for output buffer if necessary */ 18162306a36Sopenharmony_ci if ((this->compr_buf_size < orig_slen) && (this->compr_buf)) { 18262306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 18362306a36Sopenharmony_ci kfree(this->compr_buf); 18462306a36Sopenharmony_ci spin_lock(&jffs2_compressor_list_lock); 18562306a36Sopenharmony_ci this->compr_buf_size=0; 18662306a36Sopenharmony_ci this->compr_buf=NULL; 18762306a36Sopenharmony_ci } 18862306a36Sopenharmony_ci if (!this->compr_buf) { 18962306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 19062306a36Sopenharmony_ci tmp_buf = kmalloc(orig_slen, GFP_KERNEL); 19162306a36Sopenharmony_ci spin_lock(&jffs2_compressor_list_lock); 19262306a36Sopenharmony_ci if (!tmp_buf) { 19362306a36Sopenharmony_ci pr_warn("No memory for compressor allocation. (%d bytes)\n", 19462306a36Sopenharmony_ci orig_slen); 19562306a36Sopenharmony_ci continue; 19662306a36Sopenharmony_ci } 19762306a36Sopenharmony_ci else { 19862306a36Sopenharmony_ci this->compr_buf = tmp_buf; 19962306a36Sopenharmony_ci this->compr_buf_size = orig_slen; 20062306a36Sopenharmony_ci } 20162306a36Sopenharmony_ci } 20262306a36Sopenharmony_ci this->usecount++; 20362306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 20462306a36Sopenharmony_ci *datalen = orig_slen; 20562306a36Sopenharmony_ci *cdatalen = orig_dlen; 20662306a36Sopenharmony_ci compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen); 20762306a36Sopenharmony_ci spin_lock(&jffs2_compressor_list_lock); 20862306a36Sopenharmony_ci this->usecount--; 20962306a36Sopenharmony_ci if (!compr_ret) { 21062306a36Sopenharmony_ci if (((!best_dlen) || jffs2_is_best_compression(this, best, *cdatalen, best_dlen)) 21162306a36Sopenharmony_ci && (*cdatalen < *datalen)) { 21262306a36Sopenharmony_ci best_dlen = *cdatalen; 21362306a36Sopenharmony_ci best_slen = *datalen; 21462306a36Sopenharmony_ci best = this; 21562306a36Sopenharmony_ci } 21662306a36Sopenharmony_ci } 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci if (best_dlen) { 21962306a36Sopenharmony_ci *cdatalen = best_dlen; 22062306a36Sopenharmony_ci *datalen = best_slen; 22162306a36Sopenharmony_ci output_buf = best->compr_buf; 22262306a36Sopenharmony_ci best->compr_buf = NULL; 22362306a36Sopenharmony_ci best->compr_buf_size = 0; 22462306a36Sopenharmony_ci best->stat_compr_blocks++; 22562306a36Sopenharmony_ci best->stat_compr_orig_size += best_slen; 22662306a36Sopenharmony_ci best->stat_compr_new_size += best_dlen; 22762306a36Sopenharmony_ci ret = best->compr; 22862306a36Sopenharmony_ci *cpage_out = output_buf; 22962306a36Sopenharmony_ci } 23062306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 23162306a36Sopenharmony_ci break; 23262306a36Sopenharmony_ci case JFFS2_COMPR_MODE_FORCELZO: 23362306a36Sopenharmony_ci ret = jffs2_selected_compress(JFFS2_COMPR_LZO, data_in, 23462306a36Sopenharmony_ci cpage_out, datalen, cdatalen); 23562306a36Sopenharmony_ci break; 23662306a36Sopenharmony_ci case JFFS2_COMPR_MODE_FORCEZLIB: 23762306a36Sopenharmony_ci ret = jffs2_selected_compress(JFFS2_COMPR_ZLIB, data_in, 23862306a36Sopenharmony_ci cpage_out, datalen, cdatalen); 23962306a36Sopenharmony_ci break; 24062306a36Sopenharmony_ci default: 24162306a36Sopenharmony_ci pr_err("unknown compression mode\n"); 24262306a36Sopenharmony_ci } 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci if (ret == JFFS2_COMPR_NONE) { 24562306a36Sopenharmony_ci *cpage_out = data_in; 24662306a36Sopenharmony_ci *datalen = *cdatalen; 24762306a36Sopenharmony_ci none_stat_compr_blocks++; 24862306a36Sopenharmony_ci none_stat_compr_size += *datalen; 24962306a36Sopenharmony_ci } 25062306a36Sopenharmony_ci return ret; 25162306a36Sopenharmony_ci} 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ciint jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 25462306a36Sopenharmony_ci uint16_t comprtype, unsigned char *cdata_in, 25562306a36Sopenharmony_ci unsigned char *data_out, uint32_t cdatalen, uint32_t datalen) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci struct jffs2_compressor *this; 25862306a36Sopenharmony_ci int ret; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci /* Older code had a bug where it would write non-zero 'usercompr' 26162306a36Sopenharmony_ci fields. Deal with it. */ 26262306a36Sopenharmony_ci if ((comprtype & 0xff) <= JFFS2_COMPR_ZLIB) 26362306a36Sopenharmony_ci comprtype &= 0xff; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci switch (comprtype & 0xff) { 26662306a36Sopenharmony_ci case JFFS2_COMPR_NONE: 26762306a36Sopenharmony_ci /* This should be special-cased elsewhere, but we might as well deal with it */ 26862306a36Sopenharmony_ci memcpy(data_out, cdata_in, datalen); 26962306a36Sopenharmony_ci none_stat_decompr_blocks++; 27062306a36Sopenharmony_ci break; 27162306a36Sopenharmony_ci case JFFS2_COMPR_ZERO: 27262306a36Sopenharmony_ci memset(data_out, 0, datalen); 27362306a36Sopenharmony_ci break; 27462306a36Sopenharmony_ci default: 27562306a36Sopenharmony_ci spin_lock(&jffs2_compressor_list_lock); 27662306a36Sopenharmony_ci list_for_each_entry(this, &jffs2_compressor_list, list) { 27762306a36Sopenharmony_ci if (comprtype == this->compr) { 27862306a36Sopenharmony_ci this->usecount++; 27962306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 28062306a36Sopenharmony_ci ret = this->decompress(cdata_in, data_out, cdatalen, datalen); 28162306a36Sopenharmony_ci spin_lock(&jffs2_compressor_list_lock); 28262306a36Sopenharmony_ci if (ret) { 28362306a36Sopenharmony_ci pr_warn("Decompressor \"%s\" returned %d\n", 28462306a36Sopenharmony_ci this->name, ret); 28562306a36Sopenharmony_ci } 28662306a36Sopenharmony_ci else { 28762306a36Sopenharmony_ci this->stat_decompr_blocks++; 28862306a36Sopenharmony_ci } 28962306a36Sopenharmony_ci this->usecount--; 29062306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 29162306a36Sopenharmony_ci return ret; 29262306a36Sopenharmony_ci } 29362306a36Sopenharmony_ci } 29462306a36Sopenharmony_ci pr_warn("compression type 0x%02x not available\n", comprtype); 29562306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 29662306a36Sopenharmony_ci return -EIO; 29762306a36Sopenharmony_ci } 29862306a36Sopenharmony_ci return 0; 29962306a36Sopenharmony_ci} 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ciint jffs2_register_compressor(struct jffs2_compressor *comp) 30262306a36Sopenharmony_ci{ 30362306a36Sopenharmony_ci struct jffs2_compressor *this; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci if (!comp->name) { 30662306a36Sopenharmony_ci pr_warn("NULL compressor name at registering JFFS2 compressor. Failed.\n"); 30762306a36Sopenharmony_ci return -1; 30862306a36Sopenharmony_ci } 30962306a36Sopenharmony_ci comp->compr_buf_size=0; 31062306a36Sopenharmony_ci comp->compr_buf=NULL; 31162306a36Sopenharmony_ci comp->usecount=0; 31262306a36Sopenharmony_ci comp->stat_compr_orig_size=0; 31362306a36Sopenharmony_ci comp->stat_compr_new_size=0; 31462306a36Sopenharmony_ci comp->stat_compr_blocks=0; 31562306a36Sopenharmony_ci comp->stat_decompr_blocks=0; 31662306a36Sopenharmony_ci jffs2_dbg(1, "Registering JFFS2 compressor \"%s\"\n", comp->name); 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci spin_lock(&jffs2_compressor_list_lock); 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci list_for_each_entry(this, &jffs2_compressor_list, list) { 32162306a36Sopenharmony_ci if (this->priority < comp->priority) { 32262306a36Sopenharmony_ci list_add(&comp->list, this->list.prev); 32362306a36Sopenharmony_ci goto out; 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci } 32662306a36Sopenharmony_ci list_add_tail(&comp->list, &jffs2_compressor_list); 32762306a36Sopenharmony_ciout: 32862306a36Sopenharmony_ci D2(list_for_each_entry(this, &jffs2_compressor_list, list) { 32962306a36Sopenharmony_ci printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); 33062306a36Sopenharmony_ci }) 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci return 0; 33562306a36Sopenharmony_ci} 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ciint jffs2_unregister_compressor(struct jffs2_compressor *comp) 33862306a36Sopenharmony_ci{ 33962306a36Sopenharmony_ci D2(struct jffs2_compressor *this); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci jffs2_dbg(1, "Unregistering JFFS2 compressor \"%s\"\n", comp->name); 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci spin_lock(&jffs2_compressor_list_lock); 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci if (comp->usecount) { 34662306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 34762306a36Sopenharmony_ci pr_warn("Compressor module is in use. Unregister failed.\n"); 34862306a36Sopenharmony_ci return -1; 34962306a36Sopenharmony_ci } 35062306a36Sopenharmony_ci list_del(&comp->list); 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci D2(list_for_each_entry(this, &jffs2_compressor_list, list) { 35362306a36Sopenharmony_ci printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); 35462306a36Sopenharmony_ci }) 35562306a36Sopenharmony_ci spin_unlock(&jffs2_compressor_list_lock); 35662306a36Sopenharmony_ci return 0; 35762306a36Sopenharmony_ci} 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_civoid jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig) 36062306a36Sopenharmony_ci{ 36162306a36Sopenharmony_ci if (orig != comprbuf) 36262306a36Sopenharmony_ci kfree(comprbuf); 36362306a36Sopenharmony_ci} 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ciint __init jffs2_compressors_init(void) 36662306a36Sopenharmony_ci{ 36762306a36Sopenharmony_ci int ret = 0; 36862306a36Sopenharmony_ci/* Registering compressors */ 36962306a36Sopenharmony_ci ret = jffs2_zlib_init(); 37062306a36Sopenharmony_ci if (ret) 37162306a36Sopenharmony_ci goto exit; 37262306a36Sopenharmony_ci ret = jffs2_rtime_init(); 37362306a36Sopenharmony_ci if (ret) 37462306a36Sopenharmony_ci goto exit_zlib; 37562306a36Sopenharmony_ci ret = jffs2_rubinmips_init(); 37662306a36Sopenharmony_ci if (ret) 37762306a36Sopenharmony_ci goto exit_rtime; 37862306a36Sopenharmony_ci ret = jffs2_dynrubin_init(); 37962306a36Sopenharmony_ci if (ret) 38062306a36Sopenharmony_ci goto exit_runinmips; 38162306a36Sopenharmony_ci ret = jffs2_lzo_init(); 38262306a36Sopenharmony_ci if (ret) 38362306a36Sopenharmony_ci goto exit_dynrubin; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci/* Setting default compression mode */ 38762306a36Sopenharmony_ci#ifdef CONFIG_JFFS2_CMODE_NONE 38862306a36Sopenharmony_ci jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; 38962306a36Sopenharmony_ci jffs2_dbg(1, "default compression mode: none\n"); 39062306a36Sopenharmony_ci#else 39162306a36Sopenharmony_ci#ifdef CONFIG_JFFS2_CMODE_SIZE 39262306a36Sopenharmony_ci jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; 39362306a36Sopenharmony_ci jffs2_dbg(1, "default compression mode: size\n"); 39462306a36Sopenharmony_ci#else 39562306a36Sopenharmony_ci#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO 39662306a36Sopenharmony_ci jffs2_compression_mode = JFFS2_COMPR_MODE_FAVOURLZO; 39762306a36Sopenharmony_ci jffs2_dbg(1, "default compression mode: favourlzo\n"); 39862306a36Sopenharmony_ci#else 39962306a36Sopenharmony_ci jffs2_dbg(1, "default compression mode: priority\n"); 40062306a36Sopenharmony_ci#endif 40162306a36Sopenharmony_ci#endif 40262306a36Sopenharmony_ci#endif 40362306a36Sopenharmony_ci return 0; 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ciexit_dynrubin: 40662306a36Sopenharmony_ci jffs2_dynrubin_exit(); 40762306a36Sopenharmony_ciexit_runinmips: 40862306a36Sopenharmony_ci jffs2_rubinmips_exit(); 40962306a36Sopenharmony_ciexit_rtime: 41062306a36Sopenharmony_ci jffs2_rtime_exit(); 41162306a36Sopenharmony_ciexit_zlib: 41262306a36Sopenharmony_ci jffs2_zlib_exit(); 41362306a36Sopenharmony_ciexit: 41462306a36Sopenharmony_ci return ret; 41562306a36Sopenharmony_ci} 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ciint jffs2_compressors_exit(void) 41862306a36Sopenharmony_ci{ 41962306a36Sopenharmony_ci/* Unregistering compressors */ 42062306a36Sopenharmony_ci jffs2_lzo_exit(); 42162306a36Sopenharmony_ci jffs2_dynrubin_exit(); 42262306a36Sopenharmony_ci jffs2_rubinmips_exit(); 42362306a36Sopenharmony_ci jffs2_rtime_exit(); 42462306a36Sopenharmony_ci jffs2_zlib_exit(); 42562306a36Sopenharmony_ci return 0; 42662306a36Sopenharmony_ci} 427