0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/kernel.h>
0014 #include <linux/sched.h>
0015 #include <linux/vmalloc.h>
0016 #include <linux/init.h>
0017 #include <linux/lzo.h>
0018 #include "compr.h"
0019
0020 static void *lzo_mem;
0021 static void *lzo_compress_buf;
0022 static DEFINE_MUTEX(deflate_mutex);
0023
0024 static void free_workspace(void)
0025 {
0026 vfree(lzo_mem);
0027 vfree(lzo_compress_buf);
0028 }
0029
0030 static int __init alloc_workspace(void)
0031 {
0032 lzo_mem = vmalloc(LZO1X_MEM_COMPRESS);
0033 lzo_compress_buf = vmalloc(lzo1x_worst_compress(PAGE_SIZE));
0034
0035 if (!lzo_mem || !lzo_compress_buf) {
0036 free_workspace();
0037 return -ENOMEM;
0038 }
0039
0040 return 0;
0041 }
0042
0043 static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out,
0044 uint32_t *sourcelen, uint32_t *dstlen)
0045 {
0046 size_t compress_size;
0047 int ret;
0048
0049 mutex_lock(&deflate_mutex);
0050 ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem);
0051 if (ret != LZO_E_OK)
0052 goto fail;
0053
0054 if (compress_size > *dstlen)
0055 goto fail;
0056
0057 memcpy(cpage_out, lzo_compress_buf, compress_size);
0058 mutex_unlock(&deflate_mutex);
0059
0060 *dstlen = compress_size;
0061 return 0;
0062
0063 fail:
0064 mutex_unlock(&deflate_mutex);
0065 return -1;
0066 }
0067
0068 static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
0069 uint32_t srclen, uint32_t destlen)
0070 {
0071 size_t dl = destlen;
0072 int ret;
0073
0074 ret = lzo1x_decompress_safe(data_in, srclen, cpage_out, &dl);
0075
0076 if (ret != LZO_E_OK || dl != destlen)
0077 return -1;
0078
0079 return 0;
0080 }
0081
0082 static struct jffs2_compressor jffs2_lzo_comp = {
0083 .priority = JFFS2_LZO_PRIORITY,
0084 .name = "lzo",
0085 .compr = JFFS2_COMPR_LZO,
0086 .compress = &jffs2_lzo_compress,
0087 .decompress = &jffs2_lzo_decompress,
0088 .disabled = 0,
0089 };
0090
0091 int __init jffs2_lzo_init(void)
0092 {
0093 int ret;
0094
0095 ret = alloc_workspace();
0096 if (ret < 0)
0097 return ret;
0098
0099 ret = jffs2_register_compressor(&jffs2_lzo_comp);
0100 if (ret)
0101 free_workspace();
0102
0103 return ret;
0104 }
0105
0106 void jffs2_lzo_exit(void)
0107 {
0108 jffs2_unregister_compressor(&jffs2_lzo_comp);
0109 free_workspace();
0110 }