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