? fs/jffs2/current/src/compr.h Index: fs/jffs2/current/cdl/jffs2.cdl =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/cdl/jffs2.cdl,v retrieving revision 1.16 diff -u -r1.16 jffs2.cdl --- fs/jffs2/current/cdl/jffs2.cdl 6 Apr 2004 19:40:39 -0000 1.16 +++ fs/jffs2/current/cdl/jffs2.cdl 12 Aug 2004 21:29:22 -0000 @@ -4,7 +4,7 @@ # # JFFS2 Filesystem configuration data # -# $Id: jffs2.cdl,v 1.14 2004/02/17 15:40:36 gthomas Exp $ +# $Id: jffs2.cdl,v 1.15 2004/04/21 18:50:52 gthomas Exp $ # # ==================================================================== #####ECOSGPLCOPYRIGHTBEGIN#### Index: fs/jffs2/current/doc/TODO =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/doc/TODO,v retrieving revision 1.2 diff -u -r1.2 TODO --- fs/jffs2/current/doc/TODO 1 Apr 2004 03:17:57 -0000 1.2 +++ fs/jffs2/current/doc/TODO 12 Aug 2004 21:29:22 -0000 @@ -17,7 +17,8 @@ - test, test, test - NAND flash support: - - done :) + - almost done :) + - use bad block check instead of the hardwired byte check - Optimisations: - Split writes so they go to two separate blocks rather than just c->nextblock. Index: fs/jffs2/current/doc/TODO.eCos =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/doc/TODO.eCos,v retrieving revision 1.1 diff -u -r1.1 TODO.eCos --- fs/jffs2/current/doc/TODO.eCos 11 Dec 2003 23:38:20 -0000 1.1 +++ fs/jffs2/current/doc/TODO.eCos 12 Aug 2004 21:29:22 -0000 @@ -1,4 +1,4 @@ -$Id: TODO.eCos,v 1.2 2003/11/28 11:15:56 dwmw2 Exp $ +$Id: TODO.eCos,v 1.4 2003/11/28 11:15:56 dwmw2 Exp $ - Make symlinks work properly. Index: fs/jffs2/current/include/linux/jffs2.h =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/include/linux/jffs2.h,v retrieving revision 1.3 diff -u -r1.3 jffs2.h --- fs/jffs2/current/include/linux/jffs2.h 20 Nov 2003 16:52:35 -0000 1.3 +++ fs/jffs2/current/include/linux/jffs2.h 12 Aug 2004 21:29:22 -0000 @@ -8,7 +8,7 @@ * For licensing information, see the file 'LICENCE' in the * jffs2 directory. * - * $Id: jffs2.h,v 1.31 2003/10/04 08:33:05 dwmw2 Exp $ + * $Id: jffs2.h,v 1.33 2004/05/25 11:31:55 havasi Exp $ * */ @@ -43,6 +43,8 @@ #define JFFS2_COMPR_COPY 0x04 #define JFFS2_COMPR_DYNRUBIN 0x05 #define JFFS2_COMPR_ZLIB 0x06 +#define JFFS2_COMPR_LZO 0x07 +#define JFFS2_COMPR_LZARI 0x08 /* Compatibility flags. */ #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ #define JFFS2_NODE_ACCURATE 0x2000 @@ -87,39 +89,6 @@ uint16_t v16; } __attribute__((packed)) jint16_t; -#define JFFS2_NATIVE_ENDIAN - -/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from - whatever OS we're actually running on here too. */ - -#if defined(JFFS2_NATIVE_ENDIAN) -#define cpu_to_je16(x) ((jint16_t){x}) -#define cpu_to_je32(x) ((jint32_t){x}) -#define cpu_to_jemode(x) ((jmode_t){os_to_jffs2_mode(x)}) - -#define je16_to_cpu(x) ((x).v16) -#define je32_to_cpu(x) ((x).v32) -#define jemode_to_cpu(x) (jffs2_to_os_mode((x).m)) -#elif defined(JFFS2_BIG_ENDIAN) -#define cpu_to_je16(x) ((jint16_t){cpu_to_be16(x)}) -#define cpu_to_je32(x) ((jint32_t){cpu_to_be32(x)}) -#define cpu_to_jemode(x) ((jmode_t){cpu_to_be32(os_to_jffs2_mode(x))}) - -#define je16_to_cpu(x) (be16_to_cpu(x.v16)) -#define je32_to_cpu(x) (be32_to_cpu(x.v32)) -#define jemode_to_cpu(x) (be32_to_cpu(jffs2_to_os_mode((x).m))) -#elif defined(JFFS2_LITTLE_ENDIAN) -#define cpu_to_je16(x) ((jint16_t){cpu_to_le16(x)}) -#define cpu_to_je32(x) ((jint32_t){cpu_to_le32(x)}) -#define cpu_to_jemode(x) ((jmode_t){cpu_to_le32(os_to_jffs2_mode(x))}) - -#define je16_to_cpu(x) (le16_to_cpu(x.v16)) -#define je32_to_cpu(x) (le32_to_cpu(x.v32)) -#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m))) -#else -#error wibble -#endif - struct jffs2_unknown_node { /* All start like this */ Index: fs/jffs2/current/src/compr.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/compr.c,v retrieving revision 1.6 diff -u -r1.6 compr.c --- fs/jffs2/current/src/compr.c 1 Apr 2004 03:17:57 -0000 1.6 +++ fs/jffs2/current/src/compr.c 12 Aug 2004 21:29:23 -0000 @@ -2,32 +2,39 @@ * JFFS2 -- Journalling Flash File System, Version 2. * * Copyright (C) 2001-2003 Red Hat, Inc. - * * Created by Arjan van de Ven * + * Copyright (C) 2004 Ferenc Havasi , + * University of Szeged, Hungary + * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: compr.c,v 1.34 2004/03/08 15:29:09 dwmw2 Exp $ + * $Id: compr.c,v 1.41 2004/06/24 09:51:38 havasi Exp $ * */ -#include -#include -#include -#include -#include -#include -#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" + +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 +45,430 @@ * 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 = 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; -#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++; + spin_unlock(&jffs2_compressor_list_lock); + *datalen = orig_slen; + *cdatalen = orig_dlen; + compr_ret = this->compress(data_in, output_buf, datalen, cdatalen, NULL); + 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); + break; + case JFFS2_COMPR_MODE_SIZE: + 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; + /* Allocating memory for output buffer if necessary */ + if ((this->compr_buf_sizecompr_buf)) { + spin_unlock(&jffs2_compressor_list_lock); + kfree(this->compr_buf); + spin_lock(&jffs2_compressor_list_lock); + this->compr_buf_size=0; + this->compr_buf=NULL; + } + if (!this->compr_buf) { + spin_unlock(&jffs2_compressor_list_lock); + tmp_buf = kmalloc(orig_dlen,GFP_KERNEL); + spin_lock(&jffs2_compressor_list_lock); + if (!tmp_buf) { + printk(KERN_WARNING "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++; + spin_unlock(&jffs2_compressor_list_lock); + *datalen = orig_slen; + *cdatalen = orig_dlen; + compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen, NULL); + spin_lock(&jffs2_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; + } + spin_unlock(&jffs2_compressor_list_lock); + break; + default: + printk(KERN_ERR "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: + spin_lock(&jffs2_compressor_list_lock); + list_for_each_entry(this, &jffs2_compressor_list, list) { + if (comprtype == this->compr) { + this->usecount++; + spin_unlock(&jffs2_compressor_list_lock); + ret = this->decompress(cdata_in, data_out, cdatalen, datalen, NULL); + spin_lock(&jffs2_compressor_list_lock); + if (ret) { + printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret); + } + else { + this->stat_decompr_blocks++; + } + this->usecount--; + spin_unlock(&jffs2_compressor_list_lock); + return ret; + } + } + printk(KERN_WARNING "JFFS2 compression type 0x%02x not avaiable.\n", comprtype); + spin_unlock(&jffs2_compressor_list_lock); + return -EIO; + } + return 0; +} + +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"); + 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(KERN_DEBUG "Registering JFFS2 compressor \"%s\"\n", comp->name)); + + spin_lock(&jffs2_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(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); + }) + + spin_unlock(&jffs2_compressor_list_lock); + + return 0; +} + +int jffs2_unregister_compressor(struct jffs2_compressor *comp) +{ + D2(struct jffs2_compressor *this;) + + D1(printk(KERN_DEBUG "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"); + return -1; + } + list_del(&comp->list); + + D2(list_for_each_entry(this, &jffs2_compressor_list, list) { + printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); + }) + spin_unlock(&jffs2_compressor_list_lock); + return 0; +} + +#ifdef CONFIG_JFFS2_PROC + +#define JFFS2_STAT_BUF_SIZE 16000 + +char *jffs2_list_compressors(void) +{ + struct jffs2_compressor *this; + char *buf, *act_buf; + + act_buf = buf = kmalloc(JFFS2_STAT_BUF_SIZE,GFP_KERNEL); + list_for_each_entry(this, &jffs2_compressor_list, list) { + act_buf += sprintf(act_buf, "%10s priority:%d ", this->name, this->priority); + if ((this->disabled)||(!this->compress)) + act_buf += sprintf(act_buf,"disabled"); + else + act_buf += sprintf(act_buf,"enabled"); + act_buf += sprintf(act_buf,"\n"); + } + return buf; +} + +char *jffs2_stats(void) +{ + struct jffs2_compressor *this; + char *buf, *act_buf; + + act_buf = buf = kmalloc(JFFS2_STAT_BUF_SIZE,GFP_KERNEL); + + act_buf += sprintf(act_buf,"JFFS2 compressor statistics:\n"); + act_buf += sprintf(act_buf,"%10s ","none"); + act_buf += sprintf(act_buf,"compr: %d blocks (%d) decompr: %d blocks\n", none_stat_compr_blocks, + none_stat_compr_size, none_stat_decompr_blocks); + spin_lock(&jffs2_compressor_list_lock); + list_for_each_entry(this, &jffs2_compressor_list, list) { + act_buf += sprintf(act_buf,"%10s ",this->name); + if ((this->disabled)||(!this->compress)) + act_buf += sprintf(act_buf,"- "); + else + act_buf += sprintf(act_buf,"+ "); + act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d) decompr: %d blocks ", this->stat_compr_blocks, + this->stat_compr_new_size, this->stat_compr_orig_size, + this->stat_decompr_blocks); + act_buf += sprintf(act_buf,"\n"); + } + spin_unlock(&jffs2_compressor_list_lock); + + return buf; +} + +char *jffs2_get_compression_mode_name(void) +{ + switch (jffs2_compression_mode) { + case JFFS2_COMPR_MODE_NONE: + return "none"; + case JFFS2_COMPR_MODE_PRIORITY: + return "priority"; + case JFFS2_COMPR_MODE_SIZE: + return "size"; + } + return "unkown"; +} + +int jffs2_set_compression_mode_name(const char *name) +{ + if (!strcmp("none",name)) { + jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; + return 0; + } + if (!strcmp("priority",name)) { + jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY; + return 0; + } + if (!strcmp("size",name)) { + jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; + return 0; + } + return 1; +} + +static int jffs2_compressor_Xable(const char *name, int disabled) +{ + struct jffs2_compressor *this; + spin_lock(&jffs2_compressor_list_lock); + list_for_each_entry(this, &jffs2_compressor_list, list) { + if (!strcmp(this->name, name)) { + this->disabled = disabled; + spin_unlock(&jffs2_compressor_list_lock); + return 0; + } + } + spin_unlock(&jffs2_compressor_list_lock); + printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name); + return 1; +} + +int jffs2_enable_compressor_name(const char *name) +{ + return jffs2_compressor_Xable(name, 0); +} + +int jffs2_disable_compressor_name(const char *name) +{ + return jffs2_compressor_Xable(name, 1); +} + +int jffs2_set_compressor_priority(const char *name, int priority) +{ + struct jffs2_compressor *this,*comp; + spin_lock(&jffs2_compressor_list_lock); + list_for_each_entry(this, &jffs2_compressor_list, list) { + if (!strcmp(this->name, name)) { + this->priority = priority; + comp = this; + goto reinsert; + } + } + spin_unlock(&jffs2_compressor_list_lock); + printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name); + return 1; +reinsert: + /* list is sorted in the order of priority, so if + we change it we have to reinsert it into the + good place */ + list_del(&comp->list); + list_for_each_entry(this, &jffs2_compressor_list, list) { + if (this->priority < comp->priority) { + list_add(&comp->list, this->list.prev); + spin_unlock(&jffs2_compressor_list_lock); + return 0; + } + } + list_add_tail(&comp->list, &jffs2_compressor_list); + spin_unlock(&jffs2_compressor_list_lock); + return 0; +} + #endif -#ifdef JFFS2_USE_RTIME - case JFFS2_COMPR_RTIME: - jffs2_rtime_decompress(cdata_in, data_out, cdatalen, datalen); - break; + +void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig) +{ + if (orig != comprbuf) + kfree(comprbuf); +} + +int jffs2_compressors_init(void) +{ +/* Registering compressors */ +#ifdef CONFIG_JFFS2_ZLIB + jffs2_zlib_init(); #endif -#ifdef JFFS2_USE_RUBINMIPS - case JFFS2_COMPR_RUBINMIPS: - jffs2_rubinmips_decompress(cdata_in, data_out, cdatalen, datalen); - break; +#ifdef CONFIG_JFFS2_RTIME + jffs2_rtime_init(); +#endif +#ifdef CONFIG_JFFS2_RUBIN + jffs2_rubinmips_init(); + jffs2_dynrubin_init(); +#endif +#ifdef CONFIG_JFFS2_LZARI + jffs2_lzari_init(); +#endif +#ifdef CONFIG_JFFS2_LZO + jffs2_lzo_init(); +#endif +/* 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");) +#else +#ifdef CONFIG_JFFS2_CMODE_SIZE + jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; + D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");) +#else + D1(printk(KERN_INFO "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_LZO + jffs2_lzo_exit(); #endif - default: - printk(KERN_NOTICE "Unknown JFFS2 compression type 0x%02x\n", comprtype); - return -EIO; - } - return 0; +#ifdef CONFIG_JFFS2_LZARI + jffs2_lzari_exit(); +#endif +#ifdef CONFIG_JFFS2_RUBIN + jffs2_dynrubin_exit(); + jffs2_rubinmips_exit(); +#endif +#ifdef CONFIG_JFFS2_RTIME + jffs2_rtime_exit(); +#endif +#ifdef CONFIG_JFFS2_ZLIB + jffs2_zlib_exit(); +#endif + return 0; } Index: fs/jffs2/current/src/compr_rtime.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/compr_rtime.c,v retrieving revision 1.5 diff -u -r1.5 compr_rtime.c --- fs/jffs2/current/src/compr_rtime.c 20 Nov 2003 16:52:36 -0000 1.5 +++ fs/jffs2/current/src/compr_rtime.c 12 Aug 2004 21:29:23 -0000 @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: compr_rtime.c,v 1.11 2003/10/04 08:33:06 dwmw2 Exp $ + * $Id: compr_rtime.c,v 1.14 2004/06/23 16:34:40 havasi Exp $ * * * Very simple lz77-ish encoder. @@ -25,10 +25,12 @@ #include #include #include +#include +#include "compr.h" /* _compress returns the compressed size, -1 if bigger */ int jffs2_rtime_compress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t *sourcelen, uint32_t *dstlen) + uint32_t *sourcelen, uint32_t *dstlen, void *model) { short positions[256]; int outpos = 0; @@ -67,8 +69,8 @@ } -void jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t srclen, uint32_t destlen) +int jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t srclen, uint32_t destlen, void *model) { short positions[256]; int outpos = 0; @@ -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: fs/jffs2/current/src/compr_rubin.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/compr_rubin.c,v retrieving revision 1.3 diff -u -r1.3 compr_rubin.c --- fs/jffs2/current/src/compr_rubin.c 5 Feb 2003 00:00:40 -0000 1.3 +++ fs/jffs2/current/src/compr_rubin.c 12 Aug 2004 21:29:23 -0000 @@ -7,17 +7,17 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: compr_rubin.c,v 1.17 2002/05/20 14:56:37 dwmw2 Exp $ + * $Id: compr_rubin.c,v 1.20 2004/06/23 16:34:40 havasi Exp $ * */ #include #include +#include #include "compr_rubin.h" #include "histo_mips.h" - - +#include "compr.h" static void init_rubin(struct rubin_state *rs, int div, int *bits) { @@ -223,13 +223,13 @@ #if 0 /* _compress returns the compressed size, -1 if bigger */ int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t *sourcelen, uint32_t *dstlen) + uint32_t *sourcelen, uint32_t *dstlen, void *model) { return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); } #endif int jffs2_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t *sourcelen, uint32_t *dstlen) + uint32_t *sourcelen, uint32_t *dstlen, void *model) { int bits[8]; unsigned char histo[256]; @@ -306,14 +306,15 @@ } -void jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t sourcelen, uint32_t dstlen) +int jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t sourcelen, uint32_t dstlen, void *model) { 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, - uint32_t sourcelen, uint32_t dstlen) +int jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t sourcelen, uint32_t dstlen, void *model) { int bits[8]; int c; @@ -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: fs/jffs2/current/src/compr_zlib.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/compr_zlib.c,v retrieving revision 1.6 diff -u -r1.6 compr_zlib.c --- fs/jffs2/current/src/compr_zlib.c 11 Dec 2003 23:33:54 -0000 1.6 +++ fs/jffs2/current/src/compr_zlib.c 12 Aug 2004 21:29:24 -0000 @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: compr_zlib.c,v 1.25 2003/12/03 09:25:43 dwmw2 Exp $ + * $Id: compr_zlib.c,v 1.28 2004/06/23 16:34:40 havasi Exp $ * */ @@ -22,6 +22,7 @@ #include #include #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 #include -int __init jffs2_zlib_init(void) +static int __init alloc_workspaces(void) { def_strm.workspace = vmalloc(zlib_deflate_workspacesize()); if (!def_strm.workspace) { @@ -58,15 +59,18 @@ 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, - uint32_t *sourcelen, uint32_t *dstlen) + uint32_t *sourcelen, uint32_t *dstlen, void *model) { int ret; @@ -131,8 +135,8 @@ return ret; } -void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t srclen, uint32_t destlen) +int jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t srclen, uint32_t destlen, void *model) { int ret; int wbits = MAX_WBITS; @@ -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: fs/jffs2/current/src/erase.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/erase.c,v retrieving revision 1.6 diff -u -r1.6 erase.c --- fs/jffs2/current/src/erase.c 11 Dec 2003 23:33:54 -0000 1.6 +++ fs/jffs2/current/src/erase.c 12 Aug 2004 21:29:24 -0000 @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: erase.c,v 1.58 2003/11/26 13:02:46 dwmw2 Exp $ + * $Id: erase.c,v 1.60 2004/06/30 17:26:15 dbrown Exp $ * */ @@ -28,7 +28,7 @@ #ifndef __ECOS static void jffs2_erase_callback(struct erase_info *); #endif -static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); +static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset); static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); @@ -36,12 +36,14 @@ void jffs2_erase_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) { int ret; + uint32_t bad_offset; #ifdef __ECOS ret = jffs2_flash_erase(c, jeb); if (!ret) { jffs2_erase_succeeded(c, jeb); return; } + bad_offset = jeb->offset; #else /* Linux */ struct erase_info *instr; @@ -65,18 +67,16 @@ instr->len = c->sector_size; instr->callback = jffs2_erase_callback; instr->priv = (unsigned long)(&instr[1]); + instr->fail_addr = 0xffffffff; ((struct erase_priv_struct *)instr->priv)->jeb = jeb; ((struct erase_priv_struct *)instr->priv)->c = c; - /* NAND , read out the fail counter, if possible */ - if (!jffs2_can_mark_obsolete(c)) - jffs2_nand_read_failcnt(c,jeb); - ret = c->mtd->erase(c->mtd, instr); if (!ret) return; + bad_offset = instr->fail_addr; kfree(instr); #endif /* __ECOS */ @@ -98,7 +98,7 @@ else printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret); - jffs2_erase_failed(c, jeb); + jffs2_erase_failed(c, jeb, bad_offset); } void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count) @@ -166,16 +166,34 @@ jffs2_erase_pending_trigger(c); } -static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) +static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset) { - spin_lock(&c->erase_completion_lock); - c->erasing_size -= c->sector_size; - c->bad_size += c->sector_size; - list_del(&jeb->list); - list_add(&jeb->list, &c->bad_list); - c->nr_erasing_blocks--; - spin_unlock(&c->erase_completion_lock); - wake_up(&c->erase_wait); + /* For NAND, if the failure did not occur at the device level for a + specific physical page, don't bother updating the bad block table. */ + if (jffs2_cleanmarker_oob(c) && (bad_offset != 0xffffffff)) { + /* We had a device-level failure to erase. Let's see if we've + failed too many times. */ + if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) { + /* We'd like to give this block another try. */ + spin_lock(&c->erase_completion_lock); + list_del(&jeb->list); + list_add(&jeb->list, &c->erase_pending_list); + c->erasing_size -= c->sector_size; + c->dirty_size += c->sector_size; + jeb->dirty_size = c->sector_size; + spin_unlock(&c->erase_completion_lock); + return; + } + } + + spin_lock(&c->erase_completion_lock); + c->erasing_size -= c->sector_size; + c->bad_size += c->sector_size; + list_del(&jeb->list); + list_add(&jeb->list, &c->bad_list); + c->nr_erasing_blocks--; + spin_unlock(&c->erase_completion_lock); + wake_up(&c->erase_wait); } #ifndef __ECOS @@ -185,7 +203,7 @@ if(instr->state != MTD_ERASE_DONE) { printk(KERN_WARNING "Erase at 0x%08x finished, but state != MTD_ERASE_DONE. State is 0x%x instead.\n", instr->addr, instr->state); - jffs2_erase_failed(priv->c, priv->jeb); + jffs2_erase_failed(priv->c, priv->jeb, instr->fail_addr); } else { jffs2_erase_succeeded(priv->c, priv->jeb); } @@ -289,6 +307,7 @@ unsigned char *ebuf; size_t retlen; int ret; + uint32_t bad_offset; if (!jffs2_cleanmarker_oob(c)) { marker_ref = jffs2_alloc_raw_node_ref(); @@ -313,6 +332,8 @@ uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs); int i; + bad_offset = ofs; + ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf); if (ret) { printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret); @@ -326,22 +347,21 @@ /* It's OK. We know it's properly aligned */ unsigned long datum = *(unsigned long *)(&ebuf[i]); if (datum + 1) { - printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, ofs + i); + bad_offset += i; + printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, bad_offset); bad: if (!jffs2_cleanmarker_oob(c)) jffs2_free_raw_node_ref(marker_ref); - else - jffs2_write_nand_badblock( c ,jeb ); kfree(ebuf); bad2: spin_lock(&c->erase_completion_lock); - c->erasing_size -= c->sector_size; - c->bad_size += c->sector_size; - - list_add_tail(&jeb->list, &c->bad_list); - c->nr_erasing_blocks--; + /* Stick it on a list (any list) so + erase_failed can take it right off + again. Silly, but shouldn't happen + often. */ + list_add(&jeb->list, &c->erasing_list); spin_unlock(&c->erase_completion_lock); - wake_up(&c->erase_wait); + jffs2_erase_failed(c, jeb, bad_offset); return; } } @@ -350,7 +370,9 @@ } kfree(ebuf); } - + + bad_offset = jeb->offset; + /* Write the erase complete marker */ D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset)); if (jffs2_cleanmarker_oob(c)) { Index: fs/jffs2/current/src/fs-ecos.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/fs-ecos.c,v retrieving revision 1.27 diff -u -r1.27 fs-ecos.c --- fs/jffs2/current/src/fs-ecos.c 21 Apr 2004 18:51:21 -0000 1.27 +++ fs/jffs2/current/src/fs-ecos.c 12 Aug 2004 21:29:26 -0000 @@ -1420,7 +1420,7 @@ // Check that pos is still within current file size, or at the // very end. - if (pos < 0 || pos > node->i_size) + if (pos < 0 ) return EINVAL; // All OK, set fp offset and return new position. Index: fs/jffs2/current/src/gc.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/gc.c,v retrieving revision 1.7 diff -u -r1.7 gc.c --- fs/jffs2/current/src/gc.c 1 Apr 2004 03:17:57 -0000 1.7 +++ fs/jffs2/current/src/gc.c 12 Aug 2004 21:29:28 -0000 @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: gc.c,v 1.133 2004/03/08 15:29:09 dwmw2 Exp $ + * $Id: gc.c,v 1.137 2004/07/20 13:44:55 dwmw2 Exp $ * */ @@ -19,6 +19,7 @@ #include #include #include "nodelist.h" +#include "compr.h" static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, @@ -80,7 +81,7 @@ nextlist = &c->erasable_list; } else { /* Eep. All were empty */ - printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n"); + D1(printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n")); return NULL; } @@ -204,7 +205,7 @@ jeb = jffs2_find_gc_block(c); if (!jeb) { - printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n"); + D1 (printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n")); spin_unlock(&c->erase_completion_lock); up(&c->alloc_sem); return -EIO; @@ -358,10 +359,14 @@ spin_unlock(&c->inocache_lock); f = jffs2_gc_fetch_inode(c, inum, nlink); - if (IS_ERR(f)) - return PTR_ERR(f); - if (!f) - return 0; + if (IS_ERR(f)) { + ret = PTR_ERR(f); + goto release_sem; + } + if (!f) { + ret = 0; + goto release_sem; + } ret = jffs2_garbage_collect_live(c, jeb, raw, f); @@ -1176,7 +1181,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 +1214,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: fs/jffs2/current/src/nodelist.h =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/nodelist.h,v retrieving revision 1.7 diff -u -r1.7 nodelist.h --- fs/jffs2/current/src/nodelist.h 1 Apr 2004 03:17:57 -0000 1.7 +++ fs/jffs2/current/src/nodelist.h 12 Aug 2004 21:29:29 -0000 @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: nodelist.h,v 1.116 2004/03/08 15:29:09 dwmw2 Exp $ + * $Id: nodelist.h,v 1.119 2004/05/26 12:28:12 gleixner Exp $ * */ @@ -44,6 +44,39 @@ #define D2(x) #endif +#define JFFS2_NATIVE_ENDIAN + +/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from + whatever OS we're actually running on here too. */ + +#if defined(JFFS2_NATIVE_ENDIAN) +#define cpu_to_je16(x) ((jint16_t){x}) +#define cpu_to_je32(x) ((jint32_t){x}) +#define cpu_to_jemode(x) ((jmode_t){os_to_jffs2_mode(x)}) + +#define je16_to_cpu(x) ((x).v16) +#define je32_to_cpu(x) ((x).v32) +#define jemode_to_cpu(x) (jffs2_to_os_mode((x).m)) +#elif defined(JFFS2_BIG_ENDIAN) +#define cpu_to_je16(x) ((jint16_t){cpu_to_be16(x)}) +#define cpu_to_je32(x) ((jint32_t){cpu_to_be32(x)}) +#define cpu_to_jemode(x) ((jmode_t){cpu_to_be32(os_to_jffs2_mode(x))}) + +#define je16_to_cpu(x) (be16_to_cpu(x.v16)) +#define je32_to_cpu(x) (be32_to_cpu(x.v32)) +#define jemode_to_cpu(x) (be32_to_cpu(jffs2_to_os_mode((x).m))) +#elif defined(JFFS2_LITTLE_ENDIAN) +#define cpu_to_je16(x) ((jint16_t){cpu_to_le16(x)}) +#define cpu_to_je32(x) ((jint32_t){cpu_to_le32(x)}) +#define cpu_to_jemode(x) ((jmode_t){cpu_to_le32(os_to_jffs2_mode(x))}) + +#define je16_to_cpu(x) (le16_to_cpu(x.v16)) +#define je32_to_cpu(x) (le32_to_cpu(x.v32)) +#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m))) +#else +#error wibble +#endif + /* This is all we need to keep in-core for each raw node during normal operation. As and when we do read_inode on a particular inode, we can @@ -439,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); @@ -465,11 +489,6 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c); int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); 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: fs/jffs2/current/src/os-ecos.h =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/os-ecos.h,v retrieving revision 1.8 diff -u -r1.8 os-ecos.h --- fs/jffs2/current/src/os-ecos.h 11 Dec 2003 23:33:55 -0000 1.8 +++ fs/jffs2/current/src/os-ecos.h 12 Aug 2004 21:29:29 -0000 @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: os-ecos.h,v 1.19 2003/11/28 11:38:45 dwmw2 Exp $ + * $Id: os-ecos.h,v 1.20 2004/05/05 12:00:31 dwmw2 Exp $ * */ @@ -191,8 +191,8 @@ #define jffs2_flush_wbuf_pad(c) ({ (void)(c), 0; }) #define jffs2_flush_wbuf_gc(c, i) ({ (void)(c), (void) i, 0; }) #define jffs2_nand_read_failcnt(c,jeb) do { ; } while(0) -#define jffs2_write_nand_badblock(c,jeb) do { ; } while(0) -#define jffs2_nand_flash_setup(c) (0) +#define jffs2_write_nand_badblock(c,jeb,p) (0) +#define jffs2_flash_setup(c) (0) #define jffs2_nand_flash_cleanup(c) do {} while(0) #define jffs2_wbuf_dirty(c) (0) #define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e) @@ -206,4 +206,6 @@ #define BUG_ON(x) do { if (unlikely(x)) BUG(); } while(0) #endif +#define __init + #endif /* __JFFS2_OS_ECOS_H__ */ Index: fs/jffs2/current/src/read.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/read.c,v retrieving revision 1.6 diff -u -r1.6 read.c --- fs/jffs2/current/src/read.c 1 Apr 2004 03:17:57 -0000 1.6 +++ fs/jffs2/current/src/read.c 12 Aug 2004 21:29:29 -0000 @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: read.c,v 1.35 2004/03/08 15:29:09 dwmw2 Exp $ + * $Id: read.c,v 1.36 2004/05/25 11:12:32 havasi Exp $ * */ @@ -18,6 +18,7 @@ #include #include #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: fs/jffs2/current/src/scan.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/scan.c,v retrieving revision 1.6 diff -u -r1.6 scan.c --- fs/jffs2/current/src/scan.c 1 Apr 2004 03:17:57 -0000 1.6 +++ fs/jffs2/current/src/scan.c 12 Aug 2004 21:29:30 -0000 @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: scan.c,v 1.109 2004/03/19 16:40:50 dwmw2 Exp $ + * $Id: scan.c,v 1.111 2004/07/27 14:13:43 gleixner Exp $ * */ #include @@ -104,6 +104,10 @@ else buf_size = PAGE_SIZE; + /* Respect kmalloc limitations */ + if (buf_size > 128*1024) + buf_size = 128*1024; + D1(printk(KERN_DEBUG "Allocating readbuf of %d bytes\n", buf_size)); flashbuf = kmalloc(buf_size, GFP_KERNEL); if (!flashbuf) @@ -337,8 +341,6 @@ switch (ret) { case 0: return cleanmarkerfound ? BLK_STATE_CLEANMARKER : BLK_STATE_ALLFF; case 1: return BLK_STATE_ALLDIRTY; - case 2: return BLK_STATE_BADBLOCK; /* case 2/3 are paranoia checks */ - case 3: return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */ default: return ret; } } Index: fs/jffs2/current/src/write.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/write.c,v retrieving revision 1.7 diff -u -r1.7 write.c --- fs/jffs2/current/src/write.c 1 Apr 2004 03:17:57 -0000 1.7 +++ fs/jffs2/current/src/write.c 12 Aug 2004 21:29:31 -0000 @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: write.c,v 1.83 2004/03/30 09:36:09 dwmw2 Exp $ + * $Id: write.c,v 1.85 2004/07/13 08:58:25 dwmw2 Exp $ * */ @@ -18,6 +18,7 @@ #include #include #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) @@ -91,7 +92,7 @@ struct jffs2_raw_node_ref *raw; struct jffs2_full_dnode *fn; size_t retlen; - struct iovec vecs[2]; + struct kvec vecs[2]; int ret; int retried = 0; unsigned long cnt = 2; @@ -232,7 +233,7 @@ struct jffs2_raw_node_ref *raw; struct jffs2_full_dirent *fd; size_t retlen; - struct iovec vecs[2]; + struct kvec vecs[2]; int retried = 0; int ret; @@ -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)); Index: compat/linux/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/compat/linux/current/ChangeLog,v retrieving revision 1.5 diff -u -r1.5 ChangeLog --- compat/linux/current/ChangeLog 20 Nov 2003 08:24:58 -0000 1.5 +++ compat/linux/current/ChangeLog 12 Aug 2004 21:29:31 -0000 @@ -1,3 +1,13 @@ +2004-08-12 Andrew Lunn + + * include/linux/spinlock.h: Add CYG_UNUSED_PARAM() calls to avoid + compiler warnings. + +2004-08-04 Gary Thomas + + * include/linux/list.h (list_for_each_entry): New macro needed for + latest jffs2 code. + 2003-11-12 Thomas Koeller * cdl/linux.cdl: Index: compat/linux/current/include/linux/list.h =================================================================== RCS file: /cvs/ecos/ecos/packages/compat/linux/current/include/linux/list.h,v retrieving revision 1.1 diff -u -r1.1 list.h --- compat/linux/current/include/linux/list.h 22 Jan 2003 01:10:41 -0000 1.1 +++ compat/linux/current/include/linux/list.h 12 Aug 2004 21:29:31 -0000 @@ -63,6 +63,11 @@ /* MACROS */ +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + #define INIT_LIST_HEAD( _list_ ) \ CYG_MACRO_START \ (_list_)->next = (_list_)->prev = (_list_); \ @@ -122,6 +127,15 @@ (_ent_) != (_list_); \ (_ent_) = (_ent_)->next ) +/* + * list_for_each_entry - this function can be use to iterate over all + * items in a list* _list_ with it's head at _head_ and link _item_ + */ +#define list_for_each_entry(_list_, _head_, _item_) \ +for ((_list_) = list_entry((_head_)->next, typeof(*_list_), _item_); \ + &((_list_)->_item_) != (_head_); \ + (_list_) = list_entry((_list_)->_item_.next, typeof(*_list_), _item_)) + /* -----------------------------------------------------------------------*/ #endif /* #ifndef CYGONCE_FS_JFFS2_LIST_H */ /* EOF list.h */ Index: compat/linux/current/include/linux/spinlock.h =================================================================== RCS file: /cvs/ecos/ecos/packages/compat/linux/current/include/linux/spinlock.h,v retrieving revision 1.1 diff -u -r1.1 spinlock.h --- compat/linux/current/include/linux/spinlock.h 22 Jan 2003 01:10:41 -0000 1.1 +++ compat/linux/current/include/linux/spinlock.h 12 Aug 2004 21:29:31 -0000 @@ -4,10 +4,30 @@ typedef struct { } spinlock_t; #define SPIN_LOCK_UNLOCKED (spinlock_t) { } -#define spin_lock_init(lock) do{} while (0) -#define spin_lock(lock) do{} while (0) -#define spin_unlock(lock) do{} while (0) -#define spin_lock_bh(lock) do{} while (0) -#define spin_unlock_bh(lock) do{} while (0) + +#define spin_lock_init(lock) \ +CYG_MACRO_START; \ +CYG_UNUSED_PARAM(spinlock_t *, lock); \ +CYG_MACRO_END + +#define spin_lock(lock) \ +CYG_MACRO_START; \ +CYG_UNUSED_PARAM(spinlock_t *, lock); \ +CYG_MACRO_END + +#define spin_unlock(lock) \ +CYG_MACRO_START; \ +CYG_UNUSED_PARAM(spinlock_t *, lock); \ +CYG_MACRO_END + +#define spin_lock_bh(lock) \ +CYG_MACRO_START; \ +CYG_UNUSED_PARAM(spinlock_t *, lock); \ +CYG_MACRO_END + +#define spin_unlock_bh(lock) \ +CYG_MACRO_START; \ +CYG_UNUSED_PARAM(spinlock_t *, lock); \ +CYG_MACRO_END #endif /* __LINUX_SPINLOCK_H__ */ Index: compat/linux/current/include/linux/types.h =================================================================== RCS file: /cvs/ecos/ecos/packages/compat/linux/current/include/linux/types.h,v retrieving revision 1.1 diff -u -r1.1 types.h --- compat/linux/current/include/linux/types.h 22 Jan 2003 01:10:42 -0000 1.1 +++ compat/linux/current/include/linux/types.h 12 Aug 2004 21:29:31 -0000 @@ -8,5 +8,6 @@ #define uint32_t cyg_uint32 #define loff_t off_t +#define kvec iovec #endif /* __LINUX_TYPES_H__ */