mtd/fs/jffs2 compr.h, NONE, 1.1 Makefile.common, 1.1, 1.2 compr.c,
1.34, 1.35 compr_rtime.c, 1.11, 1.12 compr_rubin.c, 1.17,
1.18 compr_zlib.c, 1.25, 1.26 gc.c, 1.133, 1.134 nodelist.h,
1.117, 1.118 os-linux.h, 1.42, 1.43 read.c, 1.35,
1.36 super-v24.c, 1.77, 1.78 super.c, 1.93, 1.94 write.c, 1.83, 1.84
havasi at infradead.org
havasi at infradead.org
Tue May 25 07:12:34 EDT 2004
Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/home/havasi/mtd/fs/jffs2
Modified Files:
Makefile.common compr.c compr_rtime.c compr_rubin.c
compr_zlib.c gc.c nodelist.h os-linux.h read.c super-v24.c
super.c write.c
Added Files:
compr.h
Log Message:
BBC core patch:
- new compressor interface
- 3 compression mode: none, priority, size
- compressors can be selected via kconfig
--- NEW FILE compr.h ---
/*
* JFFS2 -- Journalling Flash File System, Version 2.
*
* Copyright (C) 2004 Ferenc Havasi <havasi at inf.u-szeged.hu>,
* University of Szeged, Hungary
*
* For licensing information, see the file 'LICENCE' in the
* jffs2 directory.
*
* $Id: compr.h,v 1.1 2004/05/25 11:12:31 havasi Exp $
*
*/
#ifndef __JFFS2_COMPR_H__
#define __JFFS2_COMPR_H__
#include <linux/kernel.h>
#include <linux/vmalloc.h>
#include <linux/list.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/jffs2.h>
#include <linux/jffs2_fs_i.h>
#include <linux/jffs2_fs_sb.h>
#include "nodelist.h"
#define JFFS2_RUBINMIPS_PRIORITY 10
#define JFFS2_DYNRUBIN_PRIORITY 20
#define JFFS2_RTIME_PRIORITY 50
#define JFFS2_ZLIB_PRIORITY 60
#define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */
#define JFFS2_DYNRUBIN_DISABLED /* for decompression */
#define JFFS2_COMPR_MODE_NONE 0
#define JFFS2_COMPR_MODE_PRIORITY 1
#define JFFS2_COMPR_MODE_SIZE 2
#define JFFS2_MALLOC(a) kmalloc(a,GFP_KERNEL)
#define JFFS2_FREE(a) kfree(a)
#define JFFS2_MALLOC_BIG(a) vmalloc(a)
#define JFFS2_FREE_BIG(a) vfree(a)
void jffs2_set_compression_mode(int mode);
int jffs2_get_compression_mode(void);
struct jffs2_compressor {
struct list_head list;
int priority; /* used by prirority comr. mode */
char *name;
char compr; /* JFFS2_COMPR_XXX */
int (*compress)(unsigned char *data_in, unsigned char *cpage_out,
uint32_t *srclen, uint32_t *destlen);
int (*decompress)(unsigned char *cdata_in, unsigned char *data_out,
uint32_t cdatalen, uint32_t datalen);
int usecount;
int disabled; /* if seted the compressor won't compress */
unsigned char *compr_buf; /* used by size compr. mode */
uint32_t compr_buf_size; /* used by size compr. mode */
uint32_t stat_compr_orig_size;
uint32_t stat_compr_new_size;
uint32_t stat_compr_blocks;
uint32_t stat_decompr_blocks;
};
int jffs2_register_compressor(struct jffs2_compressor *comp);
int jffs2_unregister_compressor(struct jffs2_compressor *comp);
int jffs2_compressors_init(void);
int jffs2_compressors_exit(void);
uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
unsigned char *data_in, unsigned char **cpage_out,
uint32_t *datalen, uint32_t *cdatalen);
int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
uint16_t comprtype, unsigned char *cdata_in,
unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig);
/* Compressor modules */
/* These functions will be called by jffs2_compressors_init/exit */
#ifdef CONFIG_JFFS2_RUBIN
int jffs2_rubinmips_init(void);
void jffs2_rubinmips_exit(void);
int jffs2_dynrubin_init(void);
void jffs2_dynrubin_exit(void);
#endif
#ifdef CONFIG_JFFS2_RTIME
int jffs2_rtime_init(void);
void jffs2_rtime_exit(void);
#endif
#ifdef CONFIG_JFFS2_ZLIB
int jffs2_zlib_init(void);
void jffs2_zlib_exit(void);
#endif
#endif /* __JFFS2_COMPR_H__ */
Index: Makefile.common
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/Makefile.common,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Makefile.common 27 May 2003 09:34:41 -0000 1.1
+++ Makefile.common 25 May 2004 11:12:31 -0000 1.2
@@ -12,8 +12,10 @@
obj-$(CONFIG_JFFS2_FS) := jffs2.o
-COMPR_OBJS := compr.o compr_rubin.o compr_rtime.o compr_zlib.o
-JFFS2_OBJS := dir.o file.o ioctl.o nodelist.o malloc.o \
+JRUBIN_OBJS-$(CONFIG_JFFS2_RUBIN) := compr_rubin.o
+JRTIME_OBJS-$(CONFIG_JFFS2_RTIME) := compr_rtime.o
+JZLIB_OBJS-$(CONFIG_JFFS2_ZLIB) := compr_zlib.o
+JFFS2_OBJS := compr.o dir.o file.o ioctl.o nodelist.o malloc.o \
read.o nodemgmt.o readinode.o write.o scan.o gc.o \
symlink.o build.o erase.o background.o fs.o writev.o
@@ -28,8 +30,7 @@
NAND_OBJS-$(CONFIG_JFFS2_FS_NAND) := wbuf.o
jffs2-objs := $(COMPR_OBJS) $(JFFS2_OBJS) $(VERS_OBJS) $(NAND_OBJS-y) \
- $(LINUX_OBJS)
-
+ $(LINUX_OBJS) $(JRUBIN_OBJS-y) $(JRTIME_OBJS-y) $(JZLIB_OBJS-y)
# 2.4 build compatibility
ifeq ($(BELOW25),y)
@@ -37,4 +38,3 @@
O_TARGET := jffs2.o
include $(TOPDIR)/Rules.make
endif
-
Index: compr.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/compr.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- compr.c 8 Mar 2004 15:29:09 -0000 1.34
+++ compr.c 25 May 2004 11:12:31 -0000 1.35
@@ -2,32 +2,42 @@
* JFFS2 -- Journalling Flash File System, Version 2.
*
* Copyright (C) 2001-2003 Red Hat, Inc.
- *
* Created by Arjan van de Ven <arjanv at redhat.com>
*
+ * Copyright (C) 2004 Ferenc Havasi <havasi at inf.u-szeged.hu>,
+ * University of Szeged, Hungary
+ *
* For licensing information, see the file 'LICENCE' in this directory.
*
* $Id$
*
*/
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/jffs2.h>
-#include "nodelist.h"
-
-int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
-int jffs2_rtime_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-void jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
-int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-void jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
-int jffs2_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-void jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
+#include "compr.h"
+
+#define COMPRESSOR_LIST_LOCK spin_lock(&jffs2_compressor_list_lock)
+#define COMPRESSOR_LIST_UNLOCK spin_unlock(&jffs2_compressor_list_lock)
+
+static spinlock_t jffs2_compressor_list_lock = SPIN_LOCK_UNLOCKED;
+
+/* Available compressors are on this list */
+static LIST_HEAD(jffs2_compressor_list);
+/* Actual compression mode */
+static int jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY;
+
+void jffs2_set_compression_mode(int mode)
+{
+ jffs2_compression_mode = mode;
+}
+
+int jffs2_get_compression_mode(void)
+{
+ return jffs2_compression_mode;
+}
+
+/* Statistics for blocks stored without compression */
+static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_compr_size=0;
/* jffs2_compress:
* @data: Pointer to uncompressed data
@@ -38,103 +48,279 @@
* data. On exit, expected to hold the actual size of the compressed
* data.
*
- * Returns: Byte to be stored with data indicating compression type used.
+ * Returns: Lower byte to be stored with data indicating compression type used.
* Zero is used to show that the data could not be compressed - the
* compressed version was actually larger than the original.
+ * Upper byte will be used later. (soon)
*
* If the cdata buffer isn't large enough to hold all the uncompressed data,
* jffs2_compress should compress as much as will fit, and should set
* *datalen accordingly to show the amount of data which were compressed.
*/
-unsigned char jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
+uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
unsigned char *data_in, unsigned char **cpage_out,
uint32_t *datalen, uint32_t *cdatalen)
{
-#ifdef JFFS2_COMPRESSION
- int ret;
+ int ret = JFFS2_COMPR_NONE;
+ int 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;
- *cpage_out = kmalloc(*cdatalen, GFP_KERNEL);
- if (!*cpage_out) {
- printk(KERN_WARNING "No memory for compressor allocation. Compression failed\n");
- goto out;
- }
+ switch (jffs2_compression_mode) {
+ case JFFS2_COMPR_MODE_NONE:
+ break;
+ case JFFS2_COMPR_MODE_PRIORITY:
+ output_buf = JFFS2_MALLOC(*cdatalen);
+ if (!output_buf) {
+ printk("JFFS2: No memory for compressor allocation. Compression failed.\n");
+ goto out;
+ }
+ orig_slen = *datalen;
+ orig_dlen = *cdatalen;
+ 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;
-#ifdef JFFS2_USE_ZLIB
- ret = jffs2_zlib_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_ZLIB;
- }
-#endif
-#ifdef JFFS2_USE_DYNRUBIN
- ret = jffs2_dynrubin_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_DYNRUBIN;
- }
-#endif
-#ifdef JFFS2_USE_RUBINMIPS
- ret = jffs2_rubinmips_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_RUBINMIPS;
- }
-#endif
-#ifdef JFFS2_USE_RTIME
- /* rtime does manage to recompress already-compressed data */
- ret = jffs2_rtime_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_RTIME;
- }
-#endif
- kfree(*cpage_out);
-#endif /* Compression */
+ this->usecount++;
+ COMPRESSOR_LIST_UNLOCK;
+ *datalen = orig_slen;
+ *cdatalen = orig_dlen;
+ compr_ret = this->compress(data_in, output_buf, datalen, cdatalen);
+ 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;
+ }
+ }
+ COMPRESSOR_LIST_UNLOCK;
+ break;
+ case JFFS2_COMPR_MODE_SIZE:
+ orig_slen = *datalen;
+ orig_dlen = *cdatalen;
+ 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;
+ /* Allocating memory for output buffer if necessary */
+ if ((this->compr_buf_size<orig_dlen)&&(this->compr_buf)) {
+ COMPRESSOR_LIST_UNLOCK;
+ JFFS2_FREE(this->compr_buf);
+ COMPRESSOR_LIST_LOCK;
+ this->compr_buf_size=0;
+ this->compr_buf=NULL;
+ }
+ if (!this->compr_buf) {
+ COMPRESSOR_LIST_UNLOCK;
+ tmp_buf = JFFS2_MALLOC(orig_dlen);
+ COMPRESSOR_LIST_LOCK;
+ if (!tmp_buf) {
+ printk("JFFS2: No memory for compressor allocation. (%d bytes)\n",orig_dlen);
+ continue;
+ }
+ else {
+ this->compr_buf = tmp_buf;
+ this->compr_buf_size = orig_dlen;
+ }
+ }
+ this->usecount++;
+ COMPRESSOR_LIST_UNLOCK;
+ *datalen = orig_slen;
+ *cdatalen = orig_dlen;
+ compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen);
+ COMPRESSOR_LIST_LOCK;
+ this->usecount--;
+ if (!compr_ret) {
+ if ((!best_dlen)||(best_dlen>*cdatalen)) {
+ best_dlen = *cdatalen;
+ best_slen = *datalen;
+ best = this;
+ }
+ }
+ }
+ if (best_dlen) {
+ *cdatalen = best_dlen;
+ *datalen = best_slen;
+ output_buf = best->compr_buf;
+ best->compr_buf = NULL;
+ best->compr_buf_size = 0;
+ best->stat_compr_blocks++;
+ best->stat_compr_orig_size += best_slen;
+ best->stat_compr_new_size += best_dlen;
+ ret = best->compr;
+ }
+ COMPRESSOR_LIST_UNLOCK;
+ break;
+ default:
+ printk("JFFS2: unknow compression mode.\n");
+ }
out:
- *cpage_out = data_in;
- *datalen = *cdatalen;
- return JFFS2_COMPR_NONE; /* We failed to compress */
-}
-
-void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
-{
- if (orig != comprbuf)
- kfree(comprbuf);
+ 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;
}
int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
- unsigned char comprtype, unsigned char *cdata_in,
+ uint16_t comprtype, unsigned char *cdata_in,
unsigned char *data_out, uint32_t cdatalen, uint32_t datalen)
{
- switch (comprtype) {
+ struct jffs2_compressor *this;
+ int ret;
+
+ switch (comprtype & 0xff) {
case JFFS2_COMPR_NONE:
/* This should be special-cased elsewhere, but we might as well deal with it */
memcpy(data_out, cdata_in, datalen);
+ none_stat_decompr_blocks++;
break;
-
case JFFS2_COMPR_ZERO:
memset(data_out, 0, datalen);
break;
-#ifdef JFFS2_USE_ZLIB
- case JFFS2_COMPR_ZLIB:
- jffs2_zlib_decompress(cdata_in, data_out, cdatalen, datalen);
- break;
+ default:
+ COMPRESSOR_LIST_LOCK;
+ list_for_each_entry(this, &jffs2_compressor_list, list) {
+ if (comprtype == this->compr) {
+ this->usecount++;
+ COMPRESSOR_LIST_UNLOCK;
+ ret = this->decompress(cdata_in, data_out, cdatalen, datalen);
+ COMPRESSOR_LIST_LOCK;
+ if (ret) {
+ printk("Decompressor \"%s\" returned %d\n", this->name, ret);
+ }
+ else {
+ this->stat_decompr_blocks++;
+ }
+ this->usecount--;
+ COMPRESSOR_LIST_UNLOCK;
+ return ret;
+ }
+ }
+ printk("JFFS2 compression type 0x%02x not avaiable.\n", comprtype);
+ COMPRESSOR_LIST_UNLOCK;
+ return -EIO;
+ }
+ return 0;
+}
+
+int jffs2_register_compressor(struct jffs2_compressor *comp)
+{
+ struct jffs2_compressor *this;
+
+ if (!comp->name) {
+ printk("NULL compressor name at registering JFFS2 compressor. Failed.\n");
+ return -1;
+ }
+ comp->compr_buf_size=0;
+ comp->compr_buf=NULL;
+ comp->usecount=0;
+ comp->stat_compr_orig_size=0;
+ comp->stat_compr_new_size=0;
+ comp->stat_compr_blocks=0;
+ comp->stat_decompr_blocks=0;
+ D1(printk("Registering JFFS2 compressor \"%s\"\n", comp->name));
+
+ COMPRESSOR_LIST_LOCK;
+
+ list_for_each_entry(this, &jffs2_compressor_list, list) {
+ if (this->priority < comp->priority) {
+ list_add(&comp->list, this->list.prev);
+ goto out;
+ }
+ }
+ list_add_tail(&comp->list, &jffs2_compressor_list);
+out:
+ D2(list_for_each_entry(this, &jffs2_compressor_list, list) {
+ printk("Compressor \"%s\", prio %d\n", this->name, this->priority);
+ })
+
+ COMPRESSOR_LIST_UNLOCK;
+
+ return 0;
+}
+
+int jffs2_unregister_compressor(struct jffs2_compressor *comp)
+{
+ D2(struct jffs2_compressor *this;)
+
+ D1(printk("Unregistering JFFS2 compressor \"%s\"\n", comp->name));
+
+ COMPRESSOR_LIST_LOCK;
+
+ if (comp->usecount) {
+ COMPRESSOR_LIST_UNLOCK;
+ printk("JFFS2: Compressor modul is in use. Unregister failed.\n");
+ return -1;
+ }
+ list_del(&comp->list);
+
+ D2(list_for_each_entry(this, &jffs2_compressor_list, list) {
+ printk("Compressor \"%s\", prio %d\n", this->name, this->priority);
+ })
+ COMPRESSOR_LIST_UNLOCK;
+ return 0;
+}
+
+void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
+{
+ if (orig != comprbuf)
+ JFFS2_FREE(comprbuf);
+}
+
+int jffs2_compressors_init(void)
+{
+/* Registering compressors */
+#ifdef CONFIG_JFFS2_ZLIB
+ jffs2_zlib_init();
#endif
-#ifdef JFFS2_USE_RTIME
- case JFFS2_COMPR_RTIME:
- jffs2_rtime_decompress(cdata_in, data_out, cdatalen, datalen);
- break;
+#ifdef CONFIG_JFFS2_RTIME
+ jffs2_rtime_init();
#endif
-#ifdef JFFS2_USE_RUBINMIPS
- case JFFS2_COMPR_RUBINMIPS:
- jffs2_rubinmips_decompress(cdata_in, data_out, cdatalen, datalen);
- break;
+#ifdef CONFIG_JFFS2_RUBIN
+ jffs2_rubinmips_init();
+ jffs2_dynrubin_init();
+#endif
+/* Setting default compression mode */
+#ifdef CONFIG_JFFS2_CMODE_NONE
+ jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
+ D1(printk("JFFS2: default compression mode: none\n");)
+#else
+#ifdef CONFIG_JFFS2_CMODE_SIZE
+ jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE;
+ D1(printk("JFFS2: default compression mode: size\n");)
+#else
+ D1(printk("JFFS2: default compression mode: priority\n");)
#endif
-#ifdef JFFS2_USE_DYNRUBIN
- case JFFS2_COMPR_DYNRUBIN:
+#endif
+ return 0;
+}
- jffs2_dynrubin_decompress(cdata_in, data_out, cdatalen, datalen);
- break;
+int jffs2_compressors_exit(void)
+{
+/* Unregistering compressors */
+#ifdef CONFIG_JFFS2_RUBIN
+ jffs2_dynrubin_exit();
+ jffs2_rubinmips_exit();
#endif
- default:
- printk(KERN_NOTICE "Unknown JFFS2 compression type 0x%02x\n", comprtype);
- return -EIO;
- }
- return 0;
+#ifdef CONFIG_JFFS2_RTIME
+ jffs2_rtime_exit();
+#endif
+#ifdef CONFIG_JFFS2_ZLIB
+ jffs2_zlib_exit();
+#endif
+ return 0;
}
Index: compr_rtime.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/compr_rtime.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- compr_rtime.c 4 Oct 2003 08:33:06 -0000 1.11
+++ compr_rtime.c 25 May 2004 11:12:31 -0000 1.12
@@ -25,6 +25,8 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/jffs2.h>
+#include "compr.h"
/* _compress returns the compressed size, -1 if bigger */
int jffs2_rtime_compress(unsigned char *data_in, unsigned char *cpage_out,
@@ -67,7 +69,7 @@
}
-void jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out,
+int jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out,
uint32_t srclen, uint32_t destlen)
{
short positions[256];
@@ -98,7 +100,29 @@
outpos+=repeat;
}
}
- }
+ }
+ return 0;
}
+static struct jffs2_compressor jffs2_rtime_comp = {
+ .priority = JFFS2_RTIME_PRIORITY,
+ .name = "rtime",
+ .compr = JFFS2_COMPR_RTIME,
+ .compress = &jffs2_rtime_compress,
+ .decompress = &jffs2_rtime_decompress,
+#ifdef JFFS2_RTIME_DISABLED
+ .disabled = 1,
+#else
+ .disabled = 0,
+#endif
+};
+
+int jffs2_rtime_init(void)
+{
+ return jffs2_register_compressor(&jffs2_rtime_comp);
+}
+void jffs2_rtime_exit(void)
+{
+ jffs2_unregister_compressor(&jffs2_rtime_comp);
+}
Index: compr_rubin.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/compr_rubin.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- compr_rubin.c 20 May 2002 14:56:37 -0000 1.17
+++ compr_rubin.c 25 May 2004 11:12:31 -0000 1.18
@@ -14,10 +14,10 @@
#include <linux/string.h>
#include <linux/types.h>
+#include <linux/jffs2.h>
#include "compr_rubin.h"
#include "histo_mips.h"
-
-
+#include "compr.h"
static void init_rubin(struct rubin_state *rs, int div, int *bits)
{
@@ -306,13 +306,14 @@
}
-void jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out,
+int jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out,
uint32_t sourcelen, uint32_t dstlen)
{
rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
+ return 0;
}
-void jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out,
+int jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out,
uint32_t sourcelen, uint32_t dstlen)
{
int bits[8];
@@ -322,4 +323,51 @@
bits[c] = data_in[c];
rubin_do_decompress(256, bits, data_in+8, cpage_out, sourcelen-8, dstlen);
+ return 0;
+}
+
+static struct jffs2_compressor jffs2_rubinmips_comp = {
+ .priority = JFFS2_RUBINMIPS_PRIORITY,
+ .name = "rubinmips",
+ .compr = JFFS2_COMPR_DYNRUBIN,
+ .compress = NULL, /*&jffs2_rubinmips_compress,*/
+ .decompress = &jffs2_rubinmips_decompress,
+#ifdef JFFS2_RUBINMIPS_DISABLED
+ .disabled = 1,
+#else
+ .disabled = 0,
+#endif
+};
+
+int jffs2_rubinmips_init(void)
+{
+ return jffs2_register_compressor(&jffs2_rubinmips_comp);
+}
+
+void jffs2_rubinmips_exit(void)
+{
+ jffs2_unregister_compressor(&jffs2_rubinmips_comp);
+}
+
+static struct jffs2_compressor jffs2_dynrubin_comp = {
+ .priority = JFFS2_DYNRUBIN_PRIORITY,
+ .name = "dynrubin",
+ .compr = JFFS2_COMPR_RUBINMIPS,
+ .compress = jffs2_dynrubin_compress,
+ .decompress = &jffs2_dynrubin_decompress,
+#ifdef JFFS2_DYNRUBIN_DISABLED
+ .disabled = 1,
+#else
+ .disabled = 0,
+#endif
+};
+
+int jffs2_dynrubin_init(void)
+{
+ return jffs2_register_compressor(&jffs2_dynrubin_comp);
+}
+
+void jffs2_dynrubin_exit(void)
+{
+ jffs2_unregister_compressor(&jffs2_dynrubin_comp);
}
Index: compr_zlib.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/compr_zlib.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- compr_zlib.c 3 Dec 2003 09:25:43 -0000 1.25
+++ compr_zlib.c 25 May 2004 11:12:31 -0000 1.26
@@ -22,6 +22,7 @@
#include <linux/zutil.h>
#include <asm/semaphore.h>
#include "nodelist.h"
+#include "compr.h"
/* Plan: call deflate() with avail_in == *sourcelen,
avail_out = *dstlen - 12 and flush == Z_FINISH.
@@ -40,7 +41,7 @@
#include <linux/vmalloc.h>
#include <linux/init.h>
-int __init jffs2_zlib_init(void)
+static int __init alloc_workspaces(void)
{
def_strm.workspace = vmalloc(zlib_deflate_workspacesize());
if (!def_strm.workspace) {
@@ -58,11 +59,14 @@
return 0;
}
-void jffs2_zlib_exit(void)
+static void free_workspaces(void)
{
vfree(def_strm.workspace);
vfree(inf_strm.workspace);
}
+#else
+#define alloc_workspaces() (0)
+#define free_workspaces() do { } while(0)
#endif /* __KERNEL__ */
int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out,
@@ -131,7 +135,7 @@
return ret;
}
-void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
+int jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
uint32_t srclen, uint32_t destlen)
{
int ret;
@@ -166,7 +170,7 @@
if (Z_OK != zlib_inflateInit2(&inf_strm, wbits)) {
printk(KERN_WARNING "inflateInit failed\n");
up(&inflate_sem);
- return;
+ return 1;
}
while((ret = zlib_inflate(&inf_strm, Z_FINISH)) == Z_OK)
@@ -176,4 +180,39 @@
}
zlib_inflateEnd(&inf_strm);
up(&inflate_sem);
+ return 0;
+}
+
+static struct jffs2_compressor jffs2_zlib_comp = {
+ .priority = JFFS2_ZLIB_PRIORITY,
+ .name = "zlib",
+ .compr = JFFS2_COMPR_ZLIB,
+ .compress = &jffs2_zlib_compress,
+ .decompress = &jffs2_zlib_decompress,
+#ifdef JFFS2_ZLIB_DISABLED
+ .disabled = 1,
+#else
+ .disabled = 0,
+#endif
+};
+
+int __init jffs2_zlib_init(void)
+{
+ int ret;
+
+ ret = alloc_workspaces();
+ if (ret)
+ return ret;
+
+ ret = jffs2_register_compressor(&jffs2_zlib_comp);
+ if (ret)
+ free_workspaces();
+
+ return ret;
+}
+
+void jffs2_zlib_exit(void)
+{
+ jffs2_unregister_compressor(&jffs2_zlib_comp);
+ free_workspaces();
}
Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/gc.c,v
retrieving revision 1.133
retrieving revision 1.134
diff -u -r1.133 -r1.134
--- gc.c 8 Mar 2004 15:29:09 -0000 1.133
+++ gc.c 25 May 2004 11:12:31 -0000 1.134
@@ -19,6 +19,7 @@
#include <linux/compiler.h>
#include <linux/stat.h>
#include "nodelist.h"
+#include "compr.h"
static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
struct jffs2_inode_cache *ic,
@@ -1176,7 +1177,7 @@
while(offset < orig_end) {
uint32_t datalen;
uint32_t cdatalen;
- char comprtype = JFFS2_COMPR_NONE;
+ uint16_t comprtype = JFFS2_COMPR_NONE;
ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen);
@@ -1209,7 +1210,8 @@
ri.offset = cpu_to_je32(offset);
ri.csize = cpu_to_je32(cdatalen);
ri.dsize = cpu_to_je32(datalen);
- ri.compr = comprtype;
+ ri.compr = comprtype & 0xff;
+ ri.usercompr = (comprtype >> 8) & 0xff;
ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
Index: nodelist.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodelist.h,v
retrieving revision 1.117
retrieving revision 1.118
diff -u -r1.117 -r1.118
--- nodelist.h 5 May 2004 11:57:52 -0000 1.117
+++ nodelist.h 25 May 2004 11:12:32 -0000 1.118
@@ -472,15 +472,6 @@
unsigned char *buf, uint32_t offset, uint32_t len);
char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
-/* compr.c */
-unsigned char jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
- unsigned char *data_in, unsigned char **cpage_out,
- uint32_t *datalen, uint32_t *cdatalen);
-void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig);
-int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
- unsigned char comprtype, unsigned char *cdata_in,
- unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
-
/* scan.c */
int jffs2_scan_medium(struct jffs2_sb_info *c);
void jffs2_rotate_lists(struct jffs2_sb_info *c);
@@ -500,9 +491,5 @@
int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
int jffs2_nand_read_failcnt(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
#endif
-
-/* compr_zlib.c */
-int jffs2_zlib_init(void);
-void jffs2_zlib_exit(void);
#endif /* __JFFS2_NODELIST_H__ */
Index: os-linux.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/os-linux.h,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -r1.42 -r1.43
--- os-linux.h 5 May 2004 12:00:31 -0000 1.42
+++ os-linux.h 25 May 2004 11:12:32 -0000 1.43
@@ -201,13 +201,6 @@
int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
unsigned long count, loff_t to, size_t *retlen);
-/* Compression config */
-#define JFFS2_COMPRESSION
-#undef JFFS2_USE_DYNRUBIN /* Disabled 23/9/1. With zlib it hardly ever gets a look in */
-#undef JFFS2_USE_RUBINMIPS /* Disabled 26/2/1. Obsoleted by dynrubin */
-#define JFFS2_USE_ZLIB
-#define JFFS2_USE_RTIME /* rtime does manage to recompress already-compressed data */
-
#endif /* __JFFS2_OS_LINUX_H__ */
Index: read.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/read.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- read.c 8 Mar 2004 15:29:09 -0000 1.35
+++ read.c 25 May 2004 11:12:32 -0000 1.36
@@ -18,6 +18,7 @@
#include <linux/mtd/mtd.h>
#include <linux/compiler.h>
#include "nodelist.h"
+#include "compr.h"
int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
struct jffs2_full_dnode *fd, unsigned char *buf,
@@ -129,7 +130,7 @@
if (ri->compr != JFFS2_COMPR_NONE) {
D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n",
je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf));
- ret = jffs2_decompress(c, f, ri->compr, readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize));
+ ret = jffs2_decompress(c, f, ri->compr | (ri->usercompr << 8), readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize));
if (ret) {
printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret);
goto out_decomprbuf;
Index: super-v24.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/super-v24.c,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -r1.77 -r1.78
--- super-v24.c 5 May 2004 12:00:31 -0000 1.77
+++ super-v24.c 25 May 2004 11:12:32 -0000 1.78
@@ -22,6 +22,7 @@
#include <linux/jffs2.h>
#include <linux/pagemap.h>
#include <linux/mtd/mtd.h>
+#include "compr.h"
#include "nodelist.h"
#ifndef MTD_BLOCK_MAJOR
@@ -125,15 +126,15 @@
return -EIO;
}
#endif
- ret = jffs2_zlib_init();
+ ret = jffs2_compressors_init();
if (ret) {
- printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n");
+ printk(KERN_ERR "JFFS2 error: Failed to initialise compressors\n");
goto out;
}
ret = jffs2_create_slab_caches();
if (ret) {
printk(KERN_ERR "JFFS2 error: Failed to initialise slab caches\n");
- goto out_zlib;
+ goto out_compressors;
}
ret = register_filesystem(&jffs2_fs_type);
if (ret) {
@@ -144,17 +145,16 @@
out_slab:
jffs2_destroy_slab_caches();
- out_zlib:
- jffs2_zlib_exit();
+ out_compressors:
+ jffs2_compressors_exit();
out:
-
return ret;
}
static void __exit exit_jffs2_fs(void)
{
jffs2_destroy_slab_caches();
- jffs2_zlib_exit();
+ jffs2_compressors_exit();
unregister_filesystem(&jffs2_fs_type);
}
Index: super.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/super.c,v
retrieving revision 1.93
retrieving revision 1.94
diff -u -r1.93 -r1.94
--- super.c 5 May 2004 12:00:31 -0000 1.93
+++ super.c 25 May 2004 11:12:32 -0000 1.94
@@ -24,6 +24,7 @@
#include <linux/mtd/mtd.h>
#include <linux/ctype.h>
#include <linux/namei.h>
+#include "compr.h"
#include "nodelist.h"
static void jffs2_put_super(struct super_block *);
@@ -307,15 +308,15 @@
printk(KERN_ERR "JFFS2 error: Failed to initialise inode cache\n");
return -ENOMEM;
}
- ret = jffs2_zlib_init();
+ ret = jffs2_compressors_init();
if (ret) {
- printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n");
+ printk(KERN_ERR "JFFS2 error: Failed to initialise compressors\n");
goto out;
}
ret = jffs2_create_slab_caches();
if (ret) {
printk(KERN_ERR "JFFS2 error: Failed to initialise slab caches\n");
- goto out_zlib;
+ goto out_compressors;
}
ret = register_filesystem(&jffs2_fs_type);
if (ret) {
@@ -326,8 +327,8 @@
out_slab:
jffs2_destroy_slab_caches();
- out_zlib:
- jffs2_zlib_exit();
+ out_compressors:
+ jffs2_compressors_exit();
out:
return ret;
}
@@ -336,7 +337,7 @@
{
unregister_filesystem(&jffs2_fs_type);
jffs2_destroy_slab_caches();
- jffs2_zlib_exit();
+ jffs2_compressors_exit();
kmem_cache_destroy(jffs2_inode_cachep);
}
Index: write.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/write.c,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -r1.83 -r1.84
--- write.c 30 Mar 2004 09:36:09 -0000 1.83
+++ write.c 25 May 2004 11:12:32 -0000 1.84
@@ -18,6 +18,7 @@
#include <linux/pagemap.h>
#include <linux/mtd/mtd.h>
#include "nodelist.h"
+#include "compr.h"
int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri)
@@ -358,7 +359,7 @@
while(writelen) {
struct jffs2_full_dnode *fn;
unsigned char *comprbuf = NULL;
- unsigned char comprtype = JFFS2_COMPR_NONE;
+ uint16_t comprtype = JFFS2_COMPR_NONE;
uint32_t phys_ofs, alloclen;
uint32_t datalen, cdatalen;
int retried = 0;
@@ -388,7 +389,8 @@
ri->offset = cpu_to_je32(offset);
ri->csize = cpu_to_je32(cdatalen);
ri->dsize = cpu_to_je32(datalen);
- ri->compr = comprtype;
+ ri->compr = comprtype & 0xff;
+ ri->usercompr = (comprtype >> 8 ) & 0xff;
ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
More information about the linux-mtd-cvs
mailing list