From beaf51ff8226f6f2f6d7a598cae7dd929d4afcaa Mon Sep 17 00:00:00 2001 From: "bernard.xiong@gmail.com" Date: Sun, 1 Jan 2012 13:37:21 +0000 Subject: [PATCH] add full path options (DFS_FS_FLAG_FULLPATH) to the file system. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1904 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/dfs/filesystems/devfs/devfs.c | 1 + components/dfs/filesystems/elmfat/dfs_elm.c | 1 + components/dfs/filesystems/nfs/dfs_nfs.c | 3 +- components/dfs/filesystems/romfs/dfs_romfs.c | 583 +++++++-------- .../dfs/filesystems/skeleton/skeleton.c | 1 + components/dfs/filesystems/uffs/dfs_uffs.c | 699 +++++++++--------- components/dfs/include/dfs_fs.h | 4 + components/dfs/src/dfs_file.c | 36 +- 8 files changed, 677 insertions(+), 651 deletions(-) diff --git a/components/dfs/filesystems/devfs/devfs.c b/components/dfs/filesystems/devfs/devfs.c index 2a8e78df5e..45195f3c29 100644 --- a/components/dfs/filesystems/devfs/devfs.c +++ b/components/dfs/filesystems/devfs/devfs.c @@ -248,6 +248,7 @@ int dfs_device_fs_getdents(struct dfs_fd* file, struct dirent* dirp, rt_uint32_t static const struct dfs_filesystem_operation _device_fs = { "devfs", + DFS_FS_FLAG_DEFAULT, dfs_device_fs_mount, RT_NULL, RT_NULL, diff --git a/components/dfs/filesystems/elmfat/dfs_elm.c b/components/dfs/filesystems/elmfat/dfs_elm.c index 1beea7bbf5..d4f1dfc878 100644 --- a/components/dfs/filesystems/elmfat/dfs_elm.c +++ b/components/dfs/filesystems/elmfat/dfs_elm.c @@ -647,6 +647,7 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) static const struct dfs_filesystem_operation dfs_elm = { "elm", + DFS_FS_FLAG_DEFAULT, dfs_elm_mount, dfs_elm_unmount, dfs_elm_mkfs, diff --git a/components/dfs/filesystems/nfs/dfs_nfs.c b/components/dfs/filesystems/nfs/dfs_nfs.c index 528d4d910e..cbfdd128e0 100644 --- a/components/dfs/filesystems/nfs/dfs_nfs.c +++ b/components/dfs/filesystems/nfs/dfs_nfs.c @@ -1056,7 +1056,8 @@ int nfs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count) static const struct dfs_filesystem_operation _nfs = { - "nfs", + "nfs", + DFS_FS_FLAG_DEFAULT, nfs_mount, nfs_unmount, RT_NULL, /* mkfs */ diff --git a/components/dfs/filesystems/romfs/dfs_romfs.c b/components/dfs/filesystems/romfs/dfs_romfs.c index 760593b58c..d21c336f19 100644 --- a/components/dfs/filesystems/romfs/dfs_romfs.c +++ b/components/dfs/filesystems/romfs/dfs_romfs.c @@ -1,291 +1,292 @@ -/* - * File : dfs_romfs.c - * This file is part of Device File System in RT-Thread RTOS - * COPYRIGHT (C) 2004-2011, 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. - * - * Change Logs: - * Date Author Notes - */ - -#include -#include -#include -#include "dfs_romfs.h" - -int dfs_romfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) -{ - struct romfs_dirent *root_dirent; - - if (data == RT_NULL) - return -DFS_STATUS_EIO; - - root_dirent = (struct romfs_dirent *)data; - fs->data = root_dirent; - - return DFS_STATUS_OK; -} - -int dfs_romfs_unmount(struct dfs_filesystem *fs) -{ - return DFS_STATUS_OK; -} - -int dfs_romfs_ioctl(struct dfs_fd *file, int cmd, void *args) -{ - return -DFS_STATUS_EIO; -} - -struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size) -{ - rt_size_t index, found; - const char *subpath, *subpath_end; - struct romfs_dirent *dirent; - rt_size_t dirent_size; - - if (path[0] == '/' && path[1] == '\0') - { - *size = root_dirent->size; - return root_dirent; - } - - /* goto root directy entries */ - dirent = (struct romfs_dirent *)root_dirent->data; - dirent_size = root_dirent->size; - - /* get the end position of this subpath */ - subpath_end = path; - /* skip /// */ - while (*subpath_end && *subpath_end == '/') - subpath_end ++; - subpath = subpath_end; - while ((*subpath_end != '/') && *subpath_end) - subpath_end ++; - - while (dirent != RT_NULL) - { - found = 0; - - /* search in folder */ - for (index = 0; index < dirent_size; index ++) - { - if (rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0) - { - dirent_size = dirent[index].size; - - /* skip /// */ - while (*subpath_end && *subpath_end == '/') - subpath_end ++; - subpath = subpath_end; - while ((*subpath_end != '/') && *subpath_end) - subpath_end ++; - - if (!(*subpath)) - { - *size = dirent_size; - return &dirent[index]; - } - - if (dirent[index].type == ROMFS_DIRENT_DIR) - { - /* enter directory */ - dirent = (struct romfs_dirent*)dirent[index].data; - found = 1; - break; - } - else - { - /* return file dirent */ - if (subpath != RT_NULL) - break; /* not the end of path */ - - return &dirent[index]; - } - } - } - - if (!found) - break; /* not found */ - } - - /* not found */ - return RT_NULL; -} - -int dfs_romfs_read(struct dfs_fd *file, void *buf, rt_size_t count) -{ - rt_size_t length; - struct romfs_dirent *dirent; - - dirent = (struct romfs_dirent *)file->data; - RT_ASSERT(dirent != RT_NULL); - - if (count < file->size - file->pos) - length = count; - else - length = file->size - file->pos; - - if (length > 0) - memcpy(buf, &(dirent->data[file->pos]), length); - - /* update file current position */ - file->pos += length; - - return length; -} - -int dfs_romfs_lseek(struct dfs_fd *file, rt_off_t offset) -{ - if (offset <= file->size) - { - file->pos = offset; - return file->pos; - } - - return -DFS_STATUS_EIO; -} - -int dfs_romfs_close(struct dfs_fd *file) -{ - file->data = RT_NULL; - return DFS_STATUS_OK; -} - -int dfs_romfs_open(struct dfs_fd *file) -{ - rt_size_t size; - struct romfs_dirent *dirent; - struct romfs_dirent *root_dirent; - - root_dirent = (struct romfs_dirent *)file->fs->data; - - if (file->flags & (DFS_O_CREAT | DFS_O_WRONLY | DFS_O_APPEND | DFS_O_TRUNC | DFS_O_RDWR)) - return -DFS_STATUS_EINVAL; - - dirent = dfs_romfs_lookup(root_dirent, file->path, &size); - if (dirent == RT_NULL) - return -DFS_STATUS_ENOENT; - - /* entry is a directory file type */ - if (dirent->type == ROMFS_DIRENT_DIR) - { - if (!(file->flags & DFS_O_DIRECTORY)) - return -DFS_STATUS_ENOENT; - } - else - { - /* entry is a file, but open it as a directory */ - if (file->flags & DFS_O_DIRECTORY) - return -DFS_STATUS_ENOENT; - } - - file->data = dirent; - file->size = size; - file->pos = 0; - - return DFS_STATUS_OK; -} - -int dfs_romfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) -{ - rt_size_t size; - struct romfs_dirent *dirent; - struct romfs_dirent *root_dirent; - - root_dirent = (struct romfs_dirent *)fs->data; - dirent = dfs_romfs_lookup(root_dirent, path, &size); - - if (dirent == RT_NULL) - return -DFS_STATUS_ENOENT; - - st->st_dev = 0; - st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH | - DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH; - - if (dirent->type == ROMFS_DIRENT_DIR) - { - st->st_mode &= ~DFS_S_IFREG; - st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH; - } - - st->st_size = dirent->size; - st->st_mtime = 0; - st->st_blksize = 512; - - return DFS_STATUS_OK; -} - -int dfs_romfs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count) -{ - rt_size_t index; - const char *name; - struct dirent *d; - struct romfs_dirent *dirent, *sub_dirent; - - dirent = (struct romfs_dirent *)file->data; - RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR); - - /* enter directory */ - dirent = (struct romfs_dirent *)dirent->data; - - /* make integer count */ - count = (count / sizeof(struct dirent)); - if (count == 0) - return -DFS_STATUS_EINVAL; - - index = 0; - for (index = 0; index < count && file->pos < file->size; index ++) - { - d = dirp + index; - - sub_dirent = &dirent[file->pos]; - name = sub_dirent->name; - - /* fill dirent */ - if (sub_dirent->type == ROMFS_DIRENT_DIR) - d->d_type = DFS_DT_DIR; - else - d->d_type = DFS_DT_REG; - - d->d_namlen = rt_strlen(name); - d->d_reclen = (rt_uint16_t)sizeof(struct dirent); - rt_strncpy(d->d_name, name, rt_strlen(name) + 1); - - /* move to next position */ - ++ file->pos; - } - - return index * sizeof(struct dirent); -} - -static const struct dfs_filesystem_operation _romfs = -{ - "rom", - dfs_romfs_mount, - dfs_romfs_unmount, - RT_NULL, - RT_NULL, - - dfs_romfs_open, - dfs_romfs_close, - dfs_romfs_ioctl, - dfs_romfs_read, - RT_NULL, - RT_NULL, - dfs_romfs_lseek, - dfs_romfs_getdents, - RT_NULL, - dfs_romfs_stat, - RT_NULL, -}; - -int dfs_romfs_init(void) -{ - /* register rom file system */ - dfs_register(&_romfs); - return 0; -} - +/* + * File : dfs_romfs.c + * This file is part of Device File System in RT-Thread RTOS + * COPYRIGHT (C) 2004-2011, 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. + * + * Change Logs: + * Date Author Notes + */ + +#include +#include +#include +#include "dfs_romfs.h" + +int dfs_romfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) +{ + struct romfs_dirent *root_dirent; + + if (data == RT_NULL) + return -DFS_STATUS_EIO; + + root_dirent = (struct romfs_dirent *)data; + fs->data = root_dirent; + + return DFS_STATUS_OK; +} + +int dfs_romfs_unmount(struct dfs_filesystem *fs) +{ + return DFS_STATUS_OK; +} + +int dfs_romfs_ioctl(struct dfs_fd *file, int cmd, void *args) +{ + return -DFS_STATUS_EIO; +} + +struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size) +{ + rt_size_t index, found; + const char *subpath, *subpath_end; + struct romfs_dirent *dirent; + rt_size_t dirent_size; + + if (path[0] == '/' && path[1] == '\0') + { + *size = root_dirent->size; + return root_dirent; + } + + /* goto root directy entries */ + dirent = (struct romfs_dirent *)root_dirent->data; + dirent_size = root_dirent->size; + + /* get the end position of this subpath */ + subpath_end = path; + /* skip /// */ + while (*subpath_end && *subpath_end == '/') + subpath_end ++; + subpath = subpath_end; + while ((*subpath_end != '/') && *subpath_end) + subpath_end ++; + + while (dirent != RT_NULL) + { + found = 0; + + /* search in folder */ + for (index = 0; index < dirent_size; index ++) + { + if (rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0) + { + dirent_size = dirent[index].size; + + /* skip /// */ + while (*subpath_end && *subpath_end == '/') + subpath_end ++; + subpath = subpath_end; + while ((*subpath_end != '/') && *subpath_end) + subpath_end ++; + + if (!(*subpath)) + { + *size = dirent_size; + return &dirent[index]; + } + + if (dirent[index].type == ROMFS_DIRENT_DIR) + { + /* enter directory */ + dirent = (struct romfs_dirent*)dirent[index].data; + found = 1; + break; + } + else + { + /* return file dirent */ + if (subpath != RT_NULL) + break; /* not the end of path */ + + return &dirent[index]; + } + } + } + + if (!found) + break; /* not found */ + } + + /* not found */ + return RT_NULL; +} + +int dfs_romfs_read(struct dfs_fd *file, void *buf, rt_size_t count) +{ + rt_size_t length; + struct romfs_dirent *dirent; + + dirent = (struct romfs_dirent *)file->data; + RT_ASSERT(dirent != RT_NULL); + + if (count < file->size - file->pos) + length = count; + else + length = file->size - file->pos; + + if (length > 0) + memcpy(buf, &(dirent->data[file->pos]), length); + + /* update file current position */ + file->pos += length; + + return length; +} + +int dfs_romfs_lseek(struct dfs_fd *file, rt_off_t offset) +{ + if (offset <= file->size) + { + file->pos = offset; + return file->pos; + } + + return -DFS_STATUS_EIO; +} + +int dfs_romfs_close(struct dfs_fd *file) +{ + file->data = RT_NULL; + return DFS_STATUS_OK; +} + +int dfs_romfs_open(struct dfs_fd *file) +{ + rt_size_t size; + struct romfs_dirent *dirent; + struct romfs_dirent *root_dirent; + + root_dirent = (struct romfs_dirent *)file->fs->data; + + if (file->flags & (DFS_O_CREAT | DFS_O_WRONLY | DFS_O_APPEND | DFS_O_TRUNC | DFS_O_RDWR)) + return -DFS_STATUS_EINVAL; + + dirent = dfs_romfs_lookup(root_dirent, file->path, &size); + if (dirent == RT_NULL) + return -DFS_STATUS_ENOENT; + + /* entry is a directory file type */ + if (dirent->type == ROMFS_DIRENT_DIR) + { + if (!(file->flags & DFS_O_DIRECTORY)) + return -DFS_STATUS_ENOENT; + } + else + { + /* entry is a file, but open it as a directory */ + if (file->flags & DFS_O_DIRECTORY) + return -DFS_STATUS_ENOENT; + } + + file->data = dirent; + file->size = size; + file->pos = 0; + + return DFS_STATUS_OK; +} + +int dfs_romfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) +{ + rt_size_t size; + struct romfs_dirent *dirent; + struct romfs_dirent *root_dirent; + + root_dirent = (struct romfs_dirent *)fs->data; + dirent = dfs_romfs_lookup(root_dirent, path, &size); + + if (dirent == RT_NULL) + return -DFS_STATUS_ENOENT; + + st->st_dev = 0; + st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH | + DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH; + + if (dirent->type == ROMFS_DIRENT_DIR) + { + st->st_mode &= ~DFS_S_IFREG; + st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH; + } + + st->st_size = dirent->size; + st->st_mtime = 0; + st->st_blksize = 512; + + return DFS_STATUS_OK; +} + +int dfs_romfs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count) +{ + rt_size_t index; + const char *name; + struct dirent *d; + struct romfs_dirent *dirent, *sub_dirent; + + dirent = (struct romfs_dirent *)file->data; + RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR); + + /* enter directory */ + dirent = (struct romfs_dirent *)dirent->data; + + /* make integer count */ + count = (count / sizeof(struct dirent)); + if (count == 0) + return -DFS_STATUS_EINVAL; + + index = 0; + for (index = 0; index < count && file->pos < file->size; index ++) + { + d = dirp + index; + + sub_dirent = &dirent[file->pos]; + name = sub_dirent->name; + + /* fill dirent */ + if (sub_dirent->type == ROMFS_DIRENT_DIR) + d->d_type = DFS_DT_DIR; + else + d->d_type = DFS_DT_REG; + + d->d_namlen = rt_strlen(name); + d->d_reclen = (rt_uint16_t)sizeof(struct dirent); + rt_strncpy(d->d_name, name, rt_strlen(name) + 1); + + /* move to next position */ + ++ file->pos; + } + + return index * sizeof(struct dirent); +} + +static const struct dfs_filesystem_operation _romfs = +{ + "rom", + DFS_FS_FLAG_DEFAULT, + dfs_romfs_mount, + dfs_romfs_unmount, + RT_NULL, + RT_NULL, + + dfs_romfs_open, + dfs_romfs_close, + dfs_romfs_ioctl, + dfs_romfs_read, + RT_NULL, + RT_NULL, + dfs_romfs_lseek, + dfs_romfs_getdents, + RT_NULL, + dfs_romfs_stat, + RT_NULL, +}; + +int dfs_romfs_init(void) +{ + /* register rom file system */ + dfs_register(&_romfs); + return 0; +} + diff --git a/components/dfs/filesystems/skeleton/skeleton.c b/components/dfs/filesystems/skeleton/skeleton.c index 2d11b0b1e1..ed2791ad4a 100644 --- a/components/dfs/filesystems/skeleton/skeleton.c +++ b/components/dfs/filesystems/skeleton/skeleton.c @@ -55,6 +55,7 @@ int dfs_skt_getdents(struct dfs_fd* file, struct dirent* dirp, rt_uint32_t count static const struct dfs_filesystem_operation _skt_fs = { "skt", + DFS_FS_FLAG_DEFAULT, dfs_skt_mount, dfs_skt_unmount, RT_NULL, diff --git a/components/dfs/filesystems/uffs/dfs_uffs.c b/components/dfs/filesystems/uffs/dfs_uffs.c index 4c2a084a78..1b35590c06 100644 --- a/components/dfs/filesystems/uffs/dfs_uffs.c +++ b/components/dfs/filesystems/uffs/dfs_uffs.c @@ -1,354 +1,355 @@ -#include -#include -#include -#include "uffs/uffs_fs.h" -#include "uffs/uffs_mtb.h" -#include "uffs/uffs_fd.h" -#include "uffs_ext.h" - -/* mount and unmount file system */ -int dfs_uffs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data) -{ - return ((uffs_InitMountTable() == U_SUCC) ? 0 : -1); -} - -int dfs_uffs_unmount(struct dfs_filesystem* fs) -{ - uffs_ReleaseObjectBuf(); - return uffs_ReleaseMountTable(); -} - -int dfs_uffs_mkfs(const char* device_name) -{ - return uffs_format(NULL); -} - -int dfs_uffs_statfs(struct dfs_filesystem* fs, struct statfs *buf) -{ - int ret = U_SUCC; - uffs_MountTable *entry = (uffs_MountTable*)(fs->dev_id->user_data); - struct uffs_StorageAttrSt *attr = entry->dev->attr; - +#include +#include +#include +#include "uffs/uffs_fs.h" +#include "uffs/uffs_mtb.h" +#include "uffs/uffs_fd.h" +#include "uffs_ext.h" + +/* mount and unmount file system */ +int dfs_uffs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data) +{ + return ((uffs_InitMountTable() == U_SUCC) ? 0 : -1); +} + +int dfs_uffs_unmount(struct dfs_filesystem* fs) +{ + uffs_ReleaseObjectBuf(); + return uffs_ReleaseMountTable(); +} + +int dfs_uffs_mkfs(const char* device_name) +{ + return uffs_format(NULL); +} + +int dfs_uffs_statfs(struct dfs_filesystem* fs, struct statfs *buf) +{ + int ret = U_SUCC; + uffs_MountTable *entry = (uffs_MountTable*)(fs->dev_id->user_data); + struct uffs_StorageAttrSt *attr = entry->dev->attr; + buf->f_bsize = attr->page_data_size * attr->pages_per_block; buf->f_blocks = attr->total_blocks; - buf->f_bfree = 0; - - return ret; -} - -int dfs_uffs_open(struct dfs_fd* fd) -{ - if (fd->flags & DFS_O_DIRECTORY) - { /* directory */ - uffs_DIR* dirp; - int oflag = UO_DIR; - - if (fd->flags & DFS_O_CREAT) oflag |= UO_CREATE; - if (fd->flags & DFS_O_RDONLY) oflag |= UO_RDONLY; - if (fd->flags & DFS_O_WRONLY) oflag |= UO_WRONLY; - - if (oflag & UO_CREATE) - { /* create directory right now */ - uffs_Object* fp = uffs_GetObject(); - if(fp == NULL) - { - uffs_set_error(-UEMFILE); - return U_FAIL; - } - - if(uffs_OpenObject(fp, fd->path, oflag) != U_SUCC) - { - return U_FAIL; - } - /* release object hander */ - uffs_PutObject(fp); - } - - /* use directory handler */ - dirp = uffs_opendir(fd->path); - if(dirp == NULL) - { - uffs_set_error(-UEMFILE); - return U_FAIL; - } - fd->data = dirp; - - return U_SUCC; - } - else - {/* file */ - uffs_Object *fp; - - int mode = UO_RDONLY; - - if (fd->flags & DFS_O_WRONLY) mode |= UO_WRONLY; - if ((fd->flags & DFS_O_ACCMODE) & DFS_O_RDWR) mode |= UO_WRONLY; - /* Opens the file, if it is existing. If not, a new file is created. */ - if (fd->flags & DFS_O_CREAT) mode |= UO_CREATE; - /* Creates a new file. If the file is existing, it is truncated and overwritten. */ - if (fd->flags & DFS_O_TRUNC) mode |= UO_TRUNC; - /* Creates a new file. The function fails if the file is already existing. */ - if (fd->flags & DFS_O_EXCL) mode |= UO_EXCL; - - /* get an object hander */ - fp = uffs_GetObject(); - if(fp == NULL) - { - uffs_set_error(-UEMFILE); - return U_FAIL; - } - - if(uffs_OpenObject(fp, fd->path, mode) == U_SUCC) - { - struct uffs_stat stat_buf; - - uffs_stat(fd->path, &stat_buf); - - fd->pos = fp->pos; - fd->size = stat_buf.st_size; - fd->data = fp; - - if(fd->flags & DFS_O_APPEND) - { - fd->pos = uffs_SeekObject(fp, 0, USEEK_END); - } - return U_SUCC; - } - else - { - /* open failed, return */ - uffs_set_error(-uffs_GetObjectErr(fp)); - /* release object hander */ - uffs_PutObject(fp); - return U_FAIL; - } - } -} - - -int dfs_uffs_close(struct dfs_fd* fd) -{ - int ret=U_SUCC; - - if (fd->type == FT_DIRECTORY) - { - uffs_DIR* dirp; - dirp = (uffs_DIR*)(fd->data); - RT_ASSERT(dirp != RT_NULL); - - ret = uffs_closedir(dirp); - } - else if (fd->type == FT_REGULAR) - { - uffs_Object* fp = (uffs_Object*)(fd->data); - RT_ASSERT(fd != RT_NULL); - - ret = uffs_CloseObject(fp); - /* release object hander */ - uffs_PutObject(fp); - } - - return ret; -} - -int dfs_uffs_ioctl(struct dfs_fd* fd, int cmd, void *args) -{ - return -DFS_STATUS_ENOSYS; -} - -int dfs_uffs_read(struct dfs_fd* fd, void* buf, rt_size_t count) -{ - uffs_Object* fp; - uffs_DIR* dirp; - - if (fd->type == FT_DIRECTORY) - { - dirp = (uffs_DIR*)(fd->data); - fp = dirp->obj; - } - else - { - fp = (uffs_Object*)(fd->data); - } - - RT_ASSERT(fd != RT_NULL); - - /* update position */ - fd->pos = fp->pos; - - return uffs_ReadObject(fp, buf, count); -} - -int dfs_uffs_write(struct dfs_fd* fd, const void* buf, rt_size_t count) -{ - uffs_Object* fp; - u32 byte_write; - struct uffs_stat stat_buf; -rt_kprintf("count=%d\n",count); - if(fd->type == FT_DIRECTORY) - { - return -DFS_STATUS_EISDIR; - } - - fp = (uffs_Object*)(fd->data); - RT_ASSERT(fp != RT_NULL); - - byte_write = uffs_WriteObject(fp, buf, count); - - /* update position and file size */ - fd->pos = fp->pos; - - uffs_stat(fp->name, &stat_buf); - fd->size = stat_buf.st_size; - - return byte_write; -} - -int dfs_uffs_flush(struct dfs_fd* fd) -{ - uffs_Object* fp; - - fp = (uffs_Object*)(fd->data); - RT_ASSERT(fp != RT_NULL); - - return uffs_FlushObject(fp); -} - -int dfs_uffs_lseek(struct dfs_fd* fd, rt_off_t offset) -{ - uffs_Object* fp; - - fp = (uffs_Object*)(fd->data); - RT_ASSERT(fp != RT_NULL); - - return uffs_SeekObject(fp, offset, USEEK_SET); -} - -int dfs_uffs_getdents(struct dfs_fd* fd, struct dirent* dir, rt_uint32_t count) -{ - uffs_DIR* dirp; - struct uffs_dirent *ent; - rt_uint32_t index; - struct dirent* d; - - if(fd->type != FT_DIRECTORY) - { - return -DFS_STATUS_EISDIR; - } - - dirp = (uffs_DIR*)(fd->data); - RT_ASSERT(dirp != RT_NULL); - - /* make integer count */ - count = (count / sizeof(struct dirent)) * sizeof(struct dirent); - if ( count == 0 ) return -DFS_STATUS_EINVAL; - - index = 0; - while (1) - { - d = dir + index; - - ent = uffs_readdir(dirp); - if(ent == RT_NULL)break; - - - d->d_type = DFS_DT_DIR; - - d->d_namlen = ent->d_namelen; - d->d_reclen = (rt_uint16_t)sizeof(struct dirent); - rt_strncpy(d->d_name, ent->d_name, rt_strlen(ent->d_name) + 1); - - index ++; - if ( index * sizeof(struct dirent) >= count ) - break; - } - return index * sizeof(struct dirent); -} - -//Delete a File or Directory -int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* path) -{ - int ret; - int err = 0; - - ret = uffs_DeleteObject(path, &err); - uffs_set_error(-err); - - return ret; -} - -int dfs_uffs_stat(struct dfs_filesystem* fs, const char* path, struct stat* st) -{ - int ret=U_SUCC; - struct uffs_stat stat_buf; - - ret = uffs_stat(path, &stat_buf); - - if (ret == U_SUCC) - { - rt_uint32_t mode=0; - st->st_dev = 0; - - if(stat_buf.st_mode & US_IFREG) mode |= DFS_S_IFREG; - if(stat_buf.st_mode & US_IFDIR) mode |= DFS_S_IFDIR; - if(stat_buf.st_mode & US_IRWXU) mode |= DFS_S_IRWXU; - if(stat_buf.st_mode & US_IRUSR) mode |= DFS_S_IRUSR; - if(stat_buf.st_mode & US_IWUSR) mode |= DFS_S_IWUSR; - if(stat_buf.st_mode & US_IXUSR) mode |= DFS_S_IXUSR; - if(stat_buf.st_mode & US_IRWXG) mode |= DFS_S_IRWXG; - if(stat_buf.st_mode & US_IRGRP) mode |= DFS_S_IRGRP; - if(stat_buf.st_mode & US_IWGRP) mode |= DFS_S_IWGRP; - if(stat_buf.st_mode & US_IXGRP) mode |= DFS_S_IXGRP; - if(stat_buf.st_mode & US_IRWXO) mode |= DFS_S_IRWXO; - if(stat_buf.st_mode & US_IROTH) mode |= DFS_S_IROTH; - if(stat_buf.st_mode & US_IWOTH) mode |= DFS_S_IWOTH; - if(stat_buf.st_mode & US_IXOTH) mode |= DFS_S_IXOTH; - + buf->f_bfree = 0; + + return ret; +} + +int dfs_uffs_open(struct dfs_fd* fd) +{ + if (fd->flags & DFS_O_DIRECTORY) + { /* directory */ + uffs_DIR* dirp; + int oflag = UO_DIR; + + if (fd->flags & DFS_O_CREAT) oflag |= UO_CREATE; + if (fd->flags & DFS_O_RDONLY) oflag |= UO_RDONLY; + if (fd->flags & DFS_O_WRONLY) oflag |= UO_WRONLY; + + if (oflag & UO_CREATE) + { /* create directory right now */ + uffs_Object* fp = uffs_GetObject(); + if(fp == NULL) + { + uffs_set_error(-UEMFILE); + return U_FAIL; + } + + if(uffs_OpenObject(fp, fd->path, oflag) != U_SUCC) + { + return U_FAIL; + } + /* release object hander */ + uffs_PutObject(fp); + } + + /* use directory handler */ + dirp = uffs_opendir(fd->path); + if(dirp == NULL) + { + uffs_set_error(-UEMFILE); + return U_FAIL; + } + fd->data = dirp; + + return U_SUCC; + } + else + {/* file */ + uffs_Object *fp; + + int mode = UO_RDONLY; + + if (fd->flags & DFS_O_WRONLY) mode |= UO_WRONLY; + if ((fd->flags & DFS_O_ACCMODE) & DFS_O_RDWR) mode |= UO_WRONLY; + /* Opens the file, if it is existing. If not, a new file is created. */ + if (fd->flags & DFS_O_CREAT) mode |= UO_CREATE; + /* Creates a new file. If the file is existing, it is truncated and overwritten. */ + if (fd->flags & DFS_O_TRUNC) mode |= UO_TRUNC; + /* Creates a new file. The function fails if the file is already existing. */ + if (fd->flags & DFS_O_EXCL) mode |= UO_EXCL; + + /* get an object hander */ + fp = uffs_GetObject(); + if(fp == NULL) + { + uffs_set_error(-UEMFILE); + return U_FAIL; + } + + if(uffs_OpenObject(fp, fd->path, mode) == U_SUCC) + { + struct uffs_stat stat_buf; + + uffs_stat(fd->path, &stat_buf); + + fd->pos = fp->pos; + fd->size = stat_buf.st_size; + fd->data = fp; + + if(fd->flags & DFS_O_APPEND) + { + fd->pos = uffs_SeekObject(fp, 0, USEEK_END); + } + return U_SUCC; + } + else + { + /* open failed, return */ + uffs_set_error(-uffs_GetObjectErr(fp)); + /* release object hander */ + uffs_PutObject(fp); + return U_FAIL; + } + } +} + + +int dfs_uffs_close(struct dfs_fd* fd) +{ + int ret=U_SUCC; + + if (fd->type == FT_DIRECTORY) + { + uffs_DIR* dirp; + dirp = (uffs_DIR*)(fd->data); + RT_ASSERT(dirp != RT_NULL); + + ret = uffs_closedir(dirp); + } + else if (fd->type == FT_REGULAR) + { + uffs_Object* fp = (uffs_Object*)(fd->data); + RT_ASSERT(fd != RT_NULL); + + ret = uffs_CloseObject(fp); + /* release object hander */ + uffs_PutObject(fp); + } + + return ret; +} + +int dfs_uffs_ioctl(struct dfs_fd* fd, int cmd, void *args) +{ + return -DFS_STATUS_ENOSYS; +} + +int dfs_uffs_read(struct dfs_fd* fd, void* buf, rt_size_t count) +{ + uffs_Object* fp; + uffs_DIR* dirp; + + if (fd->type == FT_DIRECTORY) + { + dirp = (uffs_DIR*)(fd->data); + fp = dirp->obj; + } + else + { + fp = (uffs_Object*)(fd->data); + } + + RT_ASSERT(fd != RT_NULL); + + /* update position */ + fd->pos = fp->pos; + + return uffs_ReadObject(fp, buf, count); +} + +int dfs_uffs_write(struct dfs_fd* fd, const void* buf, rt_size_t count) +{ + uffs_Object* fp; + u32 byte_write; + struct uffs_stat stat_buf; +rt_kprintf("count=%d\n",count); + if(fd->type == FT_DIRECTORY) + { + return -DFS_STATUS_EISDIR; + } + + fp = (uffs_Object*)(fd->data); + RT_ASSERT(fp != RT_NULL); + + byte_write = uffs_WriteObject(fp, buf, count); + + /* update position and file size */ + fd->pos = fp->pos; + + uffs_stat(fp->name, &stat_buf); + fd->size = stat_buf.st_size; + + return byte_write; +} + +int dfs_uffs_flush(struct dfs_fd* fd) +{ + uffs_Object* fp; + + fp = (uffs_Object*)(fd->data); + RT_ASSERT(fp != RT_NULL); + + return uffs_FlushObject(fp); +} + +int dfs_uffs_lseek(struct dfs_fd* fd, rt_off_t offset) +{ + uffs_Object* fp; + + fp = (uffs_Object*)(fd->data); + RT_ASSERT(fp != RT_NULL); + + return uffs_SeekObject(fp, offset, USEEK_SET); +} + +int dfs_uffs_getdents(struct dfs_fd* fd, struct dirent* dir, rt_uint32_t count) +{ + uffs_DIR* dirp; + struct uffs_dirent *ent; + rt_uint32_t index; + struct dirent* d; + + if(fd->type != FT_DIRECTORY) + { + return -DFS_STATUS_EISDIR; + } + + dirp = (uffs_DIR*)(fd->data); + RT_ASSERT(dirp != RT_NULL); + + /* make integer count */ + count = (count / sizeof(struct dirent)) * sizeof(struct dirent); + if ( count == 0 ) return -DFS_STATUS_EINVAL; + + index = 0; + while (1) + { + d = dir + index; + + ent = uffs_readdir(dirp); + if(ent == RT_NULL)break; + + + d->d_type = DFS_DT_DIR; + + d->d_namlen = ent->d_namelen; + d->d_reclen = (rt_uint16_t)sizeof(struct dirent); + rt_strncpy(d->d_name, ent->d_name, rt_strlen(ent->d_name) + 1); + + index ++; + if ( index * sizeof(struct dirent) >= count ) + break; + } + return index * sizeof(struct dirent); +} + +//Delete a File or Directory +int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* path) +{ + int ret; + int err = 0; + + ret = uffs_DeleteObject(path, &err); + uffs_set_error(-err); + + return ret; +} + +int dfs_uffs_stat(struct dfs_filesystem* fs, const char* path, struct stat* st) +{ + int ret=U_SUCC; + struct uffs_stat stat_buf; + + ret = uffs_stat(path, &stat_buf); + + if (ret == U_SUCC) + { + rt_uint32_t mode=0; + st->st_dev = 0; + + if(stat_buf.st_mode & US_IFREG) mode |= DFS_S_IFREG; + if(stat_buf.st_mode & US_IFDIR) mode |= DFS_S_IFDIR; + if(stat_buf.st_mode & US_IRWXU) mode |= DFS_S_IRWXU; + if(stat_buf.st_mode & US_IRUSR) mode |= DFS_S_IRUSR; + if(stat_buf.st_mode & US_IWUSR) mode |= DFS_S_IWUSR; + if(stat_buf.st_mode & US_IXUSR) mode |= DFS_S_IXUSR; + if(stat_buf.st_mode & US_IRWXG) mode |= DFS_S_IRWXG; + if(stat_buf.st_mode & US_IRGRP) mode |= DFS_S_IRGRP; + if(stat_buf.st_mode & US_IWGRP) mode |= DFS_S_IWGRP; + if(stat_buf.st_mode & US_IXGRP) mode |= DFS_S_IXGRP; + if(stat_buf.st_mode & US_IRWXO) mode |= DFS_S_IRWXO; + if(stat_buf.st_mode & US_IROTH) mode |= DFS_S_IROTH; + if(stat_buf.st_mode & US_IWOTH) mode |= DFS_S_IWOTH; + if(stat_buf.st_mode & US_IXOTH) mode |= DFS_S_IXOTH; + st->st_mode = mode; st->st_size = stat_buf.st_size; st->st_mtime= stat_buf.st_mtime; - st->st_blksize= stat_buf.st_blksize; - - return U_SUCC; - } - - return U_FAIL; -} - -int dfs_uffs_rename(struct dfs_filesystem* fs, const char* oldpath, const char* newpath) -{ - int ret; - int err = 0; - - ret = uffs_RenameObject(oldpath, newpath, &err); - uffs_set_error(-err); - - return ret; -} - -struct dfs_filesystem_operation _uffs = -{ - "uffs", - dfs_uffs_mount, - dfs_uffs_unmount, - dfs_uffs_mkfs, - dfs_uffs_statfs, - dfs_uffs_open, - dfs_uffs_close, - dfs_uffs_ioctl, - dfs_uffs_read, - dfs_uffs_write, - dfs_uffs_flush, - dfs_uffs_lseek, - dfs_uffs_getdents, - dfs_uffs_unlink, - dfs_uffs_stat, - dfs_uffs_rename, -}; - -int dfs_uffs_init(void) -{ - /* register UFFS file system */ - return dfs_register(&_uffs); -} - + st->st_blksize= stat_buf.st_blksize; + + return U_SUCC; + } + + return U_FAIL; +} + +int dfs_uffs_rename(struct dfs_filesystem* fs, const char* oldpath, const char* newpath) +{ + int ret; + int err = 0; + + ret = uffs_RenameObject(oldpath, newpath, &err); + uffs_set_error(-err); + + return ret; +} + +struct dfs_filesystem_operation _uffs = +{ + "uffs", + DFS_FS_FLAG_DEFAULT, + dfs_uffs_mount, + dfs_uffs_unmount, + dfs_uffs_mkfs, + dfs_uffs_statfs, + dfs_uffs_open, + dfs_uffs_close, + dfs_uffs_ioctl, + dfs_uffs_read, + dfs_uffs_write, + dfs_uffs_flush, + dfs_uffs_lseek, + dfs_uffs_getdents, + dfs_uffs_unlink, + dfs_uffs_stat, + dfs_uffs_rename, +}; + +int dfs_uffs_init(void) +{ + /* register UFFS file system */ + return dfs_register(&_uffs); +} + diff --git a/components/dfs/include/dfs_fs.h b/components/dfs/include/dfs_fs.h index 2108d07c82..90a5b50d69 100644 --- a/components/dfs/include/dfs_fs.h +++ b/components/dfs/include/dfs_fs.h @@ -17,6 +17,9 @@ #include +#define DFS_FS_FLAG_DEFAULT 0x00 /* default flag */ +#define DFS_FS_FLAG_FULLPATH 0x01 /* set full path to underlaying file system */ + /* Pre-declaration */ struct dfs_filesystem; struct dfs_fd; @@ -25,6 +28,7 @@ struct dfs_fd; struct dfs_filesystem_operation { char *name; + rt_uint32_t flags; /* flags for file system operations */ /* mount and unmount file system */ int (*mount) (struct dfs_filesystem *fs, unsigned long rwflag, const void *data); diff --git a/components/dfs/src/dfs_file.c b/components/dfs/src/dfs_file.c index 25de66af11..b9f050b602 100644 --- a/components/dfs/src/dfs_file.c +++ b/components/dfs/src/dfs_file.c @@ -66,13 +66,20 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags) fd->size = 0; fd->pos = 0; - if (dfs_subdir(fs->path, fullpath) == RT_NULL) - fd->path = rt_strdup("/"); + if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH)) + { + if (dfs_subdir(fs->path, fullpath) == RT_NULL) + fd->path = rt_strdup("/"); + else + fd->path = rt_strdup(dfs_subdir(fs->path, fullpath)); + rt_free(fullpath); + dfs_log(DFS_DEBUG_INFO, ("Actual file path: %s\n", fd->path)); + } else - fd->path = rt_strdup(dfs_subdir(fs->path, fullpath)); - rt_free(fullpath); - dfs_log(DFS_DEBUG_INFO, ("Actual file path: %s\n", fd->path)); - + { + fd->path = fullpath; + } + /* specific file system open routine */ if (fs->ops->open == RT_NULL) { @@ -241,10 +248,15 @@ int dfs_file_unlink(const char *path) if (fs->ops->unlink != RT_NULL) { - if (dfs_subdir(fs->path, fullpath) == RT_NULL) - result = fs->ops->unlink(fs, "/"); + if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH)) + { + if (dfs_subdir(fs->path, fullpath) == RT_NULL) + result = fs->ops->unlink(fs, "/"); + else + result = fs->ops->unlink(fs, dfs_subdir(fs->path, fullpath)); + } else - result = fs->ops->unlink(fs, dfs_subdir(fs->path, fullpath)); + result = fs->ops->unlink(fs, fullpath); } else result = -DFS_STATUS_ENOSYS; @@ -380,7 +392,11 @@ int dfs_file_stat(const char *path, struct stat *buf) } /* get the real file path and get file stat */ - result = fs->ops->stat(fs, dfs_subdir(fs->path, fullpath), buf); + if (fs->ops->flags & DFS_FS_FLAG_FULLPATH) + result = fs->ops->stat(fs, fullpath, buf); + else + result = fs->ops->stat(fs, dfs_subdir(fs->path, fullpath), buf); + } rt_free(fullpath); -- GitLab