Browse Source

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
goprife@gmail.com 13 years ago
parent
commit
8e5b4024ed

+ 62 - 5
components/dfs/filesystems/jffs2/dfs_jffs2.c

@@ -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 cyg_mtab_entry * mte;
 	struct rt_mtd_device *dev;
 	struct rt_mtd_device *dev;
-	struct cyg_mtab_entry * mte;				
 };
 };
 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;
+
+		/* 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_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);

+ 5 - 5
components/dfs/filesystems/jffs2/jffs2_config.h

@@ -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_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 */
 //#define CONFIG_JFFS2_FS_WRITEBUFFER /* should not be enabled */
 
 

+ 118 - 29
components/dfs/filesystems/jffs2/kernel/asm/semaphore.h

@@ -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>
-
-//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 <cyg/hal/drv_api.h>
+
+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 <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_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. 
 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 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__ */
 #endif /* __ASM_SEMAPHORE_H__ */

+ 4 - 0
components/dfs/filesystems/jffs2/porting.h

@@ -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];
 };
 };