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
This commit is contained in:
bernard.xiong@gmail.com 2012-01-01 13:37:21 +00:00
parent 76e81a9977
commit beaf51ff82
8 changed files with 677 additions and 651 deletions

View File

@ -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 = static const struct dfs_filesystem_operation _device_fs =
{ {
"devfs", "devfs",
DFS_FS_FLAG_DEFAULT,
dfs_device_fs_mount, dfs_device_fs_mount,
RT_NULL, RT_NULL,
RT_NULL, RT_NULL,

View File

@ -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 = static const struct dfs_filesystem_operation dfs_elm =
{ {
"elm", "elm",
DFS_FS_FLAG_DEFAULT,
dfs_elm_mount, dfs_elm_mount,
dfs_elm_unmount, dfs_elm_unmount,
dfs_elm_mkfs, dfs_elm_mkfs,

View File

@ -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 = static const struct dfs_filesystem_operation _nfs =
{ {
"nfs", "nfs",
DFS_FS_FLAG_DEFAULT,
nfs_mount, nfs_mount,
nfs_unmount, nfs_unmount,
RT_NULL, /* mkfs */ RT_NULL, /* mkfs */

View File

@ -1,291 +1,292 @@
/* /*
* File : dfs_romfs.c * File : dfs_romfs.c
* This file is part of Device File System in RT-Thread RTOS * This file is part of Device File System in RT-Thread RTOS
* COPYRIGHT (C) 2004-2011, RT-Thread Development Team * COPYRIGHT (C) 2004-2011, RT-Thread Development Team
* *
* The license and distribution terms for this file may be * The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at * found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE. * http://www.rt-thread.org/license/LICENSE.
* *
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
*/ */
#include <rtthread.h> #include <rtthread.h>
#include <dfs.h> #include <dfs.h>
#include <dfs_fs.h> #include <dfs_fs.h>
#include "dfs_romfs.h" #include "dfs_romfs.h"
int dfs_romfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) int dfs_romfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
{ {
struct romfs_dirent *root_dirent; struct romfs_dirent *root_dirent;
if (data == RT_NULL) if (data == RT_NULL)
return -DFS_STATUS_EIO; return -DFS_STATUS_EIO;
root_dirent = (struct romfs_dirent *)data; root_dirent = (struct romfs_dirent *)data;
fs->data = root_dirent; fs->data = root_dirent;
return DFS_STATUS_OK; return DFS_STATUS_OK;
} }
int dfs_romfs_unmount(struct dfs_filesystem *fs) int dfs_romfs_unmount(struct dfs_filesystem *fs)
{ {
return DFS_STATUS_OK; return DFS_STATUS_OK;
} }
int dfs_romfs_ioctl(struct dfs_fd *file, int cmd, void *args) int dfs_romfs_ioctl(struct dfs_fd *file, int cmd, void *args)
{ {
return -DFS_STATUS_EIO; return -DFS_STATUS_EIO;
} }
struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size) struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size)
{ {
rt_size_t index, found; rt_size_t index, found;
const char *subpath, *subpath_end; const char *subpath, *subpath_end;
struct romfs_dirent *dirent; struct romfs_dirent *dirent;
rt_size_t dirent_size; rt_size_t dirent_size;
if (path[0] == '/' && path[1] == '\0') if (path[0] == '/' && path[1] == '\0')
{ {
*size = root_dirent->size; *size = root_dirent->size;
return root_dirent; return root_dirent;
} }
/* goto root directy entries */ /* goto root directy entries */
dirent = (struct romfs_dirent *)root_dirent->data; dirent = (struct romfs_dirent *)root_dirent->data;
dirent_size = root_dirent->size; dirent_size = root_dirent->size;
/* get the end position of this subpath */ /* get the end position of this subpath */
subpath_end = path; subpath_end = path;
/* skip /// */ /* skip /// */
while (*subpath_end && *subpath_end == '/') while (*subpath_end && *subpath_end == '/')
subpath_end ++; subpath_end ++;
subpath = subpath_end; subpath = subpath_end;
while ((*subpath_end != '/') && *subpath_end) while ((*subpath_end != '/') && *subpath_end)
subpath_end ++; subpath_end ++;
while (dirent != RT_NULL) while (dirent != RT_NULL)
{ {
found = 0; found = 0;
/* search in folder */ /* search in folder */
for (index = 0; index < dirent_size; index ++) for (index = 0; index < dirent_size; index ++)
{ {
if (rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0) if (rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
{ {
dirent_size = dirent[index].size; dirent_size = dirent[index].size;
/* skip /// */ /* skip /// */
while (*subpath_end && *subpath_end == '/') while (*subpath_end && *subpath_end == '/')
subpath_end ++; subpath_end ++;
subpath = subpath_end; subpath = subpath_end;
while ((*subpath_end != '/') && *subpath_end) while ((*subpath_end != '/') && *subpath_end)
subpath_end ++; subpath_end ++;
if (!(*subpath)) if (!(*subpath))
{ {
*size = dirent_size; *size = dirent_size;
return &dirent[index]; return &dirent[index];
} }
if (dirent[index].type == ROMFS_DIRENT_DIR) if (dirent[index].type == ROMFS_DIRENT_DIR)
{ {
/* enter directory */ /* enter directory */
dirent = (struct romfs_dirent*)dirent[index].data; dirent = (struct romfs_dirent*)dirent[index].data;
found = 1; found = 1;
break; break;
} }
else else
{ {
/* return file dirent */ /* return file dirent */
if (subpath != RT_NULL) if (subpath != RT_NULL)
break; /* not the end of path */ break; /* not the end of path */
return &dirent[index]; return &dirent[index];
} }
} }
} }
if (!found) if (!found)
break; /* not found */ break; /* not found */
} }
/* not found */ /* not found */
return RT_NULL; return RT_NULL;
} }
int dfs_romfs_read(struct dfs_fd *file, void *buf, rt_size_t count) int dfs_romfs_read(struct dfs_fd *file, void *buf, rt_size_t count)
{ {
rt_size_t length; rt_size_t length;
struct romfs_dirent *dirent; struct romfs_dirent *dirent;
dirent = (struct romfs_dirent *)file->data; dirent = (struct romfs_dirent *)file->data;
RT_ASSERT(dirent != RT_NULL); RT_ASSERT(dirent != RT_NULL);
if (count < file->size - file->pos) if (count < file->size - file->pos)
length = count; length = count;
else else
length = file->size - file->pos; length = file->size - file->pos;
if (length > 0) if (length > 0)
memcpy(buf, &(dirent->data[file->pos]), length); memcpy(buf, &(dirent->data[file->pos]), length);
/* update file current position */ /* update file current position */
file->pos += length; file->pos += length;
return length; return length;
} }
int dfs_romfs_lseek(struct dfs_fd *file, rt_off_t offset) int dfs_romfs_lseek(struct dfs_fd *file, rt_off_t offset)
{ {
if (offset <= file->size) if (offset <= file->size)
{ {
file->pos = offset; file->pos = offset;
return file->pos; return file->pos;
} }
return -DFS_STATUS_EIO; return -DFS_STATUS_EIO;
} }
int dfs_romfs_close(struct dfs_fd *file) int dfs_romfs_close(struct dfs_fd *file)
{ {
file->data = RT_NULL; file->data = RT_NULL;
return DFS_STATUS_OK; return DFS_STATUS_OK;
} }
int dfs_romfs_open(struct dfs_fd *file) int dfs_romfs_open(struct dfs_fd *file)
{ {
rt_size_t size; rt_size_t size;
struct romfs_dirent *dirent; struct romfs_dirent *dirent;
struct romfs_dirent *root_dirent; struct romfs_dirent *root_dirent;
root_dirent = (struct romfs_dirent *)file->fs->data; 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)) if (file->flags & (DFS_O_CREAT | DFS_O_WRONLY | DFS_O_APPEND | DFS_O_TRUNC | DFS_O_RDWR))
return -DFS_STATUS_EINVAL; return -DFS_STATUS_EINVAL;
dirent = dfs_romfs_lookup(root_dirent, file->path, &size); dirent = dfs_romfs_lookup(root_dirent, file->path, &size);
if (dirent == RT_NULL) if (dirent == RT_NULL)
return -DFS_STATUS_ENOENT; return -DFS_STATUS_ENOENT;
/* entry is a directory file type */ /* entry is a directory file type */
if (dirent->type == ROMFS_DIRENT_DIR) if (dirent->type == ROMFS_DIRENT_DIR)
{ {
if (!(file->flags & DFS_O_DIRECTORY)) if (!(file->flags & DFS_O_DIRECTORY))
return -DFS_STATUS_ENOENT; return -DFS_STATUS_ENOENT;
} }
else else
{ {
/* entry is a file, but open it as a directory */ /* entry is a file, but open it as a directory */
if (file->flags & DFS_O_DIRECTORY) if (file->flags & DFS_O_DIRECTORY)
return -DFS_STATUS_ENOENT; return -DFS_STATUS_ENOENT;
} }
file->data = dirent; file->data = dirent;
file->size = size; file->size = size;
file->pos = 0; file->pos = 0;
return DFS_STATUS_OK; return DFS_STATUS_OK;
} }
int dfs_romfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) int dfs_romfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
{ {
rt_size_t size; rt_size_t size;
struct romfs_dirent *dirent; struct romfs_dirent *dirent;
struct romfs_dirent *root_dirent; struct romfs_dirent *root_dirent;
root_dirent = (struct romfs_dirent *)fs->data; root_dirent = (struct romfs_dirent *)fs->data;
dirent = dfs_romfs_lookup(root_dirent, path, &size); dirent = dfs_romfs_lookup(root_dirent, path, &size);
if (dirent == RT_NULL) if (dirent == RT_NULL)
return -DFS_STATUS_ENOENT; return -DFS_STATUS_ENOENT;
st->st_dev = 0; st->st_dev = 0;
st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH | st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH; DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
if (dirent->type == ROMFS_DIRENT_DIR) if (dirent->type == ROMFS_DIRENT_DIR)
{ {
st->st_mode &= ~DFS_S_IFREG; st->st_mode &= ~DFS_S_IFREG;
st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH; st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
} }
st->st_size = dirent->size; st->st_size = dirent->size;
st->st_mtime = 0; st->st_mtime = 0;
st->st_blksize = 512; st->st_blksize = 512;
return DFS_STATUS_OK; return DFS_STATUS_OK;
} }
int dfs_romfs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count) int dfs_romfs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count)
{ {
rt_size_t index; rt_size_t index;
const char *name; const char *name;
struct dirent *d; struct dirent *d;
struct romfs_dirent *dirent, *sub_dirent; struct romfs_dirent *dirent, *sub_dirent;
dirent = (struct romfs_dirent *)file->data; dirent = (struct romfs_dirent *)file->data;
RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR); RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR);
/* enter directory */ /* enter directory */
dirent = (struct romfs_dirent *)dirent->data; dirent = (struct romfs_dirent *)dirent->data;
/* make integer count */ /* make integer count */
count = (count / sizeof(struct dirent)); count = (count / sizeof(struct dirent));
if (count == 0) if (count == 0)
return -DFS_STATUS_EINVAL; return -DFS_STATUS_EINVAL;
index = 0; index = 0;
for (index = 0; index < count && file->pos < file->size; index ++) for (index = 0; index < count && file->pos < file->size; index ++)
{ {
d = dirp + index; d = dirp + index;
sub_dirent = &dirent[file->pos]; sub_dirent = &dirent[file->pos];
name = sub_dirent->name; name = sub_dirent->name;
/* fill dirent */ /* fill dirent */
if (sub_dirent->type == ROMFS_DIRENT_DIR) if (sub_dirent->type == ROMFS_DIRENT_DIR)
d->d_type = DFS_DT_DIR; d->d_type = DFS_DT_DIR;
else else
d->d_type = DFS_DT_REG; d->d_type = DFS_DT_REG;
d->d_namlen = rt_strlen(name); d->d_namlen = rt_strlen(name);
d->d_reclen = (rt_uint16_t)sizeof(struct dirent); d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
rt_strncpy(d->d_name, name, rt_strlen(name) + 1); rt_strncpy(d->d_name, name, rt_strlen(name) + 1);
/* move to next position */ /* move to next position */
++ file->pos; ++ file->pos;
} }
return index * sizeof(struct dirent); return index * sizeof(struct dirent);
} }
static const struct dfs_filesystem_operation _romfs = static const struct dfs_filesystem_operation _romfs =
{ {
"rom", "rom",
dfs_romfs_mount, DFS_FS_FLAG_DEFAULT,
dfs_romfs_unmount, dfs_romfs_mount,
RT_NULL, dfs_romfs_unmount,
RT_NULL, RT_NULL,
RT_NULL,
dfs_romfs_open,
dfs_romfs_close, dfs_romfs_open,
dfs_romfs_ioctl, dfs_romfs_close,
dfs_romfs_read, dfs_romfs_ioctl,
RT_NULL, dfs_romfs_read,
RT_NULL, RT_NULL,
dfs_romfs_lseek, RT_NULL,
dfs_romfs_getdents, dfs_romfs_lseek,
RT_NULL, dfs_romfs_getdents,
dfs_romfs_stat, RT_NULL,
RT_NULL, dfs_romfs_stat,
}; RT_NULL,
};
int dfs_romfs_init(void)
{ int dfs_romfs_init(void)
/* register rom file system */ {
dfs_register(&_romfs); /* register rom file system */
return 0; dfs_register(&_romfs);
} return 0;
}

