update jffs2, CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE can be disable in jffs2_config.h; modify semaphore.h so that rt_mutex_init and work correctly in jffs2; fix a memory leak bug in dfs_jffs2.c when close directory

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1991 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
goprife@gmail.com 2012-03-06 14:50:19 +00:00
parent 887bcbbad8
commit 8e5b4024ed
4 changed files with 186 additions and 36 deletions

View File

@ -31,18 +31,18 @@
#error "support only one jffs2 partition on a flash device!" #error "support only one jffs2 partition on a flash device!"
#endif #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 device_part
{ {
struct rt_mtd_device *dev;
struct cyg_mtab_entry * mte; struct cyg_mtab_entry * mte;
struct rt_mtd_device *dev;
}; };
static struct device_part device_partition[DEVICE_PART_MAX] = {0}; static struct device_part device_partition[DEVICE_PART_MAX] = {0};
#define jffs2_mount jffs2_fste.mount #define jffs2_mount jffs2_fste.mount
#define jffs2_umount jffs2_fste.umount #define jffs2_umount jffs2_fste.umount
#define jffs2_open jffs2_fste.open #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_mkdir jffs2_fste.mkdir
#define jffs2_rmdir jffs2_fste.rmdir #define jffs2_rmdir jffs2_fste.rmdir
#define jffs2_rename jffs2_fste.rename #define jffs2_rename jffs2_fste.rename
@ -84,6 +84,9 @@ static int jffs2_result_to_dfs(int result)
{ {
int status = -1; int status = -1;
if (result < 0)
result = -result;
switch (result) switch (result)
{ {
case ENOERR:/** no error */ case ENOERR:/** no error */
@ -99,6 +102,7 @@ static int jffs2_result_to_dfs(int result)
status = -DFS_STATUS_EINVAL; status = -DFS_STATUS_EINVAL;
break; break;
case EMFILE: /** No more file handles available(too many open files) */ 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; status = -1;
break;//fixme break;//fixme
case ENOENT: /** file or path not found */ case ENOENT: /** file or path not found */
@ -119,7 +123,12 @@ static int jffs2_result_to_dfs(int result)
case EISDIR: /** Is a directory */ case EISDIR: /** Is a directory */
status = -DFS_STATUS_EISDIR; status = -DFS_STATUS_EISDIR;
break; break;
case ENOSPC: /**//* No space left on device */
status = -DFS_STATUS_ENOSPC;
break;
default: default:
rt_kprintf("dfs_jffs2.c error: %d\r\n", result);
status = -1; status = -1;
break; /* unknown error! */ break; /* unknown error! */
} }
@ -281,13 +290,17 @@ static int dfs_jffs2_open(struct dfs_fd* file)
/* fixme, should test file->path can end with '/' */ /* fixme, should test file->path can end with '/' */
result = jffs2_mkdir(mte, mte->root, name); result = jffs2_mkdir(mte, mte->root, name);
if (result) if (result)
{
rt_free(jffs2_file);
return jffs2_result_to_dfs(result); return jffs2_result_to_dfs(result);
}
} }
/* open dir */ /* open dir */
result = jffs2_opendir(mte, mte->root, name, jffs2_file); result = jffs2_opendir(mte, mte->root, name, jffs2_file);
if (result) if (result)
{ {
rt_free(jffs2_file);
return jffs2_result_to_dfs(result); return jffs2_result_to_dfs(result);
} }
#ifdef CONFIG_JFFS2_NO_RELATIVEDIR #ifdef CONFIG_JFFS2_NO_RELATIVEDIR
@ -346,6 +359,8 @@ static int dfs_jffs2_close(struct dfs_fd* file)
result = jffs2_dir_colse(jffs2_file); result = jffs2_dir_colse(jffs2_file);
if (result) if (result)
return jffs2_result_to_dfs(result); return jffs2_result_to_dfs(result);
rt_free(jffs2_file);
return 0; return 0;
} }
/* regular file operations */ /* regular file operations */
@ -457,6 +472,11 @@ static int dfs_jffs2_getdents(struct dfs_fd* file,
struct jffs2_dirent jffs2_d; struct jffs2_dirent jffs2_d;
struct dirent * d; struct dirent * d;
rt_uint32_t index; 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; int result;
RT_ASSERT(file->data != RT_NULL); 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_offset = 0;//not used...
uio_s.uio_resid = uio_s.uio_iov->iov_len; //seem no use in jffs2; 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 */ /* make integer count, usually count is 1 */
count = (count / sizeof(struct dirent)) * sizeof(struct dirent); count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
if (count == 0) if (count == 0)
@ -488,14 +515,44 @@ static int dfs_jffs2_getdents(struct dfs_fd* file,
if (result || jffs2_d.d_name[0] == 0) if (result || jffs2_d.d_name[0] == 0)
break; break;
#if defined (CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE)
switch(jffs2_d.d_type & JFFS2_S_IFMT) switch(jffs2_d.d_type & JFFS2_S_IFMT)
{ {
case JFFS2_S_IFREG: d->d_type = DFS_DT_REG; break; case JFFS2_S_IFREG: d->d_type = DFS_DT_REG; break;
case JFFS2_S_IFDIR: d->d_type = DFS_DT_DIR; break; case JFFS2_S_IFDIR: d->d_type = DFS_DT_DIR; break;
default: d->d_type = DFS_DT_UNKNOWN; break; default: d->d_type = DFS_DT_UNKNOWN; break;
} }
#else
fullname = rt_malloc(FILE_PATH_MAX);
if(fullname == RT_NULL)
return -DFS_STATUS_ENOMEM;
/* write the rest feilds of struct dirent* dirp */ /* 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);
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_namlen = rt_strlen(jffs2_d.d_name);
d->d_reclen = (rt_uint16_t)sizeof(struct dirent); d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
rt_strncpy(d->d_name, jffs2_d.d_name, d->d_namlen + 1); 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) switch(s.st_mode & JFFS2_S_IFMT)
{ {
case JFFS2_S_IFREG: case JFFS2_S_IFREG:
result = jffs2_unlink(mte, mte->root, path); result = jffs2_file_unlink(mte, mte->root, path);
break; break;
case JFFS2_S_IFDIR: case JFFS2_S_IFDIR:
result = jffs2_rmdir(mte, mte->root, path); result = jffs2_rmdir(mte, mte->root, path);

View File

@ -3,7 +3,7 @@
#define __ECOS /* must be defined */ #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*/ #define DEVICE_PART_MAX 1 /* the max partions on a nand deivce*/
@ -22,7 +22,7 @@
*/ */
#define CONFIG_JFFS2_NO_RELATIVEDIR #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) #if defined(CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE)
#define CYGPKG_FILEIO_DIRENT_DTYPE #define CYGPKG_FILEIO_DIRENT_DTYPE
#endif #endif
@ -34,9 +34,9 @@
/* jffs2 gc thread section */ /* jffs2 gc thread section */
//#define CYGOPT_FS_JFFS2_GCTHREAD //#define CYGOPT_FS_JFFS2_GCTHREAD
#define CYGNUM_JFFS2_GC_THREAD_PRIORITY 20 #define CYGNUM_JFFS2_GC_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX-2) /* GC thread's priority */
#define CYGNUM_JFFS2_GS_THREAD_TICKS 20 #define CYGNUM_JFFS2_GS_THREAD_TICKS 20 /* event timeout ticks */
#define CYGNUM_JFFS2_GC_THREAD_TICKS 20 #define CYGNUM_JFFS2_GC_THREAD_TICKS 20 /* GC thread's running ticks */
//#define CONFIG_JFFS2_FS_WRITEBUFFER /* should not be enabled */ //#define CONFIG_JFFS2_FS_WRITEBUFFER /* should not be enabled */

View File

@ -1,38 +1,119 @@
#ifndef __ASM_SEMAPHORE_H__ #ifndef __ASM_SEMAPHORE_H__
#define __ASM_SEMAPHORE_H__ #define __ASM_SEMAPHORE_H__
//#include <cyg/hal/drv_api.h> #define CONFIG_JFFS2_SEMAPHORE 1 // no mutex, 1 use static, 2 use dynamic
#if CONFIG_JFFS2_SEMAPHORE == 0
#include <cyg/hal/drv_api.h>
//struct semaphore { struct semaphore {
// cyg_drv_mutex_t x; cyg_drv_mutex_t x;
//}; };
//#define DECLARE_MUTEX(x) //struct semaphore x = { { 0 } }; #define DECLARE_MUTEX(x) //struct semaphore x = { { 0 } };
//#define DECLARE_MUTEX_LOCKED(x) //struct semaphore x = { { 1 } }; #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(struct semaphore * 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 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(sem) //cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem) #define down(struct semaphore * 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_interruptible(struct semaphore * sem) 0//({ cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem), 0; })
//#define down_trylock(sem) //cyg_drv_mutex_trylock((cyg_drv_mutex_t *)sem) #define down_trylock(struct semaphore * sem) //cyg_drv_mutex_trylock((cyg_drv_mutex_t *)sem)
//#define up(sem) //cyg_drv_mutex_unlock((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 <rtthread.h>
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 <rtthread.h> #include <rtthread.h>
struct semaphore { struct semaphore {
struct rt_mutex x; rt_mutex_t mutex;
}; };
#define DECLARE_MUTEX(x) struct semaphore x = { { .value = 0, } }; #define DECLARE_MUTEX(x)
#define DECLARE_MUTEX_LOCKED(x) struct semaphore x = { { .vlalue = 1 } }; #define DECLARE_MUTEX_LOCKED(x)
#define init_MUTEX(sem) rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO) rt_inline void init_MUTEX(struct semaphore * sem)
#define init_MUTEX_LOCKED(sem) do { \ {
rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO);\ sem->mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO);
rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER);} \ }
while(0) rt_inline init_MUTEX_LOCKED(struct semaphore * sem)
#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; }) 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. 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 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 ) void cyg_drv_mutex_unlock( cyg_drv_mutex *mutex )
*/ */
#define down_trylock(sem) rt_mutex_take((rt_mutex_t)sem, RT_WAITING_NO) //#define down_trylock(struct semaphore * sem) rt_mutex_take((rt_mutex_t)sem, RT_WAITING_NO)
#define up(sem) rt_mutex_release((rt_mutex_t)sem) 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__ */ #endif /* __ASM_SEMAPHORE_H__ */

View File

@ -1,6 +1,7 @@
#ifndef _PORTING_H #ifndef _PORTING_H
#define _PORTING_H #define _PORTING_H
#include "jffs2_config.h"
/* the following should be same with os_sys_stat.h */ /* the following should be same with os_sys_stat.h */
#define JFFS2_S_IFMT 0x000003FF #define JFFS2_S_IFMT 0x000003FF
#define JFFS2_S_IFDIR (1<<0) #define JFFS2_S_IFDIR (1<<0)
@ -31,10 +32,13 @@ struct jffs2_stat {
struct jffs2_dirent struct jffs2_dirent
{ {
#ifdef CYGPKG_FILEIO_DIRENT_DTYPE
unsigned long d_type; // Only supported with FATFS, RAMFS, ROMFS, unsigned long d_type; // Only supported with FATFS, RAMFS, ROMFS,
// and JFFS2. // and JFFS2.
// d_type is not part of POSIX so // d_type is not part of POSIX so
// should be used with caution. // should be used with caution.
#endif
char d_name[NAME_MAX+1]; char d_name[NAME_MAX+1];
}; };