JFFS2: Add RTEMS support

This commit is contained in:
Sebastian Huber committed 2013-09-19 13:16:06 +02:00
1 parent 78b85286f0
commit 3c96bee3f9
24 files changed
+2032 -2969

No files matched your search

+3
View File
@@ -120,6 +120,9 @@ include_rtems_rfs_HEADERS += libfs/src/rfs/rtems-rfs-link.h
include_rtems_rfs_HEADERS += libfs/src/rfs/rtems-rfs-mutex.h
include_rtems_rfs_HEADERS += libfs/src/rfs/rtems-rfs-trace.h
# JFFS2
include_rtems_HEADERS += libfs/src/jffs2/include/rtems/jffs2.h
## libblock
include_rtems_HEADERS += libblock/include/rtems/bdbuf.h
include_rtems_HEADERS += libblock/include/rtems/blkdev.h
+1
View File
@@ -1437,6 +1437,7 @@ extern int rtems_mkdir(const char *path, mode_t mode);
#define RTEMS_FILESYSTEM_TYPE_NFS "nfs"
#define RTEMS_FILESYSTEM_TYPE_DOSFS "dosfs"
#define RTEMS_FILESYSTEM_TYPE_RFS "rfs"
#define RTEMS_FILESYSTEM_TYPE_JFFS2 "jffs2"
/** @} */
+29
View File
@@ -102,6 +102,35 @@ librfs_a_SOURCES = \
src/rfs/rtems-rfs-rtems-dir.c src/rfs/rtems-rfs-rtems-file.c \
src/rfs/rtems-rfs-trace.c
# JFFS2
noinst_LIBRARIES += libjffs2.a
libjffs2_a_SOURCES =
libjffs2_a_SOURCES += src/jffs2/src/build.c
libjffs2_a_SOURCES += src/jffs2/src/compat-crc32.c
libjffs2_a_SOURCES += src/jffs2/src/compat-rbtree.c
libjffs2_a_SOURCES += src/jffs2/src/compr.c
libjffs2_a_SOURCES += src/jffs2/src/compr_rtime.c
libjffs2_a_SOURCES += src/jffs2/src/compr_zlib.c
libjffs2_a_SOURCES += src/jffs2/src/debug.c
libjffs2_a_SOURCES += src/jffs2/src/dir-rtems.c
libjffs2_a_SOURCES += src/jffs2/src/erase.c
libjffs2_a_SOURCES += src/jffs2/src/flashio.c
libjffs2_a_SOURCES += src/jffs2/src/fs-rtems.c
libjffs2_a_SOURCES += src/jffs2/src/gc.c
libjffs2_a_SOURCES += src/jffs2/src/malloc-rtems.c
libjffs2_a_SOURCES += src/jffs2/src/nodelist.c
libjffs2_a_SOURCES += src/jffs2/src/nodemgmt.c
libjffs2_a_SOURCES += src/jffs2/src/read.c
libjffs2_a_SOURCES += src/jffs2/src/readinode.c
libjffs2_a_SOURCES += src/jffs2/src/scan.c
libjffs2_a_SOURCES += src/jffs2/src/write.c
libjffs2_a_CFLAGS =
libjffs2_a_CFLAGS += -Wno-pointer-sign
libjffs2_a_CPPFLAGS =
libjffs2_a_CPPFLAGS += $(AM_CPPFLAGS) -I$(srcdir)/src/jffs2/include
libjffs2_a_CPPFLAGS += -D__ECOS
libjffs2_a_CPPFLAGS += '-DKBUILD_MODNAME="JFFS2"'
# ---
include $(srcdir)/preinstall.am
include $(top_srcdir)/automake/subdirs.am
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -78,7 +78,7 @@ 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);
#define jffs2_free_comprbuf(x, y) do { } while (0)
/* Compressor modules */
/* These functions will be called by jffs2_compressors_init/exit */
+25 -32
View File
@@ -28,15 +28,20 @@
#include <linux/jffs2.h>
#include "compr.h"
/* _compress returns the compressed size, -1 if bigger */
static int jffs2_rtime_compress(unsigned char *data_in,
unsigned char *cpage_out,
uint32_t *sourcelen, uint32_t *dstlen)
uint16_t rtems_jffs2_compressor_rtime_compress(
rtems_jffs2_compressor_control *self,
unsigned char *data_in,
unsigned char *cpage_out,
uint32_t *sourcelen,
uint32_t *dstlen
)
{
short positions[256];
int outpos = 0;
int pos=0;
(void) self;
memset(positions,0,sizeof(positions));
while (pos < (*sourcelen) && outpos <= (*dstlen)-2) {
@@ -60,24 +65,35 @@ static int jffs2_rtime_compress(unsigned char *data_in,
if (outpos >= pos) {
/* We failed */
return -1;
return JFFS2_COMPR_NONE;
}
/* Tell the caller how much we managed to compress, and how much space it took */
*sourcelen = pos;
*dstlen = outpos;
return 0;
return JFFS2_COMPR_RTIME;
}
static int jffs2_rtime_decompress(unsigned char *data_in,
unsigned char *cpage_out,
uint32_t srclen, uint32_t destlen)
int rtems_jffs2_compressor_rtime_decompress(
rtems_jffs2_compressor_control *self,
uint16_t comprtype,
unsigned char *data_in,
unsigned char *cpage_out,
uint32_t srclen,
uint32_t destlen
)
{
short positions[256];
int outpos = 0;
int pos=0;
(void) self;
if (comprtype != JFFS2_COMPR_RTIME) {
return -EIO;
}
memset(positions,0,sizeof(positions));
while (outpos<destlen) {
@@ -105,26 +121,3 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
}
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);
}
File diff suppressed because it is too large. Load diff
+18
View File
@@ -75,6 +75,7 @@ do { \
#define JFFS2_DBG_MSG_PREFIX JFFS2_DBG JFFS2_DBG_PREFIX
/* JFFS2 message macros */
#ifndef __rtems__
#define JFFS2_ERROR(fmt, ...) \
pr_err("error: (%d) %s: " fmt, \
task_pid_nr(current), __func__, ##__VA_ARGS__)
@@ -90,6 +91,23 @@ do { \
#define JFFS2_DEBUG(fmt, ...) \
printk(KERN_DEBUG "[JFFS2 DBG] (%d) %s: " fmt, \
task_pid_nr(current), __func__, ##__VA_ARGS__)
#else /* __rtems__ */
#define JFFS2_ERROR(fmt, ...) \
pr_err("error: %s: " fmt, \
__func__, ##__VA_ARGS__)
#define JFFS2_WARNING(fmt, ...) \
pr_warn("warning: %s: " fmt, \
__func__, ##__VA_ARGS__)
#define JFFS2_NOTICE(fmt, ...) \
pr_notice("notice: %s: " fmt, \
__func__, ##__VA_ARGS__)
#define JFFS2_DEBUG(fmt, ...) \
printk(KERN_DEBUG "[JFFS2 DBG] %s: " fmt, \
__func__, ##__VA_ARGS__)
#endif /* __rtems__ */
/*
* We split our debugging messages on several parts, depending on the JFFS2
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -391,7 +391,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
*bad_offset = ofs;
ret = mtd_read(c->mtd, ofs, readlen, &retlen, ebuf);
ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf);
if (ret) {
pr_warn("Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n",
ofs, ret);
+14 -46
View File
@@ -15,46 +15,28 @@
#include <linux/kernel.h>
#include "nodelist.h"
#include <cyg/io/io.h>
#include <cyg/io/config_keys.h>
#include <cyg/io/flash.h>
cyg_bool jffs2_flash_read(struct jffs2_sb_info * c,
int jffs2_flash_read(struct jffs2_sb_info * c,
cyg_uint32 read_buffer_offset, const size_t size,
size_t * return_size, unsigned char *write_buffer)
{
Cyg_ErrNo err;
cyg_uint32 len = size;
struct super_block *sb = OFNI_BS_2SFFJ(c);
const struct super_block *sb = OFNI_BS_2SFFJ(c);
rtems_jffs2_flash_control *fc = sb->s_flash_control;
//D2(printf("FLASH READ\n"));
//D2(printf("read address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + read_buffer_offset));
//D2(printf("write address = %x\n", write_buffer));
//D2(printf("size = %x\n", size));
err = cyg_io_bread(sb->s_dev, write_buffer, &len, read_buffer_offset);
*return_size = size;
*return_size = (size_t) len;
return ((err == ENOERR) ? ENOERR : -EIO);
return (*fc->read)(fc, read_buffer_offset, write_buffer, size);
}
cyg_bool jffs2_flash_write(struct jffs2_sb_info * c,
int jffs2_flash_write(struct jffs2_sb_info * c,
cyg_uint32 write_buffer_offset, const size_t size,
size_t * return_size, unsigned char *read_buffer)
{
const struct super_block *sb = OFNI_BS_2SFFJ(c);
rtems_jffs2_flash_control *fc = sb->s_flash_control;
Cyg_ErrNo err;
cyg_uint32 len = size;
struct super_block *sb = OFNI_BS_2SFFJ(c);
*return_size = size;
// D2(printf("FLASH WRITE ENABLED!!!\n"));
// D2(printf("write address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + write_buffer_offset));
// D2(printf("read address = %x\n", read_buffer));
// D2(printf("size = %x\n", size));
err = cyg_io_bwrite(sb->s_dev, read_buffer, &len, write_buffer_offset);
*return_size = (size_t) len;
return ((err == ENOERR) ? ENOERR : -EIO);
return (*fc->write)(fc, write_buffer_offset, read_buffer, size);
}
int
@@ -140,26 +122,12 @@ jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
return ret;
}
cyg_bool jffs2_flash_erase(struct jffs2_sb_info * c,
int jffs2_flash_erase(struct jffs2_sb_info * c,
struct jffs2_eraseblock * jeb)
{
cyg_io_flash_getconfig_erase_t e;
cyg_flashaddr_t err_addr;
Cyg_ErrNo err;
cyg_uint32 len = sizeof (e);
struct super_block *sb = OFNI_BS_2SFFJ(c);
const struct super_block *sb = OFNI_BS_2SFFJ(c);
rtems_jffs2_flash_control *fc = sb->s_flash_control;
e.offset = jeb->offset;
e.len = c->sector_size;
e.err_address = &err_addr;
// D2(printf("FLASH ERASE ENABLED!!!\n"));
// D2(printf("erase address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + jeb->offset));
// D2(printf("size = %x\n", c->sector_size));
err = cyg_io_get_config(sb->s_dev, CYG_IO_GET_CONFIG_FLASH_ERASE,
&e, &len);
return (err != ENOERR || e.flasherr != 0);
return (*fc->erase)(fc, jeb->offset);
}
File diff suppressed because it is too large. Load diff
+6
View File
@@ -741,7 +741,9 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
struct jffs2_full_dnode *new_fn;
struct jffs2_raw_inode ri;
struct jffs2_node_frag *last_frag;
#ifndef __rtems__
union jffs2_device_node dev;
#endif /* __rtems__ */
char *mdata = NULL;
int mdatalen = 0;
uint32_t alloclen, ilen;
@@ -749,11 +751,15 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
if (S_ISBLK(JFFS2_F_I_MODE(f)) ||
S_ISCHR(JFFS2_F_I_MODE(f)) ) {
#ifndef __rtems__
/* For these, we don't actually need to read the old node */
mdatalen = jffs2_encode_dev(&dev, JFFS2_F_I_RDEV(f));
mdata = (char *)&dev;
jffs2_dbg(1, "%s(): Writing %d bytes of kdev_t\n",
__func__, mdatalen);
#else /* __rtems__ */
return -EIO;
#endif /* __rtems__ */
} else if (S_ISLNK(JFFS2_F_I_MODE(f))) {
mdatalen = fn->size;
mdata = kmalloc(fn->size, GFP_KERNEL);
+2
View File
@@ -50,7 +50,9 @@ struct jffs2_inode_info {
uint16_t flags;
uint8_t usercompr;
#if !defined (__ECOS)
struct inode vfs_inode;
#endif
};
#endif /* _JFFS2_FS_I */
+54 -74
View File
@@ -12,13 +12,8 @@
*/
#include <linux/kernel.h>
#include <cyg/hal/drv_api.h>
#include "nodelist.h"
#if !defined(CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE)
# define CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE 0
#endif
struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize)
{
return malloc(sizeof(struct jffs2_full_dirent) + namesize);
@@ -69,6 +64,60 @@ void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
free(x);
}
static struct jffs2_raw_node_ref *jffs2_alloc_refblock(void)
{
struct jffs2_raw_node_ref *ret;
ret = malloc((REFS_PER_BLOCK + 1) * sizeof(*ret));
if (ret) {
int i = 0;
for (i=0; i < REFS_PER_BLOCK; i++) {
ret[i].flash_offset = REF_EMPTY_NODE;
ret[i].next_in_ino = NULL;
}
ret[i].flash_offset = REF_LINK_NODE;
ret[i].next_in_ino = NULL;
}
return ret;
}
int jffs2_prealloc_raw_node_refs(struct jffs2_sb_info *c,
struct jffs2_eraseblock *jeb, int nr)
{
struct jffs2_raw_node_ref **p, *ref;
int i = nr;
p = &jeb->last_node;
ref = *p;
/* If jeb->last_node is really a valid node then skip over it */
if (ref && ref->flash_offset != REF_EMPTY_NODE)
ref++;
while (i) {
if (!ref) {
ref = *p = jffs2_alloc_refblock();
if (!ref)
return -ENOMEM;
}
if (ref->flash_offset == REF_LINK_NODE) {
p = &ref->next_in_ino;
ref = *p;
continue;
}
i--;
ref++;
}
jeb->allocated_refs = nr;
return 0;
}
void jffs2_free_refblock(struct jffs2_raw_node_ref *x)
{
free(x);
}
struct jffs2_node_frag *jffs2_alloc_node_frag(void)
{
return malloc(sizeof(struct jffs2_node_frag));
@@ -79,75 +128,6 @@ void jffs2_free_node_frag(struct jffs2_node_frag *x)
free(x);
}
#if CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE == 0
int jffs2_create_slab_caches(void)
{
return 0;
}
void jffs2_destroy_slab_caches(void)
{
}
struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void)
{
return malloc(sizeof(struct jffs2_raw_node_ref));
}
void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
{
free(x);
}
#else // CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE == 0
static struct jffs2_raw_node_ref
rnr_pool[CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE] __attribute__ ((aligned (4))),
* first = NULL;
static cyg_drv_mutex_t mutex;
int jffs2_create_slab_caches(void)
{
struct jffs2_raw_node_ref * p;
cyg_drv_mutex_init(&mutex);
for (
p = rnr_pool;
p < rnr_pool + CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE - 1;
p++
)
p->next_phys = p + 1;
rnr_pool[CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE - 1].next_phys = NULL;
first = &rnr_pool[0];
return 0;
}
void jffs2_destroy_slab_caches(void)
{
}
struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void)
{
struct jffs2_raw_node_ref * p;
cyg_drv_mutex_lock(&mutex);
p = first;
if (p != NULL)
first = p->next_phys;
cyg_drv_mutex_unlock(&mutex);
return p;
}
void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
{
cyg_drv_mutex_lock(&mutex);
x->next_phys = first;
first = x;
cyg_drv_mutex_unlock(&mutex);
}
#endif // CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE == 0
struct jffs2_inode_cache *jffs2_alloc_inode_cache(void)
{
struct jffs2_inode_cache *ret = malloc(sizeof(struct jffs2_inode_cache));
+4 -2
View File
@@ -21,8 +21,8 @@
#include "acl.h"
#include "summary.h"
#ifdef __ECOS
#include "os-ecos.h"
#ifdef __rtems__
#include "os-rtems.h"
#else
#include "os-linux.h"
#endif
@@ -309,6 +309,7 @@ static inline int jffs2_blocks_use_vmalloc(struct jffs2_sb_info *c)
#define PAD(x) (((x)+3)&~3)
#ifndef __rtems__
static inline int jffs2_encode_dev(union jffs2_device_node *jdev, dev_t rdev)
{
if (old_valid_dev(rdev)) {
@@ -319,6 +320,7 @@ static inline int jffs2_encode_dev(union jffs2_device_node *jdev, dev_t rdev)
return sizeof(jdev->new_id);
}
}
#endif /* __rtems__ */
static inline struct jffs2_node_frag *frag_first(struct rb_root *root)
{
File diff suppressed because it is too large. Load diff
+7
View File
@@ -416,7 +416,14 @@ static void eat_last(struct rb_root *root, struct rb_node *node)
*link = node->rb_left;
if (node->rb_left)
#ifndef __rtems__
node->rb_left->__rb_parent_color = node->__rb_parent_color;
#else /* __rtems__ */
{
node->rb_left->rb_parent = node->rb_parent;
node->rb_left->rb_color = node->rb_color;
}
#endif /* __rtems__ */
}
/* We put the version tree in reverse order, so we can use the same eat_last()
+2 -1
View File
@@ -95,8 +95,9 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
unsigned char *flashbuf = NULL;
uint32_t buf_size = 0;
struct jffs2_summary *s = NULL; /* summary info collected by the scan process */
size_t try_size;
#ifndef __ECOS
size_t pointlen, try_size;
size_t pointlen;
ret = mtd_point(c->mtd, 0, c->mtd->size, &pointlen,
(void **)&flashbuf, NULL);
+4
View File
@@ -257,6 +257,10 @@ $(PROJECT_INCLUDE)/rtems/rfs/rtems-rfs-trace.h: libfs/src/rfs/rtems-rfs-trace.h
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rfs/rtems-rfs-trace.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rfs/rtems-rfs-trace.h
$(PROJECT_INCLUDE)/rtems/jffs2.h: libfs/src/jffs2/include/rtems/jffs2.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/jffs2.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/jffs2.h
$(PROJECT_INCLUDE)/rtems/bdbuf.h: libblock/include/rtems/bdbuf.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/bdbuf.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/bdbuf.h
+18 -1
View File
@@ -237,6 +237,7 @@ const rtems_libio_helper rtems_fs_init_helper =
* CONFIGURE_FILESYSTEM_NFS - Network File System, networking enabled
* CONFIGURE_FILESYSTEM_DOSFS - DOS File System, uses libblock
* CONFIGURE_FILESYSTEM_RFS - RTEMS File System (RFS), uses libblock
* CONFIGURE_FILESYSTEM_JFFS2 - Journalling Flash File System, Version 2
*
* Combinations:
*
@@ -264,6 +265,7 @@ const rtems_libio_helper rtems_fs_init_helper =
#define CONFIGURE_FILESYSTEM_NFS
#define CONFIGURE_FILESYSTEM_DOSFS
#define CONFIGURE_FILESYSTEM_RFS
#define CONFIGURE_FILESYSTEM_JFFS2
#endif
/*
@@ -283,7 +285,8 @@ const rtems_libio_helper rtems_fs_init_helper =
defined(CONFIGURE_FILESYSTEM_FTPFS) || \
defined(CONFIGURE_FILESYSTEM_NFS) || \
defined(CONFIGURE_FILESYSTEM_DOSFS) || \
defined(CONFIGURE_FILESYSTEM_RFS)
defined(CONFIGURE_FILESYSTEM_RFS) || \
defined(CONFIGURE_FILESYSTEM_JFFS2)
#error "Configured filesystems but root filesystem was not IMFS!"
#error "Filesystems could be disabled, DEVFS is root, or"
#error " miniIMFS is root!"
@@ -440,6 +443,16 @@ const rtems_libio_helper rtems_fs_init_helper =
{ RTEMS_FILESYSTEM_TYPE_RFS, rtems_rfs_rtems_initialise }
#endif
/**
* JFFS2
*/
#if !defined(CONFIGURE_FILESYSTEM_ENTRY_JFFS2) && \
defined(CONFIGURE_FILESYSTEM_JFFS2)
#include <rtems/jffs2.h>
#define CONFIGURE_FILESYSTEM_ENTRY_JFFS2 \
{ RTEMS_FILESYSTEM_TYPE_JFFS2, rtems_jffs2_initialize }
#endif
#ifdef CONFIGURE_INIT
/**
@@ -513,6 +526,10 @@ const rtems_libio_helper rtems_fs_init_helper =
defined(CONFIGURE_FILESYSTEM_ENTRY_RFS)
CONFIGURE_FILESYSTEM_ENTRY_RFS,
#endif
#if defined(CONFIGURE_FILESYSTEM_JFFS2) && \
defined(CONFIGURE_FILESYSTEM_ENTRY_JFFS2)
CONFIGURE_FILESYSTEM_ENTRY_JFFS2,
#endif
CONFIGURE_FILESYSTEM_NULL
};
#endif
+1
View File
@@ -27,6 +27,7 @@ TMP_LIBS += ../libfs/libdefaultfs.a
TMP_LIBS += ../libfs/libdevfs.a
TMP_LIBS += ../libfs/libimfs.a
TMP_LIBS += ../libfs/librfs.a
TMP_LIBS += ../libfs/libjffs2.a
TMP_LIBS += ../libmisc/libmonitor.a
TMP_LIBS += ../libmisc/libuntar.a