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!"
 #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);

+ 5 - 5
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 */
 

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

@@ -1,38 +1,119 @@
 #ifndef __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>
 
 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__ */

+ 4 - 0
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];
 };