1*c799aca3SRichard Purdie /* 2*c799aca3SRichard Purdie * JFFS2 -- Journalling Flash File System, Version 2. 3*c799aca3SRichard Purdie * 4*c799aca3SRichard Purdie * Copyright © 2007 Nokia Corporation. All rights reserved. 5*c799aca3SRichard Purdie * 6*c799aca3SRichard Purdie * Created by Richard Purdie <rpurdie@openedhand.com> 7*c799aca3SRichard Purdie * 8*c799aca3SRichard Purdie * For licensing information, see the file 'LICENCE' in this directory. 9*c799aca3SRichard Purdie * 10*c799aca3SRichard Purdie */ 11*c799aca3SRichard Purdie 12*c799aca3SRichard Purdie #include <linux/kernel.h> 13*c799aca3SRichard Purdie #include <linux/sched.h> 14*c799aca3SRichard Purdie #include <linux/slab.h> 15*c799aca3SRichard Purdie #include <linux/vmalloc.h> 16*c799aca3SRichard Purdie #include <linux/init.h> 17*c799aca3SRichard Purdie #include <linux/lzo.h> 18*c799aca3SRichard Purdie #include "compr.h" 19*c799aca3SRichard Purdie 20*c799aca3SRichard Purdie static void *lzo_mem; 21*c799aca3SRichard Purdie static void *lzo_compress_buf; 22*c799aca3SRichard Purdie static DEFINE_MUTEX(deflate_mutex); 23*c799aca3SRichard Purdie 24*c799aca3SRichard Purdie static void free_workspace(void) 25*c799aca3SRichard Purdie { 26*c799aca3SRichard Purdie vfree(lzo_mem); 27*c799aca3SRichard Purdie vfree(lzo_compress_buf); 28*c799aca3SRichard Purdie } 29*c799aca3SRichard Purdie 30*c799aca3SRichard Purdie static int __init alloc_workspace(void) 31*c799aca3SRichard Purdie { 32*c799aca3SRichard Purdie lzo_mem = vmalloc(LZO1X_MEM_COMPRESS); 33*c799aca3SRichard Purdie lzo_compress_buf = vmalloc(lzo1x_worst_compress(PAGE_SIZE)); 34*c799aca3SRichard Purdie 35*c799aca3SRichard Purdie if (!lzo_mem || !lzo_compress_buf) { 36*c799aca3SRichard Purdie printk(KERN_WARNING "Failed to allocate lzo deflate workspace\n"); 37*c799aca3SRichard Purdie free_workspace(); 38*c799aca3SRichard Purdie return -ENOMEM; 39*c799aca3SRichard Purdie } 40*c799aca3SRichard Purdie 41*c799aca3SRichard Purdie return 0; 42*c799aca3SRichard Purdie } 43*c799aca3SRichard Purdie 44*c799aca3SRichard Purdie static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out, 45*c799aca3SRichard Purdie uint32_t *sourcelen, uint32_t *dstlen, void *model) 46*c799aca3SRichard Purdie { 47*c799aca3SRichard Purdie size_t compress_size; 48*c799aca3SRichard Purdie int ret; 49*c799aca3SRichard Purdie 50*c799aca3SRichard Purdie mutex_lock(&deflate_mutex); 51*c799aca3SRichard Purdie ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem); 52*c799aca3SRichard Purdie mutex_unlock(&deflate_mutex); 53*c799aca3SRichard Purdie 54*c799aca3SRichard Purdie if (ret != LZO_E_OK) 55*c799aca3SRichard Purdie return -1; 56*c799aca3SRichard Purdie 57*c799aca3SRichard Purdie if (compress_size > *dstlen) 58*c799aca3SRichard Purdie return -1; 59*c799aca3SRichard Purdie 60*c799aca3SRichard Purdie memcpy(cpage_out, lzo_compress_buf, compress_size); 61*c799aca3SRichard Purdie *dstlen = compress_size; 62*c799aca3SRichard Purdie 63*c799aca3SRichard Purdie return 0; 64*c799aca3SRichard Purdie } 65*c799aca3SRichard Purdie 66*c799aca3SRichard Purdie static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out, 67*c799aca3SRichard Purdie uint32_t srclen, uint32_t destlen, void *model) 68*c799aca3SRichard Purdie { 69*c799aca3SRichard Purdie size_t dl = destlen; 70*c799aca3SRichard Purdie int ret; 71*c799aca3SRichard Purdie 72*c799aca3SRichard Purdie ret = lzo1x_decompress_safe(data_in, srclen, cpage_out, &dl); 73*c799aca3SRichard Purdie 74*c799aca3SRichard Purdie if (ret != LZO_E_OK || dl != destlen) 75*c799aca3SRichard Purdie return -1; 76*c799aca3SRichard Purdie 77*c799aca3SRichard Purdie return 0; 78*c799aca3SRichard Purdie } 79*c799aca3SRichard Purdie 80*c799aca3SRichard Purdie static struct jffs2_compressor jffs2_lzo_comp = { 81*c799aca3SRichard Purdie .priority = JFFS2_LZO_PRIORITY, 82*c799aca3SRichard Purdie .name = "lzo", 83*c799aca3SRichard Purdie .compr = JFFS2_COMPR_LZO, 84*c799aca3SRichard Purdie .compress = &jffs2_lzo_compress, 85*c799aca3SRichard Purdie .decompress = &jffs2_lzo_decompress, 86*c799aca3SRichard Purdie .disabled = 0, 87*c799aca3SRichard Purdie }; 88*c799aca3SRichard Purdie 89*c799aca3SRichard Purdie int __init jffs2_lzo_init(void) 90*c799aca3SRichard Purdie { 91*c799aca3SRichard Purdie int ret; 92*c799aca3SRichard Purdie 93*c799aca3SRichard Purdie ret = alloc_workspace(); 94*c799aca3SRichard Purdie if (ret < 0) 95*c799aca3SRichard Purdie return ret; 96*c799aca3SRichard Purdie 97*c799aca3SRichard Purdie ret = jffs2_register_compressor(&jffs2_lzo_comp); 98*c799aca3SRichard Purdie if (ret) 99*c799aca3SRichard Purdie free_workspace(); 100*c799aca3SRichard Purdie 101*c799aca3SRichard Purdie return ret; 102*c799aca3SRichard Purdie } 103*c799aca3SRichard Purdie 104*c799aca3SRichard Purdie void jffs2_lzo_exit(void) 105*c799aca3SRichard Purdie { 106*c799aca3SRichard Purdie jffs2_unregister_compressor(&jffs2_lzo_comp); 107*c799aca3SRichard Purdie free_workspace(); 108*c799aca3SRichard Purdie } 109