|
@@ -1,16 +1,27 @@
|
|
|
/*
|
|
|
- * File : rtthread.h
|
|
|
- * This file is part of RT-Thread RTOS
|
|
|
- * COPYRIGHT (C) 2006-2012, RT-Thread Development Team
|
|
|
+ * File : dfs_jffs2.c
|
|
|
+ * This file is part of Device File System in RT-Thread RTOS
|
|
|
+ * COPYRIGHT (C) 2006-2017, RT-Thread Development Team
|
|
|
*
|
|
|
- * The license and distribution terms for this file may be
|
|
|
- * found in the file LICENSE in this distribution or at
|
|
|
- * http://www.rt-thread.org/license/LICENSE.
|
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
|
+ * (at your option) any later version.
|
|
|
+ *
|
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
+ * GNU General Public License for more details.
|
|
|
+ *
|
|
|
+ * You should have received a copy of the GNU General Public License along
|
|
|
+ * with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
*
|
|
|
* Change Logs:
|
|
|
* Date Author Notes
|
|
|
* 2012-1-7 prife the first version
|
|
|
-*/
|
|
|
+ */
|
|
|
+
|
|
|
#include <rtthread.h>
|
|
|
#include <rtdevice.h>
|
|
|
|
|
@@ -21,7 +32,7 @@
|
|
|
#undef mode_t
|
|
|
|
|
|
#include <dfs_fs.h>
|
|
|
-#include <dfs_def.h>
|
|
|
+#include <dfs_file.h>
|
|
|
|
|
|
#include "dfs_jffs2.h"
|
|
|
#include "jffs2_config.h"
|
|
@@ -29,51 +40,50 @@
|
|
|
#include <string.h>
|
|
|
|
|
|
#if DEVICE_PART_MAX > 1
|
|
|
- #error "support only one jffs2 partition on a flash device!"
|
|
|
+ #error "support only one jffs2 partition on a flash device!"
|
|
|
#endif
|
|
|
-
|
|
|
+
|
|
|
/* 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_nor_device *dev;
|
|
|
+ struct cyg_mtab_entry * mte;
|
|
|
+ struct rt_mtd_nor_device *dev;
|
|
|
};
|
|
|
static struct device_part device_partition[DEVICE_PART_MAX] = {0};
|
|
|
-
|
|
|
static struct rt_mutex jffs2_lock;
|
|
|
|
|
|
-#define jffs2_mount jffs2_fste.mount
|
|
|
-#define jffs2_umount jffs2_fste.umount
|
|
|
-#define jffs2_open jffs2_fste.open
|
|
|
-#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
|
|
|
-#define jffs2_link jffs2_fste.link
|
|
|
-#define jffs2_opendir jffs2_fste.opendir
|
|
|
-#define jffs2_chdir jffs2_fste.chdir
|
|
|
-#define jffs2_ops_stat jffs2_fste.stat
|
|
|
-#define jffs2_getinfo jffs2_fste.getinfo
|
|
|
-#define jffs2_setinfo jffs2_fste.setinfo
|
|
|
-
|
|
|
-#define jffs2_file_read jffs2_fileops.fo_read
|
|
|
-#define jffs2_file_write jffs2_fileops.fo_write
|
|
|
-#define jffs2_file_lseek jffs2_fileops.fo_lseek
|
|
|
-#define jffs2_file_ioctl jffs2_fileops.fo_ioctl
|
|
|
-#define jffs2_file_select jffs2_fileops.fo_select
|
|
|
-#define jffs2_file_fsync jffs2_fileops.fo_fsync
|
|
|
-#define jffs2_file_colse jffs2_fileops.fo_close
|
|
|
-#define jffs2_file_fstat jffs2_fileops.fo_fstat
|
|
|
-#define jffs2_file_getinfo jffs2_fileops.fo_getinfo
|
|
|
-#define jffs2_file_setinfo jffs2_fileops.fo_setinfo
|
|
|
-
|
|
|
-#define jffs2_dir_read jffs2_dirops.fo_read
|
|
|
+#define jffs2_mount jffs2_fste.mount
|
|
|
+#define jffs2_umount jffs2_fste.umount
|
|
|
+#define jffs2_open jffs2_fste.open
|
|
|
+#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
|
|
|
+#define jffs2_link jffs2_fste.link
|
|
|
+#define jffs2_opendir jffs2_fste.opendir
|
|
|
+#define jffs2_chdir jffs2_fste.chdir
|
|
|
+#define jffs2_ops_stat jffs2_fste.stat
|
|
|
+#define jffs2_getinfo jffs2_fste.getinfo
|
|
|
+#define jffs2_setinfo jffs2_fste.setinfo
|
|
|
+
|
|
|
+#define jffs2_file_read jffs2_fileops.fo_read
|
|
|
+#define jffs2_file_write jffs2_fileops.fo_write
|
|
|
+#define jffs2_file_lseek jffs2_fileops.fo_lseek
|
|
|
+#define jffs2_file_ioctl jffs2_fileops.fo_ioctl
|
|
|
+#define jffs2_file_select jffs2_fileops.fo_select
|
|
|
+#define jffs2_file_fsync jffs2_fileops.fo_fsync
|
|
|
+#define jffs2_file_colse jffs2_fileops.fo_close
|
|
|
+#define jffs2_file_fstat jffs2_fileops.fo_fstat
|
|
|
+#define jffs2_file_getinfo jffs2_fileops.fo_getinfo
|
|
|
+#define jffs2_file_setinfo jffs2_fileops.fo_setinfo
|
|
|
+
|
|
|
+#define jffs2_dir_read jffs2_dirops.fo_read
|
|
|
//#define jffs2_dir_write jffs2_dirops.fo_write
|
|
|
-#define jffs2_dir_lseek jffs2_dirops.fo_lseek
|
|
|
+#define jffs2_dir_lseek jffs2_dirops.fo_lseek
|
|
|
//#define jffs2_dir_ioctl jffs2_dirops.fo_ioctl
|
|
|
-#define jffs2_dir_select jffs2_dirops.fo_select
|
|
|
+#define jffs2_dir_select jffs2_dirops.fo_select
|
|
|
//#define jffs2_dir_fsync jffs2_dirops.fo_fsync
|
|
|
-#define jffs2_dir_colse jffs2_dirops.fo_close
|
|
|
+#define jffs2_dir_colse jffs2_dirops.fo_close
|
|
|
//#define jffs2_dir_fstat jffs2_dirops.fo_fstat
|
|
|
//#define jffs2_dir_getinfo jffs2_dirops.fo_getinfo
|
|
|
//#define jffs2_dir_setinfo jffs2_dirops.fo_setinfo
|
|
@@ -82,649 +92,610 @@ static struct rt_mutex jffs2_lock;
|
|
|
* RT-Thread Device Interface for jffs2
|
|
|
*/
|
|
|
|
|
|
-/* these code is in src/flashio.c */
|
|
|
+/* these code is in src/flashio.c */
|
|
|
static int jffs2_result_to_dfs(int result)
|
|
|
{
|
|
|
- int status = -1;
|
|
|
-
|
|
|
- if (result < 0)
|
|
|
- result = -result;
|
|
|
-
|
|
|
- switch (result)
|
|
|
- {
|
|
|
- case ENOERR:/** no error */
|
|
|
- break;
|
|
|
- case EACCES:/** Tried to open read-only file for writing, or files sharing mode
|
|
|
- does not allow specified operations, or given path is directory */
|
|
|
- status = -DFS_STATUS_EINVAL;
|
|
|
- break;/* no suitable */
|
|
|
- case EEXIST: /** _O_CREAT and _O_EXCL flags specified, but filename already exists */
|
|
|
- status = -DFS_STATUS_EEXIST;
|
|
|
- break;
|
|
|
- case EINVAL: /** Invalid oflag or pmode argument */
|
|
|
- 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 */
|
|
|
- status = -DFS_STATUS_ENOENT;
|
|
|
- break;
|
|
|
- case EBADF: /** invalid file handle */
|
|
|
- status = -DFS_STATUS_EBADF;
|
|
|
- break;
|
|
|
- case ENOMEM:/** no enough memory */
|
|
|
- status = -DFS_STATUS_ENOMEM;
|
|
|
- break;
|
|
|
- case EIO: /** I/O error from lower level flash operation */
|
|
|
- status = -DFS_STATUS_EIO;
|
|
|
- break;
|
|
|
- case ENOTDIR: /** Not a directory */
|
|
|
- status = -DFS_STATUS_ENOTDIR;
|
|
|
- break;
|
|
|
- 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! */
|
|
|
- }
|
|
|
-
|
|
|
- return status;
|
|
|
+ if (result < 0) return result;
|
|
|
+ if (result > 0) return -result;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* RT-Thread DFS Interface for jffs2
|
|
|
*/
|
|
|
-static int dfs_jffs2_mount(struct dfs_filesystem* fs,
|
|
|
- unsigned long rwflag,
|
|
|
- const void* data)
|
|
|
+static int dfs_jffs2_mount(struct dfs_filesystem* fs,
|
|
|
+ unsigned long rwflag,
|
|
|
+ const void* data)
|
|
|
{
|
|
|
- unsigned index;
|
|
|
- struct cyg_mtab_entry * mte;
|
|
|
- int result;
|
|
|
-
|
|
|
- /* find a empty entry in partition table */
|
|
|
- for (index = 0; index < DEVICE_PART_MAX; index ++)
|
|
|
- {
|
|
|
- if (device_partition[index].dev == RT_NULL)
|
|
|
- break;
|
|
|
- }
|
|
|
- if (index == DEVICE_PART_MAX)
|
|
|
- return -DFS_STATUS_ENOSPC;
|
|
|
-
|
|
|
- mte = rt_malloc(sizeof(struct cyg_mtab_entry));
|
|
|
- if (mte == RT_NULL)
|
|
|
- return -DFS_STATUS_ENOMEM;
|
|
|
-
|
|
|
- mte->name = fs->path;
|
|
|
- mte->fsname = "jffs2";
|
|
|
- mte->devname = NULL;
|
|
|
- /* note that, i use mte->data to store rtt's device
|
|
|
- * while, in jffs2_mount, mte->data will be copy into
|
|
|
- * s_dev in struct super_block, and mte->data will be
|
|
|
- * filled with jffs2_sb(see the source of jffs2_mount.
|
|
|
- */
|
|
|
- mte->data = (CYG_ADDRWORD)fs->dev_id;
|
|
|
-
|
|
|
- device_partition[index].dev = RT_MTD_NOR_DEVICE(fs->dev_id);
|
|
|
- /* after jffs2_mount, mte->data will not be dev_id any more */
|
|
|
- result = jffs2_mount(NULL, mte);
|
|
|
- if (result != 0)
|
|
|
- {
|
|
|
- device_partition[index].dev = NULL;
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
- }
|
|
|
- /* save this pointer */
|
|
|
- device_partition[index].mte = mte;
|
|
|
- return 0;
|
|
|
+ unsigned index;
|
|
|
+ struct cyg_mtab_entry * mte;
|
|
|
+ int result;
|
|
|
+
|
|
|
+ /* find a empty entry in partition table */
|
|
|
+ for (index = 0; index < DEVICE_PART_MAX; index ++)
|
|
|
+ {
|
|
|
+ if (device_partition[index].dev == RT_NULL)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (index == DEVICE_PART_MAX)
|
|
|
+ return -ENOSPC;
|
|
|
+
|
|
|
+ mte = rt_malloc(sizeof(struct cyg_mtab_entry));
|
|
|
+ if (mte == RT_NULL)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ mte->name = fs->path;
|
|
|
+ mte->fsname = "jffs2";
|
|
|
+ mte->devname = NULL;
|
|
|
+ /* note that, i use mte->data to store rtt's device
|
|
|
+ * while, in jffs2_mount, mte->data will be copy into
|
|
|
+ * s_dev in struct super_block, and mte->data will be
|
|
|
+ * filled with jffs2_sb(see the source of jffs2_mount.
|
|
|
+ */
|
|
|
+ mte->data = (CYG_ADDRWORD)fs->dev_id;
|
|
|
+
|
|
|
+ device_partition[index].dev = RT_MTD_NOR_DEVICE(fs->dev_id);
|
|
|
+ /* after jffs2_mount, mte->data will not be dev_id any more */
|
|
|
+ result = jffs2_mount(NULL, mte);
|
|
|
+ if (result != 0)
|
|
|
+ {
|
|
|
+ device_partition[index].dev = NULL;
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* save this pointer */
|
|
|
+ device_partition[index].mte = mte;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static int _find_fs(struct cyg_mtab_entry ** mte, rt_device_t dev_id)
|
|
|
{
|
|
|
- unsigned index;
|
|
|
- /* find device index */
|
|
|
- for (index = 0; index < DEVICE_PART_MAX; index++)
|
|
|
- {
|
|
|
- if (device_partition[index].dev == RT_MTD_NOR_DEVICE(dev_id))
|
|
|
- {
|
|
|
- *mte = device_partition[index].mte;
|
|
|
- return 0;
|
|
|
- }
|
|
|
- }
|
|
|
- rt_kprintf("error, could not found the fs!");
|
|
|
- return -1;
|
|
|
+ unsigned index;
|
|
|
+
|
|
|
+ /* find device index */
|
|
|
+ for (index = 0; index < DEVICE_PART_MAX; index++)
|
|
|
+ {
|
|
|
+ if (device_partition[index].dev == RT_MTD_NOR_DEVICE(dev_id))
|
|
|
+ {
|
|
|
+ *mte = device_partition[index].mte;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ rt_kprintf("error, could not found the fs!");
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
static int dfs_jffs2_unmount(struct dfs_filesystem* fs)
|
|
|
{
|
|
|
- int result;
|
|
|
- unsigned index;
|
|
|
- /* find device index, then umount it */
|
|
|
- for (index = 0; index < DEVICE_PART_MAX; index++)
|
|
|
- {
|
|
|
- if (device_partition[index].dev == RT_MTD_NOR_DEVICE(fs->dev_id))
|
|
|
- {
|
|
|
- result = jffs2_umount(device_partition[index].mte);
|
|
|
- if (result)
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
- rt_free(device_partition[index].mte);
|
|
|
- device_partition[index].dev = NULL;
|
|
|
- device_partition[index].mte = NULL;
|
|
|
- return DFS_STATUS_OK;
|
|
|
- }
|
|
|
- }
|
|
|
- return -DFS_STATUS_ENOENT;
|
|
|
+ int result;
|
|
|
+ unsigned index;
|
|
|
+
|
|
|
+ /* find device index, then umount it */
|
|
|
+ for (index = 0; index < DEVICE_PART_MAX; index++)
|
|
|
+ {
|
|
|
+ if (device_partition[index].dev == RT_MTD_NOR_DEVICE(fs->dev_id))
|
|
|
+ {
|
|
|
+ result = jffs2_umount(device_partition[index].mte);
|
|
|
+ if (result) return jffs2_result_to_dfs(result);
|
|
|
+
|
|
|
+ rt_free(device_partition[index].mte);
|
|
|
+ device_partition[index].dev = NULL;
|
|
|
+ device_partition[index].mte = NULL;
|
|
|
+ return RT_EOK;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return -ENOENT;
|
|
|
}
|
|
|
|
|
|
static int dfs_jffs2_mkfs(rt_device_t dev_id)
|
|
|
{
|
|
|
- /* just erase all blocks on this nand partition */
|
|
|
- return -DFS_STATUS_ENOSYS;
|
|
|
+ /* just erase all blocks on this nand partition */
|
|
|
+ return -ENOSYS;
|
|
|
}
|
|
|
|
|
|
-static int dfs_jffs2_statfs(struct dfs_filesystem* fs,
|
|
|
+static int dfs_jffs2_statfs(struct dfs_filesystem* fs,
|
|
|
struct statfs *buf)
|
|
|
{
|
|
|
- /* since the limit of unsigned long, so the max size of flash device is 4G */
|
|
|
- struct cyg_mtab_entry * mte;
|
|
|
- struct jffs2_fs_info info;
|
|
|
- int result;
|
|
|
-
|
|
|
- result = _find_fs(&mte, fs->dev_id);
|
|
|
- if (result)
|
|
|
- return -DFS_STATUS_ENOENT;
|
|
|
-
|
|
|
- RT_ASSERT(mte->data != NULL);
|
|
|
-
|
|
|
- jffs2_get_info_from_sb((void *)mte->data, &info);
|
|
|
- buf->f_bsize = info.sector_size;
|
|
|
- buf->f_blocks = info.nr_blocks;
|
|
|
- buf->f_bfree = info.free_size / info.sector_size;
|
|
|
-
|
|
|
- return 0;
|
|
|
+ /* since the limit of unsigned long, so the max size of flash device is 4G */
|
|
|
+ struct cyg_mtab_entry * mte;
|
|
|
+ struct jffs2_fs_info info;
|
|
|
+ int result;
|
|
|
+
|
|
|
+ result = _find_fs(&mte, fs->dev_id);
|
|
|
+ if (result)
|
|
|
+ return -ENOENT;
|
|
|
+
|
|
|
+ RT_ASSERT(mte->data != 0);
|
|
|
+
|
|
|
+ jffs2_get_info_from_sb((void *)mte->data, &info);
|
|
|
+ buf->f_bsize = info.sector_size;
|
|
|
+ buf->f_blocks = info.nr_blocks;
|
|
|
+ buf->f_bfree = info.free_size / info.sector_size;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static const char jffs2_root_path[] = ".";
|
|
|
|
|
|
static int dfs_jffs2_open(struct dfs_fd* file)
|
|
|
{
|
|
|
- int oflag, mode;
|
|
|
- int result;
|
|
|
- cyg_file * jffs2_file;
|
|
|
- struct cyg_mtab_entry * mte;
|
|
|
- const char * name;
|
|
|
-
|
|
|
- oflag = file->flags;
|
|
|
-
|
|
|
- jffs2_file = rt_malloc(sizeof(cyg_file));
|
|
|
- if (jffs2_file == RT_NULL)
|
|
|
- return -DFS_STATUS_ENOMEM;
|
|
|
-
|
|
|
- /* just escape '/' provided by dfs code */
|
|
|
- name = file->path;
|
|
|
- if ((name[0] == '/') && (name[1] == 0))
|
|
|
- name = jffs2_root_path;
|
|
|
- else /* name[0] still will be '/' */
|
|
|
- name ++;
|
|
|
-
|
|
|
- result = _find_fs(&mte, file->fs->dev_id);
|
|
|
- if (result)
|
|
|
- {
|
|
|
- rt_free(jffs2_file);
|
|
|
- return -DFS_STATUS_ENOENT;
|
|
|
- }
|
|
|
-
|
|
|
- if (oflag & DFS_O_DIRECTORY) /* operations about dir */
|
|
|
- {
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
- if (oflag & DFS_O_CREAT) /* create a dir*/
|
|
|
- {
|
|
|
- /* fixme, should test file->path can end with '/' */
|
|
|
- result = jffs2_mkdir(mte, mte->root, name);
|
|
|
- if (result)
|
|
|
- {
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- rt_free(jffs2_file);
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
- }
|
|
|
- }
|
|
|
- /* open dir */
|
|
|
- result = jffs2_opendir(mte, mte->root, name, jffs2_file);
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- if (result)
|
|
|
- {
|
|
|
- rt_free(jffs2_file);
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
- }
|
|
|
+ int result;
|
|
|
+ int oflag, mode;
|
|
|
+ const char * name;
|
|
|
+ cyg_file * jffs2_file;
|
|
|
+ struct dfs_filesystem *fs;
|
|
|
+ struct cyg_mtab_entry * mte;
|
|
|
+
|
|
|
+ oflag = file->flags;
|
|
|
+ fs = (struct dfs_filesystem *)file->data;
|
|
|
+ RT_ASSERT(fs != RT_NULL);
|
|
|
+
|
|
|
+ jffs2_file = rt_malloc(sizeof(cyg_file));
|
|
|
+ if (jffs2_file == RT_NULL)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ /* just escape '/' provided by dfs code */
|
|
|
+ name = file->path;
|
|
|
+ if ((name[0] == '/') && (name[1] == 0))
|
|
|
+ name = jffs2_root_path;
|
|
|
+ else /* name[0] still will be '/' */
|
|
|
+ name ++;
|
|
|
+
|
|
|
+ result = _find_fs(&mte, fs->dev_id);
|
|
|
+ if (result)
|
|
|
+ {
|
|
|
+ rt_free(jffs2_file);
|
|
|
+ return -ENOENT;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* set mount table */
|
|
|
+ jffs2_file->f_mte = mte;
|
|
|
+
|
|
|
+ if (oflag & O_DIRECTORY) /* operations about dir */
|
|
|
+ {
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ if (oflag & O_CREAT) /* create a dir*/
|
|
|
+ {
|
|
|
+ /* fixme, should test file->path can end with '/' */
|
|
|
+ result = jffs2_mkdir(mte, mte->root, name);
|
|
|
+ if (result)
|
|
|
+ {
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ rt_free(jffs2_file);
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* open dir */
|
|
|
+ result = jffs2_opendir(mte, mte->root, name, jffs2_file);
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ if (result)
|
|
|
+ {
|
|
|
+ rt_free(jffs2_file);
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+ }
|
|
|
#ifdef CONFIG_JFFS2_NO_RELATIVEDIR
|
|
|
- jffs2_file->f_offset = 2;
|
|
|
+ jffs2_file->f_offset = 2;
|
|
|
#endif
|
|
|
- /* save this pointer, it will be used by dfs_jffs2_getdents*/
|
|
|
- file->data = jffs2_file;
|
|
|
- return 0;
|
|
|
- }
|
|
|
- /* regular file operations */
|
|
|
- mode = 0;
|
|
|
- if (oflag & DFS_O_RDONLY) mode |= JFFS2_O_RDONLY;
|
|
|
- if (oflag & DFS_O_WRONLY) mode |= JFFS2_O_WRONLY;
|
|
|
- if (oflag & DFS_O_RDWR) mode |= JFFS2_O_RDWR;
|
|
|
- /* Opens the file, if it is existing. If not, a new file is created. */
|
|
|
- if (oflag & DFS_O_CREAT) mode |= JFFS2_O_CREAT;
|
|
|
- /* Creates a new file. If the file is existing, it is truncated and overwritten. */
|
|
|
- if (oflag & DFS_O_TRUNC) mode |= JFFS2_O_TRUNC;
|
|
|
- /* Creates a new file. The function fails if the file is already existing. */
|
|
|
- if (oflag & DFS_O_EXCL) mode |= JFFS2_O_EXCL;
|
|
|
-// if (oflag & DFS_O_APPEND) mode |= JFFS2_O_APPEND;
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ /* save this pointer, it will be used by dfs_jffs2_getdents*/
|
|
|
+ file->data = jffs2_file;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ /* regular file operations */
|
|
|
+ mode = JFFS2_O_RDONLY;
|
|
|
+ if (oflag & O_WRONLY) mode |= JFFS2_O_WRONLY;
|
|
|
+ if (oflag & O_RDWR) mode |= JFFS2_O_RDWR;
|
|
|
+ /* Opens the file, if it is existing. If not, a new file is created. */
|
|
|
+ if (oflag & O_CREAT) mode |= JFFS2_O_CREAT;
|
|
|
+ /* Creates a new file. If the file is existing, it is truncated and overwritten. */
|
|
|
+ if (oflag & O_TRUNC) mode |= JFFS2_O_TRUNC;
|
|
|
+ /* Creates a new file. The function fails if the file is already existing. */
|
|
|
+ if (oflag & O_EXCL) mode |= JFFS2_O_EXCL;
|
|
|
+
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
result = jffs2_open(mte, 0, name, mode, jffs2_file);
|
|
|
if (result != 0)
|
|
|
{
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- rt_free(jffs2_file);
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ rt_free(jffs2_file);
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
}
|
|
|
-
|
|
|
- /* save this pointer, it will be used when calling read()��write(),
|
|
|
- flush(), lessk(), and will be rt_free when calling close()*/
|
|
|
- file->data = jffs2_file;
|
|
|
- file->pos = jffs2_file->f_offset;
|
|
|
- file->size = 0;
|
|
|
- jffs2_file_lseek(jffs2_file, (off_t *)(&(file->size)), DFS_SEEK_END);
|
|
|
- jffs2_file->f_offset = (off_t)file->pos;
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
-
|
|
|
- if (oflag & DFS_O_APPEND)
|
|
|
- {
|
|
|
- file->pos = file->size;
|
|
|
- jffs2_file->f_offset = file->size;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
+
|
|
|
+ /* save this pointer, it will be used when calling read()��write(),
|
|
|
+ flush(), lessk(), and will be rt_free when calling close()*/
|
|
|
+ file->data = jffs2_file;
|
|
|
+ file->pos = jffs2_file->f_offset;
|
|
|
+ file->size = 0;
|
|
|
+ jffs2_file_lseek(jffs2_file, (off_t *)(&(file->size)), SEEK_END);
|
|
|
+ jffs2_file->f_offset = (off_t)file->pos;
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+
|
|
|
+ if (oflag & O_APPEND)
|
|
|
+ {
|
|
|
+ file->pos = file->size;
|
|
|
+ jffs2_file->f_offset = file->size;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
static int dfs_jffs2_close(struct dfs_fd* file)
|
|
|
{
|
|
|
- int result;
|
|
|
- cyg_file * jffs2_file;
|
|
|
-
|
|
|
- RT_ASSERT(file->data != NULL);
|
|
|
- jffs2_file = (cyg_file *)(file->data);
|
|
|
-
|
|
|
- if (file->flags & DFS_O_DIRECTORY) /* operations about dir */
|
|
|
- {
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
- result = jffs2_dir_colse(jffs2_file);
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- if (result)
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
-
|
|
|
- rt_free(jffs2_file);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- /* regular file operations */
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
- result = jffs2_file_colse(jffs2_file);
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- if (result)
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
-
|
|
|
- /* release memory */
|
|
|
- rt_free(jffs2_file);
|
|
|
- return 0;
|
|
|
+ int result;
|
|
|
+ cyg_file * jffs2_file;
|
|
|
+
|
|
|
+ RT_ASSERT(file->data != NULL);
|
|
|
+ jffs2_file = (cyg_file *)(file->data);
|
|
|
+
|
|
|
+ if (file->flags & O_DIRECTORY) /* operations about dir */
|
|
|
+ {
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ result = jffs2_dir_colse(jffs2_file);
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ if (result)
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+
|
|
|
+ rt_free(jffs2_file);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ /* regular file operations */
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ result = jffs2_file_colse(jffs2_file);
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ if (result)
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+
|
|
|
+ /* release memory */
|
|
|
+ rt_free(jffs2_file);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static int dfs_jffs2_ioctl(struct dfs_fd* file, int cmd, void* args)
|
|
|
{
|
|
|
- return -DFS_STATUS_ENOSYS;
|
|
|
+ return -ENOSYS;
|
|
|
}
|
|
|
|
|
|
-static int dfs_jffs2_read(struct dfs_fd* file, void* buf, rt_size_t len)
|
|
|
+static int dfs_jffs2_read(struct dfs_fd* file, void* buf, size_t len)
|
|
|
{
|
|
|
- cyg_file * jffs2_file;
|
|
|
- struct CYG_UIO_TAG uio_s;
|
|
|
- struct CYG_IOVEC_TAG iovec;
|
|
|
- int char_read;
|
|
|
- int result;
|
|
|
-
|
|
|
- RT_ASSERT(file->data != NULL);
|
|
|
- jffs2_file = (cyg_file *)(file->data);
|
|
|
+ cyg_file * jffs2_file;
|
|
|
+ struct CYG_UIO_TAG uio_s;
|
|
|
+ struct CYG_IOVEC_TAG iovec;
|
|
|
+ int char_read;
|
|
|
+ int result;
|
|
|
+
|
|
|
+ RT_ASSERT(file->data != NULL);
|
|
|
+ jffs2_file = (cyg_file *)(file->data);
|
|
|
uio_s.uio_iov = &iovec;
|
|
|
uio_s.uio_iov->iov_base = buf;
|
|
|
uio_s.uio_iov->iov_len = len;
|
|
|
uio_s.uio_iovcnt = 1; //must be 1
|
|
|
//uio_s.uio_offset //not used...
|
|
|
uio_s.uio_resid = uio_s.uio_iov->iov_len; //seem no use in jffs2;
|
|
|
-
|
|
|
- char_read = jffs2_file->f_offset; /* the current offset */
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
- result = jffs2_file_read(jffs2_file, &uio_s);
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- if (result)
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
-
|
|
|
- /* update position */
|
|
|
- file->pos = jffs2_file->f_offset;
|
|
|
- char_read = jffs2_file->f_offset - char_read;
|
|
|
- return char_read;
|
|
|
+
|
|
|
+ char_read = jffs2_file->f_offset; /* the current offset */
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ result = jffs2_file_read(jffs2_file, &uio_s);
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ if (result)
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+
|
|
|
+ /* update position */
|
|
|
+ file->pos = jffs2_file->f_offset;
|
|
|
+ char_read = jffs2_file->f_offset - char_read;
|
|
|
+ return char_read;
|
|
|
}
|
|
|
|
|
|
-static int dfs_jffs2_write(struct dfs_fd* file,
|
|
|
- const void* buf,
|
|
|
- rt_size_t len)
|
|
|
+static int dfs_jffs2_write(struct dfs_fd* file,
|
|
|
+ const void* buf,
|
|
|
+ size_t len)
|
|
|
{
|
|
|
- cyg_file * jffs2_file;
|
|
|
- struct CYG_UIO_TAG uio_s;
|
|
|
- struct CYG_IOVEC_TAG iovec;
|
|
|
- int char_write;
|
|
|
- int result;
|
|
|
-
|
|
|
- RT_ASSERT(file->data != NULL);
|
|
|
- jffs2_file = (cyg_file *)(file->data);
|
|
|
+ cyg_file * jffs2_file;
|
|
|
+ struct CYG_UIO_TAG uio_s;
|
|
|
+ struct CYG_IOVEC_TAG iovec;
|
|
|
+ int char_write;
|
|
|
+ int result;
|
|
|
+
|
|
|
+ RT_ASSERT(file->data != NULL);
|
|
|
+ jffs2_file = (cyg_file *)(file->data);
|
|
|
uio_s.uio_iov = &iovec;
|
|
|
uio_s.uio_iov->iov_base = (void *)buf;
|
|
|
uio_s.uio_iov->iov_len = len;
|
|
|
uio_s.uio_iovcnt = 1; //must be 1
|
|
|
//uio_s.uio_offset //not used...
|
|
|
uio_s.uio_resid = uio_s.uio_iov->iov_len; //seem no use in jffs2;
|
|
|
-
|
|
|
- char_write = jffs2_file->f_offset;
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
- result = jffs2_file_write(jffs2_file, &uio_s);
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- if (result)
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
-
|
|
|
- /* update position */
|
|
|
- file->pos = jffs2_file->f_offset;
|
|
|
- char_write = jffs2_file->f_offset - char_write;
|
|
|
- return char_write;
|
|
|
+
|
|
|
+ char_write = jffs2_file->f_offset;
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ result = jffs2_file_write(jffs2_file, &uio_s);
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ if (result)
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+
|
|
|
+ /* update position */
|
|
|
+ file->pos = jffs2_file->f_offset;
|
|
|
+ char_write = jffs2_file->f_offset - char_write;
|
|
|
+ return char_write;
|
|
|
}
|
|
|
|
|
|
static int dfs_jffs2_flush(struct dfs_fd* file)
|
|
|
{
|
|
|
- /* infact, jffs2 not support, jffs2_fo_sync just return ok */
|
|
|
- return -DFS_STATUS_ENOSYS;
|
|
|
+ /* infact, jffs2 not support, jffs2_fo_sync just return ok */
|
|
|
+ return -ENOSYS;
|
|
|
}
|
|
|
|
|
|
/* fixme warning: the offset is rt_off_t, so maybe the size of a file is must <= 2G*/
|
|
|
-static int dfs_jffs2_lseek(struct dfs_fd* file,
|
|
|
+static int dfs_jffs2_lseek(struct dfs_fd* file,
|
|
|
rt_off_t offset)
|
|
|
{
|
|
|
- cyg_file * jffs2_file;
|
|
|
- int result;
|
|
|
-
|
|
|
- RT_ASSERT(file->data != NULL);
|
|
|
- jffs2_file = (cyg_file *)(file->data);
|
|
|
-
|
|
|
- /* set offset as current offset */
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
- result = jffs2_file_lseek(jffs2_file, &offset, DFS_SEEK_SET);
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- if (result)
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
- /* update file position */
|
|
|
- file->pos = offset;
|
|
|
- return offset;
|
|
|
+ cyg_file * jffs2_file;
|
|
|
+ int result;
|
|
|
+
|
|
|
+ RT_ASSERT(file->data != NULL);
|
|
|
+ jffs2_file = (cyg_file *)(file->data);
|
|
|
+
|
|
|
+ /* set offset as current offset */
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ result = jffs2_file_lseek(jffs2_file, &offset, SEEK_SET);
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ if (result)
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+ /* update file position */
|
|
|
+ file->pos = offset;
|
|
|
+ return offset;
|
|
|
}
|
|
|
|
|
|
/* return the size of struct dirent*/
|
|
|
-static int dfs_jffs2_getdents(struct dfs_fd* file,
|
|
|
- struct dirent* dirp,
|
|
|
- rt_uint32_t count)
|
|
|
+static int dfs_jffs2_getdents(struct dfs_fd* file,
|
|
|
+ struct dirent* dirp,
|
|
|
+ rt_uint32_t count)
|
|
|
{
|
|
|
- cyg_file * jffs2_file;
|
|
|
- struct CYG_UIO_TAG uio_s;
|
|
|
- struct CYG_IOVEC_TAG iovec;
|
|
|
- struct jffs2_dirent jffs2_d;
|
|
|
- struct dirent * d;
|
|
|
- rt_uint32_t index;
|
|
|
+ cyg_file * jffs2_file;
|
|
|
+ struct CYG_UIO_TAG uio_s;
|
|
|
+ struct CYG_IOVEC_TAG iovec;
|
|
|
+ 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;
|
|
|
+ struct jffs2_stat s;
|
|
|
+ cyg_mtab_entry * mte;
|
|
|
+ char * fullname;
|
|
|
#endif
|
|
|
- int result;
|
|
|
-
|
|
|
- RT_ASSERT(file->data != RT_NULL);
|
|
|
- jffs2_file = (cyg_file*)(file->data);
|
|
|
-
|
|
|
- //set jffs2_d
|
|
|
- memset(&jffs2_d, 0, sizeof(struct jffs2_dirent));
|
|
|
- //set CYG_UIO_TAG uio_s
|
|
|
- uio_s.uio_iov = &iovec;
|
|
|
- uio_s.uio_iov->iov_base = &jffs2_d;
|
|
|
- uio_s.uio_iov->iov_len = sizeof(struct jffs2_dirent);;
|
|
|
- uio_s.uio_iovcnt = 1; //must be 1
|
|
|
- uio_s.uio_offset = 0;//not used...
|
|
|
- uio_s.uio_resid = uio_s.uio_iov->iov_len; //seem no use in jffs2;
|
|
|
+ int result;
|
|
|
|
|
|
-#if !defined (CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE)
|
|
|
+ RT_ASSERT(file->data != RT_NULL);
|
|
|
+ jffs2_file = (cyg_file*)(file->data);
|
|
|
+ mte = jffs2_file->f_mte;
|
|
|
|
|
|
- result = _find_fs(&mte, file->fs->dev_id);
|
|
|
- if (result)
|
|
|
- return -DFS_STATUS_ENOENT;
|
|
|
-#endif
|
|
|
+ //set jffs2_d
|
|
|
+ memset(&jffs2_d, 0, sizeof(struct jffs2_dirent));
|
|
|
+ //set CYG_UIO_TAG uio_s
|
|
|
+ uio_s.uio_iov = &iovec;
|
|
|
+ uio_s.uio_iov->iov_base = &jffs2_d;
|
|
|
+ uio_s.uio_iov->iov_len = sizeof(struct jffs2_dirent);;
|
|
|
+ uio_s.uio_iovcnt = 1; //must be 1
|
|
|
+ uio_s.uio_offset = 0;//not used...
|
|
|
+ uio_s.uio_resid = uio_s.uio_iov->iov_len; //seem no use in jffs2;
|
|
|
|
|
|
- /* make integer count, usually count is 1 */
|
|
|
- count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
|
|
|
- if (count == 0)
|
|
|
- return -DFS_STATUS_EINVAL;
|
|
|
-
|
|
|
- index = 0;
|
|
|
- /* usually, the while loop should only be looped only once! */
|
|
|
- while (1)
|
|
|
- {
|
|
|
- d = dirp + index;
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
- result = jffs2_dir_read(jffs2_file, &uio_s);
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- /* if met a error or all entry are read over, break while*/
|
|
|
- if (result || jffs2_d.d_name[0] == 0)
|
|
|
- break;
|
|
|
+ /* make integer count, usually count is 1 */
|
|
|
+ count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
|
|
|
+ if (count == 0) return -EINVAL;
|
|
|
+
|
|
|
+ index = 0;
|
|
|
+ /* usually, the while loop should only be looped only once! */
|
|
|
+ while (1)
|
|
|
+ {
|
|
|
+ d = dirp + index;
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ result = jffs2_dir_read(jffs2_file, &uio_s);
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ /* if met a error or all entry are read over, break while*/
|
|
|
+ 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;
|
|
|
- }
|
|
|
+ switch(jffs2_d.d_type & JFFS2_S_IFMT)
|
|
|
+ {
|
|
|
+ case JFFS2_S_IFREG: d->d_type = DT_REG; break;
|
|
|
+ case JFFS2_S_IFDIR: d->d_type = DT_DIR; break;
|
|
|
+ default: d->d_type = 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);
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
- result = jffs2_porting_stat(mte, mte->root, fullname, (void *)&s);
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- 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;
|
|
|
- }
|
|
|
+ fullname = rt_malloc(FILE_PATH_MAX);
|
|
|
+ if(fullname == RT_NULL)
|
|
|
+ return -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);
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ result = jffs2_porting_stat(mte, mte->root, fullname, (void *)&s);
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ 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 = DT_REG; break;
|
|
|
+ case JFFS2_S_IFDIR: d->d_type = DT_DIR; break;
|
|
|
+ default: d->d_type = 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);
|
|
|
-
|
|
|
- index ++;
|
|
|
- if (index * sizeof(struct dirent) >= count)
|
|
|
- break;
|
|
|
- }
|
|
|
- if (result)
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
- return index * sizeof(struct dirent);
|
|
|
+ /* 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);
|
|
|
+
|
|
|
+ index ++;
|
|
|
+ if (index * sizeof(struct dirent) >= count)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (result)
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+ return index * sizeof(struct dirent);
|
|
|
}
|
|
|
|
|
|
static int dfs_jffs2_unlink(struct dfs_filesystem* fs, const char* path)
|
|
|
{
|
|
|
- int result;
|
|
|
- struct jffs2_stat s;
|
|
|
- cyg_mtab_entry * mte;
|
|
|
-
|
|
|
- result = _find_fs(&mte, fs->dev_id);
|
|
|
- if (result)
|
|
|
- return -DFS_STATUS_ENOENT;
|
|
|
-
|
|
|
- /* deal path */
|
|
|
- if (path[0] == '/')
|
|
|
- path++;
|
|
|
-
|
|
|
- /* judge file type, dir is to be delete by rmdir, others by unlink */
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
- result = jffs2_porting_stat(mte, mte->root, path, (void *)&s);
|
|
|
- if (result)
|
|
|
- {
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
- }
|
|
|
-
|
|
|
- switch(s.st_mode & JFFS2_S_IFMT)
|
|
|
- {
|
|
|
- case JFFS2_S_IFREG:
|
|
|
- result = jffs2_file_unlink(mte, mte->root, path);
|
|
|
- break;
|
|
|
- case JFFS2_S_IFDIR:
|
|
|
- result = jffs2_rmdir(mte, mte->root, path);
|
|
|
- break;
|
|
|
- default:
|
|
|
- /* unknown file type */
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- if (result)
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
- return 0;
|
|
|
+ int result;
|
|
|
+ struct jffs2_stat s;
|
|
|
+ cyg_mtab_entry * mte;
|
|
|
+
|
|
|
+ result = _find_fs(&mte, fs->dev_id);
|
|
|
+ if (result)
|
|
|
+ return -ENOENT;
|
|
|
+
|
|
|
+ /* deal path */
|
|
|
+ if (path[0] == '/')
|
|
|
+ path++;
|
|
|
+
|
|
|
+ /* judge file type, dir is to be delete by rmdir, others by unlink */
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ result = jffs2_porting_stat(mte, mte->root, path, (void *)&s);
|
|
|
+ if (result)
|
|
|
+ {
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ switch(s.st_mode & JFFS2_S_IFMT)
|
|
|
+ {
|
|
|
+ case JFFS2_S_IFREG:
|
|
|
+ result = jffs2_file_unlink(mte, mte->root, path);
|
|
|
+ break;
|
|
|
+ case JFFS2_S_IFDIR:
|
|
|
+ result = jffs2_rmdir(mte, mte->root, path);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ /* unknown file type */
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ if (result)
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-static int dfs_jffs2_rename(struct dfs_filesystem* fs,
|
|
|
+static int dfs_jffs2_rename(struct dfs_filesystem* fs,
|
|
|
const char* oldpath,
|
|
|
- const char* newpath)
|
|
|
+ const char* newpath)
|
|
|
{
|
|
|
- int result;
|
|
|
- cyg_mtab_entry * mte;
|
|
|
-
|
|
|
- result = _find_fs(&mte, fs->dev_id);
|
|
|
- if (result)
|
|
|
- return -DFS_STATUS_ENOENT;
|
|
|
-
|
|
|
- if (*oldpath == '/')
|
|
|
- oldpath += 1;
|
|
|
- if (*newpath == '/')
|
|
|
- newpath += 1;
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
- result = jffs2_rename(mte, mte->root, oldpath, mte->root, newpath);
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
- if (result)
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
- return 0;
|
|
|
+ int result;
|
|
|
+ cyg_mtab_entry * mte;
|
|
|
+
|
|
|
+ result = _find_fs(&mte, fs->dev_id);
|
|
|
+ if (result)
|
|
|
+ return -ENOENT;
|
|
|
+
|
|
|
+ if (*oldpath == '/')
|
|
|
+ oldpath += 1;
|
|
|
+ if (*newpath == '/')
|
|
|
+ newpath += 1;
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ result = jffs2_rename(mte, mte->root, oldpath, mte->root, newpath);
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+ if (result)
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static int dfs_jffs2_stat(struct dfs_filesystem* fs, const char *path, struct stat *st)
|
|
|
{
|
|
|
- int result;
|
|
|
- struct jffs2_stat s;
|
|
|
- cyg_mtab_entry * mte;
|
|
|
-
|
|
|
- /* deal the path for jffs2 */
|
|
|
- RT_ASSERT(!((path[0] == '/') && (path[1] == 0)));
|
|
|
-
|
|
|
- if (path[0] == '/')
|
|
|
- path++;
|
|
|
-
|
|
|
- result = _find_fs(&mte, fs->dev_id);
|
|
|
- if (result)
|
|
|
- return -DFS_STATUS_ENOENT;
|
|
|
-
|
|
|
- rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
- result = jffs2_porting_stat(mte, mte->root, path, (void *)&s);
|
|
|
- rt_mutex_release(&jffs2_lock);
|
|
|
-
|
|
|
- if (result)
|
|
|
- return jffs2_result_to_dfs(result);
|
|
|
- /* convert to dfs stat structure */
|
|
|
- switch(s.st_mode & JFFS2_S_IFMT)
|
|
|
- {
|
|
|
- case JFFS2_S_IFREG:
|
|
|
- st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
|
|
- DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
|
|
- break;
|
|
|
-
|
|
|
- case JFFS2_S_IFDIR:
|
|
|
- st->st_mode = DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- st->st_mode = DFS_DT_UNKNOWN; //fixme
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- st->st_dev = 0;
|
|
|
- st->st_size = s.st_size;
|
|
|
- st->st_mtime = s.st_mtime;
|
|
|
-
|
|
|
- return 0;
|
|
|
+ int result;
|
|
|
+ struct jffs2_stat s;
|
|
|
+ cyg_mtab_entry * mte;
|
|
|
+
|
|
|
+ /* deal the path for jffs2 */
|
|
|
+ RT_ASSERT(!((path[0] == '/') && (path[1] == 0)));
|
|
|
+
|
|
|
+ if (path[0] == '/')
|
|
|
+ path++;
|
|
|
+
|
|
|
+ result = _find_fs(&mte, fs->dev_id);
|
|
|
+ if (result)
|
|
|
+ return -ENOENT;
|
|
|
+
|
|
|
+ rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER);
|
|
|
+ result = jffs2_porting_stat(mte, mte->root, path, (void *)&s);
|
|
|
+ rt_mutex_release(&jffs2_lock);
|
|
|
+
|
|
|
+ if (result)
|
|
|
+ return jffs2_result_to_dfs(result);
|
|
|
+ /* convert to dfs stat structure */
|
|
|
+ switch(s.st_mode & JFFS2_S_IFMT)
|
|
|
+ {
|
|
|
+ case JFFS2_S_IFREG:
|
|
|
+ st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
|
|
+ S_IWUSR | S_IWGRP | S_IWOTH;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case JFFS2_S_IFDIR:
|
|
|
+ st->st_mode = S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ st->st_mode = DT_UNKNOWN; //fixme
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ st->st_dev = 0;
|
|
|
+ st->st_size = s.st_size;
|
|
|
+ st->st_mtime = s.st_mtime;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-static const struct dfs_filesystem_operation dfs_jffs2_ops =
|
|
|
+static const struct dfs_file_ops _jffs2_fops =
|
|
|
{
|
|
|
- "jffs2", /* file system type: jffs2 */
|
|
|
-#if RTTHREAD_VERSION >= 10100
|
|
|
- DFS_FS_FLAG_DEFAULT, /* use Relative Path */
|
|
|
-#endif
|
|
|
- dfs_jffs2_mount,
|
|
|
- dfs_jffs2_unmount,
|
|
|
- dfs_jffs2_mkfs,
|
|
|
- dfs_jffs2_statfs,
|
|
|
-
|
|
|
- dfs_jffs2_open,
|
|
|
- dfs_jffs2_close,
|
|
|
- dfs_jffs2_ioctl,
|
|
|
- dfs_jffs2_read,
|
|
|
- dfs_jffs2_write,
|
|
|
- dfs_jffs2_flush,
|
|
|
- dfs_jffs2_lseek,
|
|
|
- dfs_jffs2_getdents,
|
|
|
- dfs_jffs2_unlink,
|
|
|
- dfs_jffs2_stat,
|
|
|
- dfs_jffs2_rename,
|
|
|
+ dfs_jffs2_open,
|
|
|
+ dfs_jffs2_close,
|
|
|
+ dfs_jffs2_ioctl,
|
|
|
+ dfs_jffs2_read,
|
|
|
+ dfs_jffs2_write,
|
|
|
+ dfs_jffs2_flush,
|
|
|
+ dfs_jffs2_lseek,
|
|
|
+ dfs_jffs2_getdents,
|
|
|
+};
|
|
|
+
|
|
|
+static const struct dfs_filesystem_ops _jffs2_ops =
|
|
|
+{
|
|
|
+ "jffs2",
|
|
|
+ DFS_FS_FLAG_DEFAULT,
|
|
|
+ &_jffs2_fops,
|
|
|
+
|
|
|
+ dfs_jffs2_mount,
|
|
|
+ dfs_jffs2_unmount,
|
|
|
+ dfs_jffs2_mkfs,
|
|
|
+ dfs_jffs2_statfs,
|
|
|
+
|
|
|
+ dfs_jffs2_unlink,
|
|
|
+ dfs_jffs2_stat,
|
|
|
+ dfs_jffs2_rename,
|
|
|
};
|
|
|
|
|
|
int dfs_jffs2_init(void)
|
|
|
{
|
|
|
/* register fatfs file system */
|
|
|
- dfs_register(&dfs_jffs2_ops);
|
|
|
+ dfs_register(&_jffs2_ops);
|
|
|
+
|
|
|
/* initialize mutex */
|
|
|
- if (rt_mutex_init(&jffs2_lock, "jffs2lock", RT_IPC_FLAG_FIFO) != RT_EOK)
|
|
|
- {
|
|
|
- rt_kprintf("init jffs2 lock mutex failed\n");
|
|
|
- }
|
|
|
- rt_kprintf("init jffs2 lock mutex okay\n");
|
|
|
- return 0;
|
|
|
+ if (rt_mutex_init(&jffs2_lock, "jffs2lock", RT_IPC_FLAG_FIFO) != RT_EOK)
|
|
|
+ {
|
|
|
+ rt_kprintf("init jffs2 lock mutex failed\n");
|
|
|
+ }
|
|
|
+ rt_kprintf("init jffs2 lock mutex okay\n");
|
|
|
+ return 0;
|
|
|
}
|
|
|
INIT_COMPONENT_EXPORT(dfs_jffs2_init);
|
|
|
-
|