diff --git a/components/dfs/filesystems/jffs2/dfs_jffs2.c b/components/dfs/filesystems/jffs2/dfs_jffs2.c index 5c06149a8ce624bfbdfd02e8ac4250ca6f2ca7c1..1f3d450ae5f3db81536c7f1a9914e25531f11411 100644 --- a/components/dfs/filesystems/jffs2/dfs_jffs2.c +++ b/components/dfs/filesystems/jffs2/dfs_jffs2.c @@ -31,18 +31,18 @@ #error "support only one jffs2 partition on a flash device!" #endif -/* make sure the following struct var had been initilased to 0! */ //fixme +/* make sure the following struct var had been initilased to 0! */ struct device_part { + struct cyg_mtab_entry * mte; struct rt_mtd_device *dev; - struct cyg_mtab_entry * mte; }; static struct device_part device_partition[DEVICE_PART_MAX] = {0}; #define jffs2_mount jffs2_fste.mount #define jffs2_umount jffs2_fste.umount #define jffs2_open jffs2_fste.open -#define jffs2_unlink jffs2_fste.unlink +#define jffs2_file_unlink jffs2_fste.unlink #define jffs2_mkdir jffs2_fste.mkdir #define jffs2_rmdir jffs2_fste.rmdir #define jffs2_rename jffs2_fste.rename @@ -84,6 +84,9 @@ static int jffs2_result_to_dfs(int result) { int status = -1; + if (result < 0) + result = -result; + switch (result) { case ENOERR:/** no error */ @@ -99,6 +102,7 @@ static int jffs2_result_to_dfs(int result) status = -DFS_STATUS_EINVAL; break; case EMFILE: /** No more file handles available(too many open files) */ + rt_kprintf("dfs_jffs2.c error: no more file handles available\r\n"); status = -1; break;//fixme case ENOENT: /** file or path not found */ @@ -119,7 +123,12 @@ static int jffs2_result_to_dfs(int result) case EISDIR: /** Is a directory */ status = -DFS_STATUS_EISDIR; break; + case ENOSPC: /**//* No space left on device */ + status = -DFS_STATUS_ENOSPC; + break; + default: + rt_kprintf("dfs_jffs2.c error: %d\r\n", result); status = -1; break; /* unknown error! */ } @@ -281,13 +290,17 @@ static int dfs_jffs2_open(struct dfs_fd* file) /* fixme, should test file->path can end with '/' */ result = jffs2_mkdir(mte, mte->root, name); if (result) + { + rt_free(jffs2_file); return jffs2_result_to_dfs(result); + } } /* open dir */ result = jffs2_opendir(mte, mte->root, name, jffs2_file); if (result) { + rt_free(jffs2_file); return jffs2_result_to_dfs(result); } #ifdef CONFIG_JFFS2_NO_RELATIVEDIR @@ -346,6 +359,8 @@ static int dfs_jffs2_close(struct dfs_fd* file) result = jffs2_dir_colse(jffs2_file); if (result) return jffs2_result_to_dfs(result); + + rt_free(jffs2_file); return 0; } /* regular file operations */ @@ -457,6 +472,11 @@ static int dfs_jffs2_getdents(struct dfs_fd* file, struct jffs2_dirent jffs2_d; struct dirent * d; rt_uint32_t index; +#if !defined (CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE) + struct jffs2_stat s; + cyg_mtab_entry * mte; + char * fullname; +#endif int result; RT_ASSERT(file->data != RT_NULL); @@ -472,6 +492,13 @@ static int dfs_jffs2_getdents(struct dfs_fd* file, uio_s.uio_offset = 0;//not used... uio_s.uio_resid = uio_s.uio_iov->iov_len; //seem no use in jffs2; +#if !defined (CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE) + + result = _find_fs(&mte, file->fs->dev_id); + if (result) + return -DFS_STATUS_ENOENT; +#endif + /* make integer count, usually count is 1 */ count = (count / sizeof(struct dirent)) * sizeof(struct dirent); if (count == 0) @@ -488,14 +515,44 @@ static int dfs_jffs2_getdents(struct dfs_fd* file, if (result || jffs2_d.d_name[0] == 0) break; +#if defined (CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE) switch(jffs2_d.d_type & JFFS2_S_IFMT) { case JFFS2_S_IFREG: d->d_type = DFS_DT_REG; break; case JFFS2_S_IFDIR: d->d_type = DFS_DT_DIR; break; default: d->d_type = DFS_DT_UNKNOWN; break; } +#else + fullname = rt_malloc(FILE_PATH_MAX); + if(fullname == RT_NULL) + return -DFS_STATUS_ENOMEM; + + /* make a right entry */ + if ((file->path[0] == '/') ) + { + if (file->path[1] == 0) + strcpy(fullname, jffs2_d.d_name); + else + rt_sprintf(fullname, "%s/%s", file->path+1, jffs2_d.d_name); + } + else + rt_sprintf(fullname, "%s/%s", file->path, jffs2_d.d_name); + + result = jffs2_porting_stat(mte, mte->root, fullname, (void *)&s); - /* write the rest feilds of struct dirent* dirp */ + if (result) + return jffs2_result_to_dfs(result); + + rt_free(fullname); + /* convert to dfs stat structure */ + switch(s.st_mode & JFFS2_S_IFMT) + { + case JFFS2_S_IFREG: d->d_type = DFS_DT_REG; break; + case JFFS2_S_IFDIR: d->d_type = DFS_DT_DIR; break; + default: d->d_type = DFS_DT_UNKNOWN; break; + } +#endif + /* write the rest fields of struct dirent* dirp */ d->d_namlen = rt_strlen(jffs2_d.d_name); d->d_reclen = (rt_uint16_t)sizeof(struct dirent); rt_strncpy(d->d_name, jffs2_d.d_name, d->d_namlen + 1); @@ -531,7 +588,7 @@ static int dfs_jffs2_unlink(struct dfs_filesystem* fs, const char* path) switch(s.st_mode & JFFS2_S_IFMT) { case JFFS2_S_IFREG: - result = jffs2_unlink(mte, mte->root, path); + result = jffs2_file_unlink(mte, mte->root, path); break; case JFFS2_S_IFDIR: result = jffs2_rmdir(mte, mte->root, path); diff --git a/components/dfs/filesystems/jffs2/jffs2_config.h b/components/dfs/filesystems/jffs2/jffs2_config.h index ad2eb879dd6b63de896d517fa711f8835211cee7..0a3e4e3c91588c32a275966a4c6f3aec013a0c72 100644 --- a/components/dfs/filesystems/jffs2/jffs2_config.h +++ b/components/dfs/filesystems/jffs2/jffs2_config.h @@ -3,7 +3,7 @@ #define __ECOS /* must be defined */ -#define FILE_PATH_MAX 256 /* the longest file path */ +#define FILE_PATH_MAX 128 /* the longest file path */ #define DEVICE_PART_MAX 1 /* the max partions on a nand deivce*/ @@ -22,7 +22,7 @@ */ #define CONFIG_JFFS2_NO_RELATIVEDIR -#define CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE /* should be enabled */ +//#define CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE #if defined(CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE) #define CYGPKG_FILEIO_DIRENT_DTYPE #endif @@ -34,9 +34,9 @@ /* jffs2 gc thread section */ //#define CYGOPT_FS_JFFS2_GCTHREAD -#define CYGNUM_JFFS2_GC_THREAD_PRIORITY 20 -#define CYGNUM_JFFS2_GS_THREAD_TICKS 20 -#define CYGNUM_JFFS2_GC_THREAD_TICKS 20 +#define CYGNUM_JFFS2_GC_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX-2) /* GC thread's priority */ +#define CYGNUM_JFFS2_GS_THREAD_TICKS 20 /* event timeout ticks */ +#define CYGNUM_JFFS2_GC_THREAD_TICKS 20 /* GC thread's running ticks */ //#define CONFIG_JFFS2_FS_WRITEBUFFER /* should not be enabled */ diff --git a/components/dfs/filesystems/jffs2/kernel/asm/semaphore.h b/components/dfs/filesystems/jffs2/kernel/asm/semaphore.h index 704c8bb9c6b2bb6ea41f7d5167aef78936111a7b..d989a658cc3344e68db7c28d6dec63556ec271bf 100644 --- a/components/dfs/filesystems/jffs2/kernel/asm/semaphore.h +++ b/components/dfs/filesystems/jffs2/kernel/asm/semaphore.h @@ -1,38 +1,119 @@ #ifndef __ASM_SEMAPHORE_H__ #define __ASM_SEMAPHORE_H__ -//#include - -//struct semaphore { -// cyg_drv_mutex_t x; -//}; - -//#define DECLARE_MUTEX(x) //struct semaphore x = { { 0 } }; -//#define DECLARE_MUTEX_LOCKED(x) //struct semaphore x = { { 1 } }; -// -//#define init_MUTEX(sem) //cyg_drv_mutex_init((cyg_drv_mutex_t *)sem) -//#define init_MUTEX_LOCKED(sem) //do { cyg_drv_mutex_init((cyg_drv_mutex_t *)sem); cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem); } while(0) -//#define down(sem) //cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem) -//#define down_interruptible(sem) //({ cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem), 0; }) -//#define down_trylock(sem) //cyg_drv_mutex_trylock((cyg_drv_mutex_t *)sem) -//#define up(sem) //cyg_drv_mutex_unlock((cyg_drv_mutex_t *)sem) +#define CONFIG_JFFS2_SEMAPHORE 1 // no mutex, 1 use static, 2 use dynamic +#if CONFIG_JFFS2_SEMAPHORE == 0 +#include + +struct semaphore { + cyg_drv_mutex_t x; +}; + +#define DECLARE_MUTEX(x) //struct semaphore x = { { 0 } }; +#define DECLARE_MUTEX_LOCKED(x) //struct semaphore x = { { 1 } }; + +#define init_MUTEX(struct semaphore * sem) //cyg_drv_mutex_init((cyg_drv_mutex_t *)sem) +#define init_MUTEX_LOCKED(struct semaphore * sem) //do { cyg_drv_mutex_init((cyg_drv_mutex_t *)sem); cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem); } while(0) +#define down(struct semaphore * sem) //cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem) +#define down_interruptible(struct semaphore * sem) 0//({ cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem), 0; }) +#define down_trylock(struct semaphore * sem) //cyg_drv_mutex_trylock((cyg_drv_mutex_t *)sem) +#define up(struct semaphore * sem) //cyg_drv_mutex_unlock((cyg_drv_mutex_t *)sem) + +#elif CONFIG_JFFS2_SEMAPHORE == 1 +#include + +struct semaphore { + struct rt_mutex mutex; +}; + +#define DECLARE_MUTEX(x) +#define DECLARE_MUTEX_LOCKED(x) +rt_inline void init_MUTEX(struct semaphore * sem) +{ + if (rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO) == RT_EOK) + { + /* detach the object from system object container */ + rt_object_detach(&(((rt_mutex_t)sem)->parent.parent)); + return; + } + rt_kprintf("get an error at %s:%d \n", __FUNCTION__, __LINE__); + RT_ASSERT(0); +} + +rt_inline void init_MUTEX_LOCKED(struct semaphore * sem) +{ + if (rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO) == RT_EOK) + { + /* detach the object from system object container */ + rt_object_detach(&(((rt_mutex_t)sem)->parent.parent)); + rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER); + return; + } + rt_kprintf("get an error at %s:%d \n", __FUNCTION__, __LINE__); + RT_ASSERT(0); +} +/* +rt_inline void init_MUTEX(struct semaphore * sem) +{ + if (rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO) == RT_EOK) + return; + rt_kprintf("get an error at %s:%d \n", __FUNCTION__, __LINE__); + RT_ASSERT(0); +} + +rt_inline init_MUTEX_LOCKED(struct semaphore * sem) +{ + if (rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO) == RT_EOK) + { + rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER); + return; + } + rt_kprintf("get an error at %s:%d \n", __FUNCTION__, __LINE__); + RT_ASSERT(0); +} +*/ +rt_inline down(struct semaphore * sem) +{ + rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER); +} +rt_inline int down_interruptible(struct semaphore* sem) +{ + rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER); + return 0; +} +rt_inline up(struct semaphore * sem) +{ + rt_mutex_release((rt_mutex_t)sem); +} +#elif CONFIG_JFFS2_SEMAPHORE == 2 #include struct semaphore { - struct rt_mutex x; + rt_mutex_t mutex; }; - -#define DECLARE_MUTEX(x) struct semaphore x = { { .value = 0, } }; -#define DECLARE_MUTEX_LOCKED(x) struct semaphore x = { { .vlalue = 1 } }; - -#define init_MUTEX(sem) rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO) -#define init_MUTEX_LOCKED(sem) do { \ - rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO);\ - rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER);} \ - while(0) -#define down(sem) rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER) -#define down_interruptible(sem) ({rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER), 0; }) + +#define DECLARE_MUTEX(x) +#define DECLARE_MUTEX_LOCKED(x) + +rt_inline void init_MUTEX(struct semaphore * sem) +{ + sem->mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO); +} +rt_inline init_MUTEX_LOCKED(struct semaphore * sem) +{ + sem->mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO); + rt_mutex_take(sem->mutex, RT_WAITING_FOREVER); +} +rt_inline down(struct semaphore * sem) +{ + rt_mutex_take(sem->mutex, RT_WAITING_FOREVER); +} +rt_inline int down_interruptible(struct semaphore* sem) +{ + rt_mutex_take(sem->mutex, RT_WAITING_FOREVER); + return 0; +} /* Attempt to lock the mutex pointed to by the mutex argument without waiting. If the mutex is already locked by some other thread then this function @@ -41,6 +122,14 @@ TRUE is returned. void cyg_drv_mutex_unlock( cyg_drv_mutex *mutex ) */ -#define down_trylock(sem) rt_mutex_take((rt_mutex_t)sem, RT_WAITING_NO) -#define up(sem) rt_mutex_release((rt_mutex_t)sem) +//#define down_trylock(struct semaphore * sem) rt_mutex_take((rt_mutex_t)sem, RT_WAITING_NO) +rt_inline up(struct semaphore * sem) +{ + rt_mutex_release(sem->mutex); +} + +#else +#error "CONFIG_JFFS2_SEMAPHORE should be 0, 1 or 2" +#endif + #endif /* __ASM_SEMAPHORE_H__ */ diff --git a/components/dfs/filesystems/jffs2/porting.h b/components/dfs/filesystems/jffs2/porting.h index 019812b86a93c71f61b3793841ccc8cdfbb4d566..86676782fe8662c13b2b1738552029b85104acb3 100644 --- a/components/dfs/filesystems/jffs2/porting.h +++ b/components/dfs/filesystems/jffs2/porting.h @@ -1,6 +1,7 @@ #ifndef _PORTING_H #define _PORTING_H +#include "jffs2_config.h" /* the following should be same with os_sys_stat.h */ #define JFFS2_S_IFMT 0x000003FF #define JFFS2_S_IFDIR (1<<0) @@ -31,10 +32,13 @@ struct jffs2_stat { struct jffs2_dirent { +#ifdef CYGPKG_FILEIO_DIRENT_DTYPE + unsigned long d_type; // Only supported with FATFS, RAMFS, ROMFS, // and JFFS2. // d_type is not part of POSIX so // should be used with caution. +#endif char d_name[NAME_MAX+1]; };