View File

@ -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 = static const struct dfs_filesystem_operation _skt_fs =
{ {
"skt", "skt",
DFS_FS_FLAG_DEFAULT,
dfs_skt_mount, dfs_skt_mount,
dfs_skt_unmount, dfs_skt_unmount,
RT_NULL, RT_NULL,

View File

@ -1,354 +1,355 @@
#include <rtthread.h> #include <rtthread.h>
#include <dfs_def.h> #include <dfs_def.h>
#include <dfs_fs.h> #include <dfs_fs.h>
#include "uffs/uffs_fs.h" #include "uffs/uffs_fs.h"
#include "uffs/uffs_mtb.h" #include "uffs/uffs_mtb.h"
#include "uffs/uffs_fd.h" #include "uffs/uffs_fd.h"
#include "uffs_ext.h" #include "uffs_ext.h"
/* mount and unmount file system */ /* mount and unmount file system */
int dfs_uffs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data) int dfs_uffs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
{ {
return ((uffs_InitMountTable() == U_SUCC) ? 0 : -1); return ((uffs_InitMountTable() == U_SUCC) ? 0 : -1);
} }
int dfs_uffs_unmount(struct dfs_filesystem* fs) int dfs_uffs_unmount(struct dfs_filesystem* fs)
{ {
uffs_ReleaseObjectBuf(); uffs_ReleaseObjectBuf();
return uffs_ReleaseMountTable(); return uffs_ReleaseMountTable();
} }
int dfs_uffs_mkfs(const char* device_name) int dfs_uffs_mkfs(const char* device_name)
{ {
return uffs_format(NULL); return uffs_format(NULL);
} }
int dfs_uffs_statfs(struct dfs_filesystem* fs, struct statfs *buf) int dfs_uffs_statfs(struct dfs_filesystem* fs, struct statfs *buf)
{ {
int ret = U_SUCC; int ret = U_SUCC;
uffs_MountTable *entry = (uffs_MountTable*)(fs->dev_id->user_data); uffs_MountTable *entry = (uffs_MountTable*)(fs->dev_id->user_data);
struct uffs_StorageAttrSt *attr = entry->dev->attr; struct uffs_StorageAttrSt *attr = entry->dev->attr;
buf->f_bsize = attr->page_data_size * attr->pages_per_block; buf->f_bsize = attr->page_data_size * attr->pages_per_block;
buf->f_blocks = attr->total_blocks; buf->f_blocks = attr->total_blocks;
buf->f_bfree = 0; buf->f_bfree = 0;
return ret; return ret;
} }
int dfs_uffs_open(struct dfs_fd* fd) int dfs_uffs_open(struct dfs_fd* fd)
{ {
if (fd->flags & DFS_O_DIRECTORY) if (fd->flags & DFS_O_DIRECTORY)
{ /* directory */ { /* directory */
uffs_DIR* dirp; uffs_DIR* dirp;
int oflag = UO_DIR; int oflag = UO_DIR;
if (fd->flags & DFS_O_CREAT) oflag |= UO_CREATE; if (fd->flags & DFS_O_CREAT) oflag |= UO_CREATE;
if (fd->flags & DFS_O_RDONLY) oflag |= UO_RDONLY; if (fd->flags & DFS_O_RDONLY) oflag |= UO_RDONLY;
if (fd->flags & DFS_O_WRONLY) oflag |= UO_WRONLY; if (fd->flags & DFS_O_WRONLY) oflag |= UO_WRONLY;
if (oflag & UO_CREATE) if (oflag & UO_CREATE)
{ /* create directory right now */ { /* create directory right now */
uffs_Object* fp = uffs_GetObject(); uffs_Object* fp = uffs_GetObject();
if(fp == NULL) if(fp == NULL)
{ {
uffs_set_error(-UEMFILE); uffs_set_error(-UEMFILE);
return U_FAIL; return U_FAIL;
} }
if(uffs_OpenObject(fp, fd->path, oflag) != U_SUCC) if(uffs_OpenObject(fp, fd->path, oflag) != U_SUCC)
{ {
return U_FAIL; return U_FAIL;
} }
/* release object hander */ /* release object hander */
uffs_PutObject(fp); uffs_PutObject(fp);
} }
/* use directory handler */ /* use directory handler */
dirp = uffs_opendir(fd->path); dirp = uffs_opendir(fd->path);
if(dirp == NULL) if(dirp == NULL)
{ {
uffs_set_error(-UEMFILE); uffs_set_error(-UEMFILE);
return U_FAIL; return U_FAIL;
} }
fd->data = dirp; fd->data = dirp;
return U_SUCC; return U_SUCC;
} }
else else
{/* file */ {/* file */
uffs_Object *fp; uffs_Object *fp;
int mode = UO_RDONLY; int mode = UO_RDONLY;
if (fd->flags & DFS_O_WRONLY) mode |= UO_WRONLY; if (fd->flags & DFS_O_WRONLY) mode |= UO_WRONLY;
if ((fd->flags & DFS_O_ACCMODE) & DFS_O_RDWR) 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. */ /* Opens the file, if it is existing. If not, a new file is created. */
if (fd->flags & DFS_O_CREAT) mode |= UO_CREATE; if (fd->flags & DFS_O_CREAT) mode |= UO_CREATE;
/* Creates a new file. If the file is existing, it is truncated and overwritten. */ /* Creates a new file. If the file is existing, it is truncated and overwritten. */
if (fd->flags & DFS_O_TRUNC) mode |= UO_TRUNC; if (fd->flags & DFS_O_TRUNC) mode |= UO_TRUNC;
/* Creates a new file. The function fails if the file is already existing. */ /* Creates a new file. The function fails if the file is already existing. */
if (fd->flags & DFS_O_EXCL) mode |= UO_EXCL; if (fd->flags & DFS_O_EXCL) mode |= UO_EXCL;
/* get an object hander */ /* get an object hander */
fp = uffs_GetObject(); fp = uffs_GetObject();
if(fp == NULL) if(fp == NULL)
{ {
uffs_set_error(-UEMFILE); uffs_set_error(-UEMFILE);
return U_FAIL; return U_FAIL;
} }
if(uffs_OpenObject(fp, fd->path, mode) == U_SUCC) if(uffs_OpenObject(fp, fd->path, mode) == U_SUCC)
{ {
struct uffs_stat stat_buf; struct uffs_stat stat_buf;
uffs_stat(fd->path, &stat_buf); uffs_stat(fd->path, &stat_buf);
fd->pos = fp->pos; fd->pos = fp->pos;
fd->size = stat_buf.st_size; fd->size = stat_buf.st_size;
fd->data = fp; fd->data = fp;
if(fd->flags & DFS_O_APPEND) if(fd->flags & DFS_O_APPEND)
{ {
fd->pos = uffs_SeekObject(fp, 0, USEEK_END); fd->pos = uffs_SeekObject(fp, 0, USEEK_END);
} }
return U_SUCC; return U_SUCC;
} }
else else
{ {
/* open failed, return */ /* open failed, return */
uffs_set_error(-uffs_GetObjectErr(fp)); uffs_set_error(-uffs_GetObjectErr(fp));
/* release object hander */ /* release object hander */
uffs_PutObject(fp); uffs_PutObject(fp);
return U_FAIL; return U_FAIL;
} }
} }
} }
int dfs_uffs_close(struct dfs_fd* fd) int dfs_uffs_close(struct dfs_fd* fd)
{ {
int ret=U_SUCC; int ret=U_SUCC;
if (fd->type == FT_DIRECTORY) if (fd->type == FT_DIRECTORY)
{ {
uffs_DIR* dirp; uffs_DIR* dirp;
dirp = (uffs_DIR*)(fd->data); dirp = (uffs_DIR*)(fd->data);
RT_ASSERT(dirp != RT_NULL); RT_ASSERT(dirp != RT_NULL);
ret = uffs_closedir(dirp); ret = uffs_closedir(dirp);
} }
else if (fd->type == FT_REGULAR) else if (fd->type == FT_REGULAR)
{ {
uffs_Object* fp = (uffs_Object*)(fd->data); uffs_Object* fp = (uffs_Object*)(fd->data);
RT_ASSERT(fd != RT_NULL); RT_ASSERT(fd != RT_NULL);
ret = uffs_CloseObject(fp); ret = uffs_CloseObject(fp);
/* release object hander */ /* release object hander */
uffs_PutObject(fp); uffs_PutObject(fp);
} }
return ret; return ret;
} }
int dfs_uffs_ioctl(struct dfs_fd* fd, int cmd, void *args) int dfs_uffs_ioctl(struct dfs_fd* fd, int cmd, void *args)
{ {
return -DFS_STATUS_ENOSYS; return -DFS_STATUS_ENOSYS;
} }
int dfs_uffs_read(struct dfs_fd* fd, void* buf, rt_size_t count) int dfs_uffs_read(struct dfs_fd* fd, void* buf, rt_size_t count)
{ {
uffs_Object* fp; uffs_Object* fp;
uffs_DIR* dirp; uffs_DIR* dirp;
if (fd->type == FT_DIRECTORY) if (fd->type == FT_DIRECTORY)
{ {
dirp = (uffs_DIR*)(fd->data); dirp = (uffs_DIR*)(fd->data);
fp = dirp->obj; fp = dirp->obj;
} }
else else
{ {
fp = (uffs_Object*)(fd->data); fp = (uffs_Object*)(fd->data);
} }
RT_ASSERT(fd != RT_NULL); RT_ASSERT(fd != RT_NULL);
/* update position */ /* update position */
fd->pos = fp->pos; fd->pos = fp->pos;
return uffs_ReadObject(fp, buf, count); return uffs_ReadObject(fp, buf, count);
} }
int dfs_uffs_write(struct dfs_fd* fd, const void* buf, rt_size_t count) int dfs_uffs_write(struct dfs_fd* fd, const void* buf, rt_size_t count)
{ {
uffs_Object* fp; uffs_Object* fp;
u32 byte_write; u32 byte_write;
struct uffs_stat stat_buf; struct uffs_stat stat_buf;
rt_kprintf("count=%d\n",count); rt_kprintf("count=%d\n",count);
if(fd->type == FT_DIRECTORY) if(fd->type == FT_DIRECTORY)
{ {
return -DFS_STATUS_EISDIR; return -DFS_STATUS_EISDIR;
} }
fp = (uffs_Object*)(fd->data); fp = (uffs_Object*)(fd->data);
RT_ASSERT(fp != RT_NULL); RT_ASSERT(fp != RT_NULL);
byte_write = uffs_WriteObject(fp, buf, count); byte_write = uffs_WriteObject(fp, buf, count);
/* update position and file size */ /* update position and file size */
fd->pos = fp->pos; fd->pos = fp->pos;
uffs_stat(fp->name, &stat_buf); uffs_stat(fp->name, &stat_buf);
fd->size = stat_buf.st_size; fd->size = stat_buf.st_size;
return byte_write; return byte_write;
} }
int dfs_uffs_flush(struct dfs_fd* fd) int dfs_uffs_flush(struct dfs_fd* fd)
{ {
uffs_Object* fp; uffs_Object* fp;
fp = (uffs_Object*)(fd->data); fp = (uffs_Object*)(fd->data);
RT_ASSERT(fp != RT_NULL); RT_ASSERT(fp != RT_NULL);
return uffs_FlushObject(fp); return uffs_FlushObject(fp);
} }
int dfs_uffs_lseek(struct dfs_fd* fd, rt_off_t offset) int dfs_uffs_lseek(struct dfs_fd* fd, rt_off_t offset)
{ {
uffs_Object* fp; uffs_Object* fp;
fp = (uffs_Object*)(fd->data); fp = (uffs_Object*)(fd->data);
RT_ASSERT(fp != RT_NULL); RT_ASSERT(fp != RT_NULL);
return uffs_SeekObject(fp, offset, USEEK_SET); return uffs_SeekObject(fp, offset, USEEK_SET);
} }
int dfs_uffs_getdents(struct dfs_fd* fd, struct dirent* dir, rt_uint32_t count) int dfs_uffs_getdents(struct dfs_fd* fd, struct dirent* dir, rt_uint32_t count)
{ {
uffs_DIR* dirp; uffs_DIR* dirp;
struct uffs_dirent *ent; struct uffs_dirent *ent;
rt_uint32_t index; rt_uint32_t index;
struct dirent* d; struct dirent* d;
if(fd->type != FT_DIRECTORY) if(fd->type != FT_DIRECTORY)
{ {
return -DFS_STATUS_EISDIR; return -DFS_STATUS_EISDIR;
} }
dirp = (uffs_DIR*)(fd->data); dirp = (uffs_DIR*)(fd->data);
RT_ASSERT(dirp != RT_NULL); RT_ASSERT(dirp != RT_NULL);
/* make integer count */ /* make integer count */
count = (count / sizeof(struct dirent)) * sizeof(struct dirent); count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
if ( count == 0 ) return -DFS_STATUS_EINVAL; if ( count == 0 ) return -DFS_STATUS_EINVAL;
index = 0; index = 0;
while (1) while (1)
{ {
d = dir + index; d = dir + index;
ent = uffs_readdir(dirp); ent = uffs_readdir(dirp);
if(ent == RT_NULL)break; if(ent == RT_NULL)break;
d->d_type = DFS_DT_DIR; d->d_type = DFS_DT_DIR;
d->d_namlen = ent->d_namelen; d->d_namlen = ent->d_namelen;
d->d_reclen = (rt_uint16_t)sizeof(struct dirent); d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
rt_strncpy(d->d_name, ent->d_name, rt_strlen(ent->d_name) + 1); rt_strncpy(d->d_name, ent->d_name, rt_strlen(ent->d_name) + 1);
index ++; index ++;
if ( index * sizeof(struct dirent) >= count ) if ( index * sizeof(struct dirent) >= count )
break; break;
} }
return index * sizeof(struct dirent); return index * sizeof(struct dirent);
} }
//Delete a File or Directory //Delete a File or Directory
int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* path) int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* path)
{ {
int ret; int ret;
int err = 0; int err = 0;
ret = uffs_DeleteObject(path, &err); ret = uffs_DeleteObject(path, &err);
uffs_set_error(-err); uffs_set_error(-err);
return ret; return ret;
} }
int dfs_uffs_stat(struct dfs_filesystem* fs, const char* path, struct stat* st) int dfs_uffs_stat(struct dfs_filesystem* fs, const char* path, struct stat* st)
{ {
int ret=U_SUCC; int ret=U_SUCC;
struct uffs_stat stat_buf; struct uffs_stat stat_buf;
ret = uffs_stat(path, &stat_buf); ret = uffs_stat(path, &stat_buf);
if (ret == U_SUCC) if (ret == U_SUCC)
{ {
rt_uint32_t mode=0; rt_uint32_t mode=0;
st->st_dev = 0; st->st_dev = 0;
if(stat_buf.st_mode & US_IFREG) mode |= DFS_S_IFREG; 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_IFDIR) mode |= DFS_S_IFDIR;
if(stat_buf.st_mode & US_IRWXU) mode |= DFS_S_IRWXU; 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_IRUSR) mode |= DFS_S_IRUSR;
if(stat_buf.st_mode & US_IWUSR) mode |= DFS_S_IWUSR; 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_IXUSR) mode |= DFS_S_IXUSR;
if(stat_buf.st_mode & US_IRWXG) mode |= DFS_S_IRWXG; 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_IRGRP) mode |= DFS_S_IRGRP;
if(stat_buf.st_mode & US_IWGRP) mode |= DFS_S_IWGRP; 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_IXGRP) mode |= DFS_S_IXGRP;
if(stat_buf.st_mode & US_IRWXO) mode |= DFS_S_IRWXO; 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_IROTH) mode |= DFS_S_IROTH;
if(stat_buf.st_mode & US_IWOTH) mode |= DFS_S_IWOTH; if(stat_buf.st_mode & US_IWOTH) mode |= DFS_S_IWOTH;
if(stat_buf.st_mode & US_IXOTH) mode |= DFS_S_IXOTH; if(stat_buf.st_mode & US_IXOTH) mode |= DFS_S_IXOTH;
st->st_mode = mode; st->st_mode = mode;
st->st_size = stat_buf.st_size; st->st_size = stat_buf.st_size;
st->st_mtime= stat_buf.st_mtime; st->st_mtime= stat_buf.st_mtime;
st->st_blksize= stat_buf.st_blksize; st->st_blksize= stat_buf.st_blksize;
return U_SUCC; return U_SUCC;
} }
return U_FAIL; return U_FAIL;
} }
int dfs_uffs_rename(struct dfs_filesystem* fs, const char* oldpath, const char* newpath) int dfs_uffs_rename(struct dfs_filesystem* fs, const char* oldpath, const char* newpath)
{ {
int ret; int ret;
int err = 0; int err = 0;
ret = uffs_RenameObject(oldpath, newpath, &err); ret = uffs_RenameObject(oldpath, newpath, &err);
uffs_set_error(-err); uffs_set_error(-err);
return ret; return ret;
} }
struct dfs_filesystem_operation _uffs = struct dfs_filesystem_operation _uffs =
{ {
"uffs", "uffs",
dfs_uffs_mount, DFS_FS_FLAG_DEFAULT,
dfs_uffs_unmount, dfs_uffs_mount,
dfs_uffs_mkfs, dfs_uffs_unmount,
dfs_uffs_statfs, dfs_uffs_mkfs,
dfs_uffs_open, dfs_uffs_statfs,
dfs_uffs_close, dfs_uffs_open,
dfs_uffs_ioctl, dfs_uffs_close,
dfs_uffs_read, dfs_uffs_ioctl,
dfs_uffs_write, dfs_uffs_read,
dfs_uffs_flush, dfs_uffs_write,
dfs_uffs_lseek, dfs_uffs_flush,
dfs_uffs_getdents, dfs_uffs_lseek,
dfs_uffs_unlink, dfs_uffs_getdents,
dfs_uffs_stat, dfs_uffs_unlink,
dfs_uffs_rename, dfs_uffs_stat,
}; dfs_uffs_rename,
};
int dfs_uffs_init(void)
{ int dfs_uffs_init(void)
/* register UFFS file system */ {
return dfs_register(&_uffs); /* register UFFS file system */
} return dfs_register(&_uffs);
}

