diff options
Diffstat (limited to 'fs/jffs2/compr.c')
| -rw-r--r-- | fs/jffs2/compr.c | 158 | 
1 files changed, 108 insertions, 50 deletions
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c index de4247021d2..4849a4c9a0e 100644 --- a/fs/jffs2/compr.c +++ b/fs/jffs2/compr.c @@ -12,6 +12,8 @@   *   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include "compr.h"  static DEFINE_SPINLOCK(jffs2_compressor_list_lock); @@ -53,6 +55,78 @@ static int jffs2_is_best_compression(struct jffs2_compressor *this,  	return 0;  } +/* + * jffs2_selected_compress: + * @compr: Explicit compression type to use (ie, JFFS2_COMPR_ZLIB). + *	If 0, just take the first available compression mode. + * @data_in: Pointer to uncompressed data + * @cpage_out: Pointer to returned pointer to buffer for compressed data + * @datalen: On entry, holds the amount of data available for compression. + *	On exit, expected to hold the amount of data actually compressed. + * @cdatalen: On entry, holds the amount of space available for compressed + *	data. On exit, expected to hold the actual size of the compressed + *	data. + * + * Returns: the compression type used.  Zero is used to show that the data + * could not be compressed; probably because we couldn't find the requested + * compression mode. + */ +static int jffs2_selected_compress(u8 compr, unsigned char *data_in, +		unsigned char **cpage_out, u32 *datalen, u32 *cdatalen) +{ +	struct jffs2_compressor *this; +	int err, ret = JFFS2_COMPR_NONE; +	uint32_t orig_slen, orig_dlen; +	char *output_buf; + +	output_buf = kmalloc(*cdatalen, GFP_KERNEL); +	if (!output_buf) { +		pr_warn("No memory for compressor allocation. Compression failed.\n"); +		return ret; +	} +	orig_slen = *datalen; +	orig_dlen = *cdatalen; +	spin_lock(&jffs2_compressor_list_lock); +	list_for_each_entry(this, &jffs2_compressor_list, list) { +		/* Skip decompress-only and disabled modules */ +		if (!this->compress || this->disabled) +			continue; + +		/* Skip if not the desired compression type */ +		if (compr && (compr != this->compr)) +			continue; + +		/* +		 * Either compression type was unspecified, or we found our +		 * compressor; either way, we're good to go. +		 */ +		this->usecount++; +		spin_unlock(&jffs2_compressor_list_lock); + +		*datalen  = orig_slen; +		*cdatalen = orig_dlen; +		err = this->compress(data_in, output_buf, datalen, cdatalen); + +		spin_lock(&jffs2_compressor_list_lock); +		this->usecount--; +		if (!err) { +			/* Success */ +			ret = this->compr; +			this->stat_compr_blocks++; +			this->stat_compr_orig_size += *datalen; +			this->stat_compr_new_size += *cdatalen; +			break; +		} +	} +	spin_unlock(&jffs2_compressor_list_lock); +	if (ret == JFFS2_COMPR_NONE) +		kfree(output_buf); +	else +		*cpage_out = output_buf; + +	return ret; +} +  /* jffs2_compress:   * @data_in: Pointer to uncompressed data   * @cpage_out: Pointer to returned pointer to buffer for compressed data @@ -76,47 +150,23 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,  			uint32_t *datalen, uint32_t *cdatalen)  {  	int ret = JFFS2_COMPR_NONE; -	int compr_ret; +	int mode, compr_ret;  	struct jffs2_compressor *this, *best=NULL;  	unsigned char *output_buf = NULL, *tmp_buf;  	uint32_t orig_slen, orig_dlen;  	uint32_t best_slen=0, best_dlen=0; -	switch (jffs2_compression_mode) { +	if (c->mount_opts.override_compr) +		mode = c->mount_opts.compr; +	else +		mode = jffs2_compression_mode; + +	switch (mode) {  	case JFFS2_COMPR_MODE_NONE:  		break;  	case JFFS2_COMPR_MODE_PRIORITY: -		output_buf = kmalloc(*cdatalen,GFP_KERNEL); -		if (!output_buf) { -			printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n"); -			goto out; -		} -		orig_slen = *datalen; -		orig_dlen = *cdatalen; -		spin_lock(&jffs2_compressor_list_lock); -		list_for_each_entry(this, &jffs2_compressor_list, list) { -			/* Skip decompress-only backwards-compatibility and disabled modules */ -			if ((!this->compress)||(this->disabled)) -				continue; - -			this->usecount++; -			spin_unlock(&jffs2_compressor_list_lock); -			*datalen  = orig_slen; -			*cdatalen = orig_dlen; -			compr_ret = this->compress(data_in, output_buf, datalen, cdatalen); -			spin_lock(&jffs2_compressor_list_lock); -			this->usecount--; -			if (!compr_ret) { -				ret = this->compr; -				this->stat_compr_blocks++; -				this->stat_compr_orig_size += *datalen; -				this->stat_compr_new_size  += *cdatalen; -				break; -			} -		} -		spin_unlock(&jffs2_compressor_list_lock); -		if (ret == JFFS2_COMPR_NONE) -			kfree(output_buf); +		ret = jffs2_selected_compress(0, data_in, cpage_out, datalen, +				cdatalen);  		break;  	case JFFS2_COMPR_MODE_SIZE:  	case JFFS2_COMPR_MODE_FAVOURLZO: @@ -140,7 +190,8 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,  				tmp_buf = kmalloc(orig_slen, GFP_KERNEL);  				spin_lock(&jffs2_compressor_list_lock);  				if (!tmp_buf) { -					printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n", orig_slen); +					pr_warn("No memory for compressor allocation. (%d bytes)\n", +						orig_slen);  					continue;  				}  				else { @@ -174,22 +225,28 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,  			best->stat_compr_orig_size += best_slen;  			best->stat_compr_new_size  += best_dlen;  			ret = best->compr; +			*cpage_out = output_buf;  		}  		spin_unlock(&jffs2_compressor_list_lock);  		break; +	case JFFS2_COMPR_MODE_FORCELZO: +		ret = jffs2_selected_compress(JFFS2_COMPR_LZO, data_in, +				cpage_out, datalen, cdatalen); +		break; +	case JFFS2_COMPR_MODE_FORCEZLIB: +		ret = jffs2_selected_compress(JFFS2_COMPR_ZLIB, data_in, +				cpage_out, datalen, cdatalen); +		break;  	default: -		printk(KERN_ERR "JFFS2: unknown compression mode.\n"); +		pr_err("unknown compression mode\n");  	} - out: +  	if (ret == JFFS2_COMPR_NONE) {  		*cpage_out = data_in;  		*datalen = *cdatalen;  		none_stat_compr_blocks++;  		none_stat_compr_size += *datalen;  	} -	else { -		*cpage_out = output_buf; -	}  	return ret;  } @@ -223,7 +280,8 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,  				ret = this->decompress(cdata_in, data_out, cdatalen, datalen);  				spin_lock(&jffs2_compressor_list_lock);  				if (ret) { -					printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret); +					pr_warn("Decompressor \"%s\" returned %d\n", +						this->name, ret);  				}  				else {  					this->stat_decompr_blocks++; @@ -233,7 +291,7 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,  				return ret;  			}  		} -		printk(KERN_WARNING "JFFS2 compression type 0x%02x not available.\n", comprtype); +		pr_warn("compression type 0x%02x not available\n", comprtype);  		spin_unlock(&jffs2_compressor_list_lock);  		return -EIO;  	} @@ -245,7 +303,7 @@ int jffs2_register_compressor(struct jffs2_compressor *comp)  	struct jffs2_compressor *this;  	if (!comp->name) { -		printk(KERN_WARNING "NULL compressor name at registering JFFS2 compressor. Failed.\n"); +		pr_warn("NULL compressor name at registering JFFS2 compressor. Failed.\n");  		return -1;  	}  	comp->compr_buf_size=0; @@ -255,7 +313,7 @@ int jffs2_register_compressor(struct jffs2_compressor *comp)  	comp->stat_compr_new_size=0;  	comp->stat_compr_blocks=0;  	comp->stat_decompr_blocks=0; -	D1(printk(KERN_DEBUG "Registering JFFS2 compressor \"%s\"\n", comp->name)); +	jffs2_dbg(1, "Registering JFFS2 compressor \"%s\"\n", comp->name);  	spin_lock(&jffs2_compressor_list_lock); @@ -278,15 +336,15 @@ out:  int jffs2_unregister_compressor(struct jffs2_compressor *comp)  { -	D2(struct jffs2_compressor *this;) +	D2(struct jffs2_compressor *this); -	D1(printk(KERN_DEBUG "Unregistering JFFS2 compressor \"%s\"\n", comp->name)); +	jffs2_dbg(1, "Unregistering JFFS2 compressor \"%s\"\n", comp->name);  	spin_lock(&jffs2_compressor_list_lock);  	if (comp->usecount) {  		spin_unlock(&jffs2_compressor_list_lock); -		printk(KERN_WARNING "JFFS2: Compressor modul is in use. Unregister failed.\n"); +		pr_warn("Compressor module is in use. Unregister failed.\n");  		return -1;  	}  	list_del(&comp->list); @@ -323,17 +381,17 @@ int __init jffs2_compressors_init(void)  /* Setting default compression mode */  #ifdef CONFIG_JFFS2_CMODE_NONE  	jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; -	D1(printk(KERN_INFO "JFFS2: default compression mode: none\n");) +	jffs2_dbg(1, "default compression mode: none\n");  #else  #ifdef CONFIG_JFFS2_CMODE_SIZE  	jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; -	D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");) +	jffs2_dbg(1, "default compression mode: size\n");  #else  #ifdef CONFIG_JFFS2_CMODE_FAVOURLZO  	jffs2_compression_mode = JFFS2_COMPR_MODE_FAVOURLZO; -	D1(printk(KERN_INFO "JFFS2: default compression mode: favourlzo\n");) +	jffs2_dbg(1, "default compression mode: favourlzo\n");  #else -	D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");) +	jffs2_dbg(1, "default compression mode: priority\n");  #endif  #endif  #endif  | 