View File

@ -17,6 +17,9 @@
#include <dfs_def.h> #include <dfs_def.h>
#define DFS_FS_FLAG_DEFAULT 0x00 /* default flag */
#define DFS_FS_FLAG_FULLPATH 0x01 /* set full path to underlaying file system */
/* Pre-declaration */ /* Pre-declaration */
struct dfs_filesystem; struct dfs_filesystem;
struct dfs_fd; struct dfs_fd;
@ -25,6 +28,7 @@ struct dfs_fd;
struct dfs_filesystem_operation struct dfs_filesystem_operation
{ {
char *name; char *name;
rt_uint32_t flags; /* flags for file system operations */
/* mount and unmount file system */ /* mount and unmount file system */
int (*mount) (struct dfs_filesystem *fs, unsigned long rwflag, const void *data); int (*mount) (struct dfs_filesystem *fs, unsigned long rwflag, const void *data);

View File

@ -66,13 +66,20 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
fd->size = 0; fd->size = 0;
fd->pos = 0; fd->pos = 0;
if (dfs_subdir(fs->path, fullpath) == RT_NULL) if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH))
fd->path = rt_strdup("/"); {
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 else
fd->path = rt_strdup(dfs_subdir(fs->path, fullpath)); {
rt_free(fullpath); fd->path = fullpath;
dfs_log(DFS_DEBUG_INFO, ("Actual file path: %s\n", fd->path)); }
/* specific file system open routine */ /* specific file system open routine */
if (fs->ops->open == RT_NULL) if (fs->ops->open == RT_NULL)
{ {
@ -241,10 +248,15 @@ int dfs_file_unlink(const char *path)
if (fs->ops->unlink != RT_NULL) if (fs->ops->unlink != RT_NULL)
{ {
if (dfs_subdir(fs->path, fullpath) == RT_NULL) if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH))
result = fs->ops->unlink(fs, "/"); {
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 else
result = fs->ops->unlink(fs, dfs_subdir(fs->path, fullpath)); result = fs->ops->unlink(fs, fullpath);
} }
else result = -DFS_STATUS_ENOSYS; 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 */ /* 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); rt_free(fullpath);