summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorgeniusgogo <[email protected]>2023-08-02 13:59:43 +0800
committerGitHub <[email protected]>2023-08-02 13:59:43 +0800
commit69d94315b8453ed1986a8a7a4cbd5835deceb3be (patch)
treee9c2121e4d2fef01b5997044ca9badc6cc08a81e /components
parent31fec3bb7051887efd7a75ed0f53b1cd7216b36a (diff)
update dfs (#7887)
Diffstat (limited to 'components')
-rw-r--r--components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c2
-rw-r--r--components/dfs/dfs_v1/src/dfs_file.c38
-rw-r--r--components/dfs/dfs_v2/filesystems/devfs/devfs.c4
-rw-r--r--components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c38
-rw-r--r--components/dfs/dfs_v2/filesystems/mqueue/dfs_mqueue.c7
-rw-r--r--components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c43
-rw-r--r--components/dfs/dfs_v2/include/dfs_file.h2
-rw-r--r--components/dfs/dfs_v2/include/dfs_fs.h4
-rw-r--r--components/dfs/dfs_v2/include/dfs_mnt.h5
-rw-r--r--components/dfs/dfs_v2/src/dfs.c4
-rw-r--r--components/dfs/dfs_v2/src/dfs_dentry.c9
-rw-r--r--components/dfs/dfs_v2/src/dfs_file.c243
-rw-r--r--components/dfs/dfs_v2/src/dfs_fs.c51
-rw-r--r--components/dfs/dfs_v2/src/dfs_mnt.c62
-rw-r--r--components/dfs/dfs_v2/src/dfs_posix.c112
15 files changed, 457 insertions, 167 deletions
diff --git a/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c b/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c
index f690d5750f..55d2027170 100644
--- a/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c
+++ b/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c
@@ -485,7 +485,7 @@ int dfs_tmpfs_stat(struct dfs_filesystem *fs,
if (d_file == NULL)
return -ENOENT;
- st->st_dev = 0;
+ st->st_dev = (dev_t)dfs_filesystem_lookup(fs->path);
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
S_IWUSR | S_IWGRP | S_IWOTH;
if (d_file->type == TMPFS_TYPE_DIR)
diff --git a/components/dfs/dfs_v1/src/dfs_file.c b/components/dfs/dfs_v1/src/dfs_file.c
index 094e26c323..e8594d8bae 100644
--- a/components/dfs/dfs_v1/src/dfs_file.c
+++ b/components/dfs/dfs_v1/src/dfs_file.c
@@ -591,39 +591,23 @@ int dfs_file_stat(const char *path, struct stat *buf)
return -ENOENT;
}
- if ((fullpath[0] == '/' && fullpath[1] == '\0') ||
- (dfs_subdir(fs->path, fullpath) == NULL))
+ if (fs->ops->stat == NULL)
{
- /* it's the root directory */
- buf->st_dev = 0;
-
- buf->st_mode = S_IRUSR | S_IRGRP | S_IROTH |
- S_IWUSR | S_IWGRP | S_IWOTH;
- buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
-
- buf->st_size = 0;
- buf->st_mtime = 0;
-
- /* release full path */
rt_free(fullpath);
+ LOG_E("the filesystem didn't implement this function");
- return RT_EOK;
+ return -ENOSYS;
+ }
+ /* get the real file path and get file stat */
+ if (fs->ops->flags & DFS_FS_FLAG_FULLPATH)
+ {
+ result = fs->ops->stat(fs, fullpath, buf);
}
else
{
- if (fs->ops->stat == NULL)
- {
- rt_free(fullpath);
- LOG_E("the filesystem didn't implement this function");
-
- return -ENOSYS;
- }
-
- /* get the real file path and get file stat */
- 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);
+ const char *subdir = dfs_subdir(fs->path, fullpath);
+ subdir = subdir ? subdir : "/";
+ result = fs->ops->stat(fs, subdir, buf);
}
rt_free(fullpath);
diff --git a/components/dfs/dfs_v2/filesystems/devfs/devfs.c b/components/dfs/dfs_v2/filesystems/devfs/devfs.c
index cfd47cdcce..713ca49db7 100644
--- a/components/dfs/dfs_v2/filesystems/devfs/devfs.c
+++ b/components/dfs/dfs_v2/filesystems/devfs/devfs.c
@@ -232,6 +232,10 @@ int dfs_devfs_free_vnode(struct dfs_vnode *vnode)
int dfs_devfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data)
{
RT_ASSERT(mnt != RT_NULL);
+
+ rt_atomic_add(&(mnt->ref_count), 1);
+ mnt->flags |= MNT_IS_LOCKED;
+
return RT_EOK;
}
diff --git a/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c b/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c
index 5e0280d941..a5eb24ecaf 100644
--- a/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c
+++ b/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c
@@ -507,15 +507,13 @@ int dfs_elm_close(struct dfs_file *file)
else if (file->vnode->type == FT_REGULAR)
{
FIL *fd = RT_NULL;
+
fd = (FIL *)(file->vnode->data);
RT_ASSERT(fd != RT_NULL);
- result = f_close(fd);
- if (result == FR_OK)
- {
- /* release memory */
- rt_free(fd);
- }
+ f_close(fd);
+ /* release memory */
+ rt_free(fd);
}
return elm_result_to_dfs(result);
@@ -573,8 +571,7 @@ ssize_t dfs_elm_read(struct dfs_file *file, void *buf, size_t len, off_t *pos)
result = f_read(fd, buf, len, &byte_read);
/* update position */
- file->fpos = fd->fptr;
- *pos = file->fpos;
+ *pos = fd->fptr;
if (result == FR_OK)
return byte_read;
@@ -597,8 +594,7 @@ ssize_t dfs_elm_write(struct dfs_file *file, const void *buf, size_t len, off_t
result = f_write(fd, buf, len, &byte_write);
/* update position and file size */
- file->fpos = fd->fptr;
- *pos = file->fpos;
+ *pos = fd->fptr;
file->vnode->size = f_size(fd);
if (result == FR_OK)
return byte_write;
@@ -621,6 +617,24 @@ int dfs_elm_flush(struct dfs_file *file)
off_t dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
{
FRESULT result = FR_OK;
+
+ switch (wherece)
+ {
+ case SEEK_SET:
+ break;
+
+ case SEEK_CUR:
+ offset += file->fpos;
+ break;
+
+ case SEEK_END:
+ offset += file->vnode->size;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
if (file->vnode->type == FT_REGULAR)
{
FIL *fd;
@@ -633,7 +647,6 @@ off_t dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
if (result == FR_OK)
{
/* return current position */
- file->fpos = fd->fptr;
return fd->fptr;
}
}
@@ -649,8 +662,7 @@ off_t dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
if (result == FR_OK)
{
/* update file position */
- file->fpos = offset;
- return file->fpos;
+ return offset;
}
}
diff --git a/components/dfs/dfs_v2/filesystems/mqueue/dfs_mqueue.c b/components/dfs/dfs_v2/filesystems/mqueue/dfs_mqueue.c
index 0dcee489ff..13719f386a 100644
--- a/components/dfs/dfs_v2/filesystems/mqueue/dfs_mqueue.c
+++ b/components/dfs/dfs_v2/filesystems/mqueue/dfs_mqueue.c
@@ -230,11 +230,6 @@ static struct dfs_filesystem_type _mqueue = {
int dfs_mqueue_init(void) {
/* register mqueue file system */
- dfs_register(&_mqueue);
- mkdir("/dev/mqueue", 0x777);
- if (dfs_mount(RT_NULL, "/dev/mqueue", "mqueue", 0, 0) != 0) {
- rt_kprintf("Dir /dev/mqueue mount failed!\n");
- }
- return 0;
+ return dfs_register(&_mqueue);
}
INIT_COMPONENT_EXPORT(dfs_mqueue_init);
diff --git a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c
index 752fbc2513..801b6120c2 100644
--- a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c
+++ b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c
@@ -280,17 +280,16 @@ static ssize_t dfs_tmpfs_read(struct dfs_file *file, void *buf, size_t count, of
d_file = (struct tmpfs_file *)file->vnode->data;
RT_ASSERT(d_file != NULL);
- if (count < file->vnode->size - file->fpos)
+ if (count < file->vnode->size - *pos)
length = count;
else
- length = file->vnode->size - file->fpos;
+ length = file->vnode->size - *pos;
if (length > 0)
- memcpy(buf, &(d_file->data[file->fpos]), length);
+ memcpy(buf, &(d_file->data[*pos]), length);
/* update file current position */
- file->fpos += length;
- *pos = file->fpos;
+ *pos += length;
return length;
}
@@ -306,41 +305,55 @@ static ssize_t dfs_tmpfs_write(struct dfs_file *file, const void *buf, size_t co
superblock = d_file->sb;
RT_ASSERT(superblock != NULL);
- if (count + file->fpos > file->vnode->size)
+ if (count + *pos > file->vnode->size)
{
rt_uint8_t *ptr;
- ptr = rt_realloc(d_file->data, file->fpos + count);
+ ptr = rt_realloc(d_file->data, *pos + count);
if (ptr == NULL)
{
rt_set_errno(-ENOMEM);
return 0;
}
- superblock->df_size += (file->fpos - d_file->size + count);
+ superblock->df_size += (*pos - d_file->size + count);
/* update d_file and file size */
d_file->data = ptr;
- d_file->size = file->fpos + count;
+ d_file->size = *pos + count;
file->vnode->size = d_file->size;
LOG_D("tmpfile ptr:%x, size:%d", ptr, d_file->size);
}
if (count > 0)
- memcpy(d_file->data + file->fpos, buf, count);
+ memcpy(d_file->data + *pos, buf, count);
/* update file current position */
- file->fpos += count;
- *pos = file->fpos;
+ *pos += count;
return count;
}
static off_t dfs_tmpfs_lseek(struct dfs_file *file, off_t offset, int wherece)
{
- if (offset <= (off_t)file->vnode->size)
+ switch (wherece)
{
- file->fpos = offset;
+ case SEEK_SET:
+ break;
+
+ case SEEK_CUR:
+ offset += file->fpos;
+ break;
+
+ case SEEK_END:
+ offset += file->vnode->size;
+ break;
- return file->fpos;
+ default:
+ return -EINVAL;
+ }
+
+ if (offset <= (off_t)file->vnode->size)
+ {
+ return offset;
}
return -EIO;
diff --git a/components/dfs/dfs_v2/include/dfs_file.h b/components/dfs/dfs_v2/include/dfs_file.h
index 11793b2ad7..bb6551c8eb 100644
--- a/components/dfs/dfs_v2/include/dfs_file.h
+++ b/components/dfs/dfs_v2/include/dfs_file.h
@@ -140,6 +140,8 @@ void dfs_file_deinit(struct dfs_file *file);
int dfs_file_open(struct dfs_file *file, const char *path, int flags, mode_t mode);
int dfs_file_close(struct dfs_file *file);
+off_t dfs_file_get_fpos(struct dfs_file *file);
+void dfs_file_set_fpos(struct dfs_file *file, off_t fpos);
ssize_t dfs_file_read(struct dfs_file *file, void *buf, size_t len);
ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len);
off_t generic_dfs_lseek(struct dfs_file *file, off_t offset, int whence);
diff --git a/components/dfs/dfs_v2/include/dfs_fs.h b/components/dfs/dfs_v2/include/dfs_fs.h
index 5146d42f7d..4a56119d51 100644
--- a/components/dfs/dfs_v2/include/dfs_fs.h
+++ b/components/dfs/dfs_v2/include/dfs_fs.h
@@ -77,6 +77,7 @@ struct dfs_filesystem_type
struct dfs_filesystem_type *next;
};
+struct dfs_filesystem_type *dfs_filesystems(void);
int dfs_unregister(struct dfs_filesystem_type *fs);
int dfs_register(struct dfs_filesystem_type *fs);
const char *dfs_filesystem_get_mounted_path(struct rt_device *device);
@@ -86,8 +87,9 @@ int dfs_mount(const char *device_name,
const char *filesystemtype,
unsigned long rwflag,
const void *data);
-int dfs_umount(const char *specialfile);
+int dfs_umount(const char *specialfile, int flags);
int dfs_unmount(const char *specialfile);
+int dfs_is_mounted(struct dfs_mnt *mnt);
int dfs_mkfs(const char *fs_name, const char *device_name);
int dfs_statfs(const char *path, struct statfs *buffer);
int dfs_filesystem_get_partition(struct dfs_partition *part,
diff --git a/components/dfs/dfs_v2/include/dfs_mnt.h b/components/dfs/dfs_v2/include/dfs_mnt.h
index c917520438..0d73051868 100644
--- a/components/dfs/dfs_v2/include/dfs_mnt.h
+++ b/components/dfs/dfs_v2/include/dfs_mnt.h
@@ -36,6 +36,9 @@ struct dfs_mnt
#define MNT_IS_ALLOCED 0x1 /* the mnt struct is allocated */
#define MNT_IS_ADDLIST 0x2 /* the mnt struct is added into list */
#define MNT_IS_MOUNTED 0x4 /* the mnt struct is mounted */
+#define MNT_IS_UMOUNT 0x8 /* the mnt is unmount */
+#define MNT_IS_LOCKED 0x10 /* the mnt is locked */
+#define MNT_FORCE 0x20 /* the mnt force unmount */
rt_atomic_t ref_count; /* reference count */
@@ -58,6 +61,8 @@ int dfs_mnt_unref(struct dfs_mnt* mnt);
rt_bool_t dfs_mnt_has_child_mnt(struct dfs_mnt *mnt, const char* fullpath);
+int dfs_mnt_foreach(struct dfs_mnt* (*func)(struct dfs_mnt *mnt, void *parameter), void *parameter);
+
#ifdef __cplusplus
}
#endif
diff --git a/components/dfs/dfs_v2/src/dfs.c b/components/dfs/dfs_v2/src/dfs.c
index 9b25985409..bcea75e219 100644
--- a/components/dfs/dfs_v2/src/dfs.c
+++ b/components/dfs/dfs_v2/src/dfs.c
@@ -197,7 +197,7 @@ int fdt_fd_new(struct dfs_fdtable *fdt)
dfs_file_lock();
/* find an empty fd entry */
- idx = fd_alloc(fdt, 0);
+ idx = fd_alloc(fdt, (fdt == &_fdtab) ? DFS_STDIO_OFFSET : 0);
/* can't find an empty fd entry */
if (idx < 0)
{
@@ -452,7 +452,7 @@ sysret_t sys_dup(int oldfd)
int sys_dup(int oldfd)
#endif
{
- int newfd = dfs_dup(oldfd, DFS_STDIO_OFFSET);
+ int newfd = dfs_dup(oldfd, (dfs_fdtable_get() == &_fdtab) ? DFS_STDIO_OFFSET : 0);
#ifdef RT_USING_SMART
return (sysret_t)newfd;
diff --git a/components/dfs/dfs_v2/src/dfs_dentry.c b/components/dfs/dfs_v2/src/dfs_dentry.c
index 78c214cc67..6605f094f2 100644
--- a/components/dfs/dfs_v2/src/dfs_dentry.c
+++ b/components/dfs/dfs_v2/src/dfs_dentry.c
@@ -185,7 +185,7 @@ void dfs_dentry_insert(struct dfs_dentry *dentry)
struct dfs_dentry *dfs_dentry_lookup(struct dfs_mnt *mnt, const char *path, uint32_t flags)
{
struct dfs_dentry *dentry;
- struct dfs_vnode *vnode;
+ struct dfs_vnode *vnode = RT_NULL;
int mntpoint_len = strlen(mnt->fullpath);
if (rt_strncmp(mnt->fullpath, path, mntpoint_len) == 0)
@@ -210,7 +210,12 @@ struct dfs_dentry *dfs_dentry_lookup(struct dfs_mnt *mnt, const char *path, uint
if (dentry)
{
DLOG(msg, "dentry", mnt->fs_ops->name, DLOG_MSG, "vnode=fs_ops->lookup(dentry)");
- vnode = mnt->fs_ops->lookup(dentry);
+
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ vnode = mnt->fs_ops->lookup(dentry);
+ }
+
if (vnode)
{
DLOG(msg, mnt->fs_ops->name, "dentry", DLOG_MSG_RET, "return vnode");
diff --git a/components/dfs/dfs_v2/src/dfs_file.c b/components/dfs/dfs_v2/src/dfs_file.c
index 52b1a63210..ac18caefc1 100644
--- a/components/dfs/dfs_v2/src/dfs_file.c
+++ b/components/dfs/dfs_v2/src/dfs_file.c
@@ -48,11 +48,28 @@ ssize_t rw_verify_area(struct dfs_file *file, off_t *ppos, size_t count)
return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
}
+off_t dfs_file_get_fpos(struct dfs_file *file)
+{
+ if (file)
+ {
+ if (file->vnode->type == FT_REGULAR)
+ {
+ rt_mutex_take(&file->pos_lock, RT_WAITING_FOREVER);
+ }
+ return file->fpos;
+ }
+
+ return 0;
+}
+
void dfs_file_set_fpos(struct dfs_file *file, off_t fpos)
{
if (file)
{
- rt_mutex_take(&file->pos_lock, RT_WAITING_FOREVER);
+ if (file->vnode->type != FT_REGULAR)
+ {
+ rt_mutex_take(&file->pos_lock, RT_WAITING_FOREVER);
+ }
file->fpos = fpos;
rt_mutex_release(&file->pos_lock);
}
@@ -116,6 +133,7 @@ static void dfs_file_unref(struct dfs_file *file)
struct dfs_dentry* dfs_file_follow_link(struct dfs_dentry *dentry)
{
int ret = 0;
+ struct dfs_dentry *tmp = dfs_dentry_ref(dentry);
if (dentry && dentry->vnode && dentry->vnode->type == FT_SYMLINK)
{
@@ -126,14 +144,18 @@ struct dfs_dentry* dfs_file_follow_link(struct dfs_dentry *dentry)
{
do
{
- ret = dentry->mnt->fs_ops->readlink(dentry, buf, DFS_PATH_MAX);
+ if (dfs_is_mounted(tmp->mnt) == 0)
+ {
+ ret = tmp->mnt->fs_ops->readlink(tmp, buf, DFS_PATH_MAX);
+ }
+
if (ret > 0)
{
struct dfs_mnt *mnt = NULL;
if (buf[0] != '/')
{
- char *dir = dfs_dentry_pathname(dentry);
+ char *dir = dfs_dentry_pathname(tmp);
/* is the relative directory */
if (dir)
@@ -155,21 +177,21 @@ struct dfs_dentry* dfs_file_follow_link(struct dfs_dentry *dentry)
struct dfs_dentry *de = dfs_dentry_lookup(mnt, buf, 0);
/* release the old dentry */
- dfs_dentry_unref(dentry);
- dentry = de;
+ dfs_dentry_unref(tmp);
+ tmp = de;
}
}
else
{
break;
}
- } while (dentry && dentry->vnode->type == FT_SYMLINK);
+ } while (tmp && tmp->vnode->type == FT_SYMLINK);
}
rt_free(buf);
}
- return dentry;
+ return tmp;
}
/*
@@ -215,7 +237,10 @@ static char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
if ((*mnt)->fs_ops->readlink)
{
- ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
+ if (dfs_is_mounted((*mnt)) == 0)
+ {
+ ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
+ }
}
if (ret > 0)
@@ -264,7 +289,10 @@ static char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
if ((*mnt)->fs_ops->readlink)
{
- ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
+ if (dfs_is_mounted((*mnt)) == 0)
+ {
+ ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
+ }
}
if (ret > 0)
@@ -316,7 +344,7 @@ static char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
*/
int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mode)
{
- int ret = -RT_ERROR;;
+ int ret = -RT_ERROR;
char *fullpath = RT_NULL;
struct dfs_dentry *dentry = RT_NULL;
int fflags = dfs_fflags(oflags);
@@ -361,10 +389,8 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
/* follow symbol link */
target_dentry = dfs_file_follow_link(dentry);
- if (target_dentry)
- {
- dentry = target_dentry;
- }
+ dfs_dentry_unref(dentry);
+ dentry = target_dentry;
}
}
@@ -419,7 +445,11 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
{
mode &= ~S_IFMT;
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->create_vnode");
- vnode = mnt->fs_ops->create_vnode(dentry, oflags & O_DIRECTORY ? FT_DIRECTORY:FT_REGULAR, mode);
+
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ vnode = mnt->fs_ops->create_vnode(dentry, oflags & O_DIRECTORY ? FT_DIRECTORY:FT_REGULAR, mode);
+ }
if (vnode)
{
@@ -477,7 +507,16 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
if (permission && file->fops->open)
{
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fops->open(file)");
- ret = file->fops->open(file);
+
+ if (dfs_is_mounted(file->vnode->mnt) == 0)
+ {
+ ret = file->fops->open(file);
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
+
if (ret < 0)
{
LOG_E("open %s failed in file system: %s", path, dentry->mnt->fs_ops->name);
@@ -523,7 +562,16 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
if (file->fops->truncate)
{
DLOG(msg, "dfs_file", dentry->mnt->fs_ops->name, DLOG_MSG, "fops->truncate(file, 0)");
- ret = file->fops->truncate(file, 0);
+
+ if (dfs_is_mounted(file->vnode->mnt) == 0)
+ {
+ ret = file->fops->truncate(file, 0);
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
+
}
}
@@ -552,6 +600,7 @@ int dfs_file_close(struct dfs_file *file)
if (ref_count == 1 && file->fops && file->fops->close)
{
DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->close(file)");
+
ret = file->fops->close(file);
if (ret == 0) /* close file sucessfully */
@@ -594,20 +643,25 @@ ssize_t dfs_file_read(struct dfs_file *file, void *buf, size_t len)
}
else if (file->vnode && file->vnode->type != FT_DIRECTORY)
{
- off_t pos;
- pos = file->fpos;
+ /* fpos lock */
+ off_t pos = dfs_file_get_fpos(file);
ret = rw_verify_area(file, &pos, len);
if (ret > 0)
{
len = ret;
- ret = file->fops->read(file, buf, len, &pos);
- if (ret > 0)
+ if (dfs_is_mounted(file->vnode->mnt) == 0)
{
- dfs_file_set_fpos(file, pos);
+ ret = file->fops->read(file, buf, len, &pos);
+ }
+ else
+ {
+ ret = -EINVAL;
}
}
+ /* fpos unlock */
+ dfs_file_set_fpos(file, pos);
}
}
@@ -632,21 +686,27 @@ ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len)
}
else if (file->vnode && file->vnode->type != FT_DIRECTORY)
{
- off_t pos;
+ /* fpos lock */
+ off_t pos = dfs_file_get_fpos(file);
- pos = file->fpos;
ret = rw_verify_area(file, &pos, len);
if (ret > 0)
{
len = ret;
DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG,
"dfs_file_write(fd, buf, %d)", len);
- ret = file->fops->write(file, buf, len, &pos);
- if (ret > 0)
+
+ if (dfs_is_mounted(file->vnode->mnt) == 0)
{
- dfs_file_set_fpos(file, pos);
+ ret = file->fops->write(file, buf, len, &pos);
+ }
+ else
+ {
+ ret = -EINVAL;
}
}
+ /* fpos unlock */
+ dfs_file_set_fpos(file, pos);
}
}
@@ -666,25 +726,26 @@ off_t generic_dfs_lseek(struct dfs_file *file, off_t offset, int whence)
else
return -EINVAL;
- dfs_file_set_fpos(file, foffset);
-
return foffset;
}
off_t dfs_file_lseek(struct dfs_file *file, off_t offset, int wherece)
{
- off_t retval;
-
- if (!file)
- return -EBADF;
+ off_t retval = -EINVAL;
- retval = -EINVAL;
- if (file->fops->lseek)
+ if (file && file->fops->lseek)
{
- retval = file->fops->lseek(file, offset, wherece);
- if (retval >= 0)
+ if (dfs_is_mounted(file->vnode->mnt) == 0)
{
- dfs_file_set_fpos(file, retval);
+ /* fpos lock */
+ off_t pos = dfs_file_get_fpos(file);
+ retval = file->fops->lseek(file, offset, wherece);
+ if (retval >= 0)
+ {
+ pos = retval;
+ }
+ /* fpos unlock */
+ dfs_file_set_fpos(file, pos);
}
}
@@ -720,7 +781,11 @@ int dfs_file_stat(const char *path, struct stat *buf)
if (mnt->fs_ops->stat)
{
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
- ret = mnt->fs_ops->stat(dentry, buf);
+
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ ret = mnt->fs_ops->stat(dentry, buf);
+ }
}
/* unref dentry */
@@ -770,7 +835,11 @@ int dfs_file_lstat(const char *path, struct stat *buf)
if (mnt->fs_ops->stat)
{
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
- ret = mnt->fs_ops->stat(dentry, buf);
+
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ ret = mnt->fs_ops->stat(dentry, buf);
+ }
}
/* unref dentry */
@@ -845,7 +914,11 @@ int dfs_file_setattr(const char *path, struct dfs_attr *attr)
if (mnt->fs_ops->setattr)
{
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->setattr(dentry, attr)");
- ret = mnt->fs_ops->setattr(dentry, attr);
+
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ ret = mnt->fs_ops->setattr(dentry, attr);
+ }
}
/* unref dentry */
@@ -870,7 +943,14 @@ int dfs_file_ioctl(struct dfs_file *file, int cmd, void *args)
{
if (file->fops && file->fops->ioctl)
{
- ret = file->fops->ioctl(file, cmd, args);
+ if (dfs_is_mounted(file->vnode->mnt) == 0)
+ {
+ ret = file->fops->ioctl(file, cmd, args);
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
}
else
{
@@ -953,7 +1033,14 @@ int dfs_file_fsync(struct dfs_file *file)
{
if (file->fops->flush)
{
- ret = file->fops->flush(file);
+ if (dfs_is_mounted(file->vnode->mnt) == 0)
+ {
+ ret = file->fops->flush(file);
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
}
}
@@ -997,7 +1084,10 @@ int dfs_file_unlink(const char *path)
if (mnt->fs_ops->unlink)
{
- ret = mnt->fs_ops->unlink(dentry);
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ ret = mnt->fs_ops->unlink(dentry);
+ }
}
}
else
@@ -1096,7 +1186,10 @@ int dfs_file_link(const char *oldname, const char *newname)
{
if (mnt->fs_ops->link)
{
- ret = mnt->fs_ops->link(old_dentry, new_dentry);
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ ret = mnt->fs_ops->link(old_dentry, new_dentry);
+ }
}
}
@@ -1211,7 +1304,10 @@ int dfs_file_symlink(const char *target, const char *linkpath)
}
}
- ret = mnt->fs_ops->symlink(dentry, tmp, index + 1);
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ ret = mnt->fs_ops->symlink(dentry, tmp, index + 1);
+ }
}
else
{
@@ -1280,7 +1376,10 @@ int dfs_file_readlink(const char *path, char *buf, int bufsize)
{
if (mnt->fs_ops->readlink)
{
- ret = mnt->fs_ops->readlink(dentry, buf, bufsize);
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ ret = mnt->fs_ops->readlink(dentry, buf, bufsize);
+ }
}
else
{
@@ -1361,7 +1460,10 @@ int dfs_file_rename(const char *old_file, const char *new_file)
{
if (mnt->fs_ops->rename)
{
- ret = mnt->fs_ops->rename(old_dentry, new_dentry);
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ ret = mnt->fs_ops->rename(old_dentry, new_dentry);
+ }
}
}
@@ -1390,7 +1492,14 @@ int dfs_file_ftruncate(struct dfs_file *file, off_t length)
{
if (file->fops->truncate)
{
- ret = file->fops->truncate(file, length);
+ if (dfs_is_mounted(file->vnode->mnt) == 0)
+ {
+ ret = file->fops->truncate(file, length);
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
}
else
{
@@ -1413,7 +1522,14 @@ int dfs_file_flush(struct dfs_file *file)
{
if (file->fops->flush)
{
- ret = file->fops->flush(file);
+ if (dfs_is_mounted(file->vnode->mnt) == 0)
+ {
+ ret = file->fops->flush(file);
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
}
else
{
@@ -1439,7 +1555,15 @@ int dfs_file_getdents(struct dfs_file *file, struct dirent *dirp, size_t nbytes)
if (file->fops && file->fops->getdents)
{
DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->getdents()");
- ret = file->fops->getdents(file, dirp, nbytes);
+
+ if (dfs_is_mounted(file->vnode->mnt) == 0)
+ {
+ ret = file->fops->getdents(file, dirp, nbytes);
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
}
}
}
@@ -1488,7 +1612,12 @@ int dfs_file_isdir(const char *path)
{
struct stat stat = {0};
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
- ret = mnt->fs_ops->stat(dentry, &stat);
+
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ ret = mnt->fs_ops->stat(dentry, &stat);
+ }
+
if (ret == RT_EOK && S_ISDIR(stat.st_mode))
{
ret = RT_EOK;
@@ -1547,7 +1676,15 @@ int dfs_file_mmap2(struct dfs_file *file, struct dfs_mmap2_args *mmap2)
}
else if (file->vnode->type == FT_DEVICE && file->vnode->fops->ioctl)
{
- ret = file->vnode->fops->ioctl(file, RT_FIOMMAP2, mmap2);
+ if (dfs_is_mounted(file->vnode->mnt) == 0)
+ {
+ ret = file->vnode->fops->ioctl(file, RT_FIOMMAP2, mmap2);
+ }
+ else
+ {
+ ret = EINVAL;
+ }
+
if (ret != 0)
{
ret = ret > 0 ? ret : -ret;
diff --git a/components/dfs/dfs_v2/src/dfs_fs.c b/components/dfs/dfs_v2/src/dfs_fs.c
index ffedc44fca..8c28dbe7ef 100644
--- a/components/dfs/dfs_v2/src/dfs_fs.c
+++ b/components/dfs/dfs_v2/src/dfs_fs.c
@@ -43,6 +43,11 @@ static struct dfs_filesystem_type **_find_filesystem(const char *name)
return type;
}
+struct dfs_filesystem_type *dfs_filesystems(void)
+{
+ return file_systems;
+}
+
int dfs_register(struct dfs_filesystem_type *fs)
{
int ret = 0;
@@ -160,6 +165,8 @@ int dfs_mount(const char *device_name,
DLOG(msg, type->fs_ops->name, "dfs", DLOG_MSG_RET, "mount OK, ret root_dentry");
mnt_child = mnt_parent;
+ mnt_child->flags |= MNT_IS_MOUNTED;
+
DLOG(note_right, "mnt", "mount sucessfully");
DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_insert(, mnt_child)");
dfs_mnt_insert(RT_NULL, mnt_child);
@@ -202,7 +209,7 @@ int dfs_mount(const char *device_name,
ret = -1;
}
}
- else if (strcmp(mnt_parent->fullpath, fullpath) != 0)
+ else if (mnt_parent && (strcmp(mnt_parent->fullpath, fullpath) != 0))
{
DLOG(msg, "dfs", "dentry", DLOG_MSG, "mntpoint_dentry = dfs_dentry_lookup(mnt_parent, %s, 0)", fullpath);
mntpoint_dentry = dfs_dentry_lookup(mnt_parent, fullpath, 0);
@@ -224,6 +231,8 @@ int dfs_mount(const char *device_name,
ret = mnt_child->fs_ops->mount(mnt_child, rwflag, data);
if (ret == RT_EOK)
{
+ mnt_child->flags |= MNT_IS_MOUNTED;
+
LOG_D("mount %s sucessfully", fullpath);
DLOG(msg, mnt_child->fs_ops->name, "dfs", DLOG_MSG_RET, "mount OK");
@@ -285,7 +294,7 @@ int dfs_mount(const char *device_name,
return ret;
}
-int dfs_umount(const char *specialfile)
+int dfs_umount(const char *specialfile, int flags)
{
int ret = -RT_ERROR;
char *fullpath = RT_NULL;
@@ -301,22 +310,13 @@ int dfs_umount(const char *specialfile)
if (strcmp(mnt->fullpath, fullpath) == 0)
{
/* is the mount point */
+ rt_atomic_t ref_count = rt_atomic_load(&(mnt->ref_count));
- if (rt_atomic_load(&(mnt->ref_count)) == 1 && rt_list_isempty(&mnt->child))
+ if (!(mnt->flags & MNT_IS_LOCKED) && rt_list_isempty(&mnt->child) && (ref_count == 1 || (flags & MNT_FORCE)))
{
- DLOG(msg, "dfs", mnt->fs_ops->name, DLOG_MSG, "fs_ops->umount(mnt)");
- ret = mnt->fs_ops->umount(mnt);
- if (ret == 0)
- {
- DLOG(msg, mnt->fs_ops->name, "dfs", DLOG_MSG_RET, "return OK");
- /* destroy this mount point */
- DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_destroy(mnt)");
- dfs_mnt_destroy(mnt);
- }
- else
- {
- LOG_E("umount file system: %s failed.", fullpath);
- }
+ /* destroy this mount point */
+ DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_destroy(mnt)");
+ ret = dfs_mnt_destroy(mnt);
}
else
{
@@ -345,7 +345,19 @@ int dfs_umount(const char *specialfile)
/* for compatibility */
int dfs_unmount(const char *specialfile)
{
- return dfs_umount(specialfile);
+ return dfs_umount(specialfile, 0);
+}
+
+int dfs_is_mounted(struct dfs_mnt *mnt)
+{
+ int ret = 0;
+
+ if (mnt && !(mnt->flags & MNT_IS_MOUNTED))
+ {
+ ret = -1;
+ }
+
+ return ret;
}
int dfs_mkfs(const char *fs_name, const char *device_name)
@@ -407,7 +419,10 @@ int dfs_statfs(const char *path, struct statfs *buffer)
{
if (mnt->fs_ops->statfs)
{
- ret = mnt->fs_ops->statfs(mnt, buffer);
+ if (dfs_is_mounted(mnt) == 0)
+ {
+ ret = mnt->fs_ops->statfs(mnt, buffer);
+ }
}
}
diff --git a/components/dfs/dfs_v2/src/dfs_mnt.c b/components/dfs/dfs_v2/src/dfs_mnt.c
index 759fed5598..379606d9ce 100644
--- a/components/dfs/dfs_v2/src/dfs_mnt.c
+++ b/components/dfs/dfs_v2/src/dfs_mnt.c
@@ -67,6 +67,7 @@ int dfs_mnt_insert(struct dfs_mnt* mnt, struct dfs_mnt* child)
{
/* it's root mnt */
mnt = child;
+ mnt->flags |= MNT_IS_LOCKED;
/* ref to gobal root */
if (_root_mnt)
@@ -194,22 +195,34 @@ int dfs_mnt_unref(struct dfs_mnt* mnt)
if (mnt)
{
- ret = dfs_lock();
- if (ret == RT_EOK)
+ rt_atomic_sub(&(mnt->ref_count), 1);
+
+ if (rt_atomic_load(&(mnt->ref_count)) == 0)
{
- rt_atomic_sub(&(mnt->ref_count), 1);
+ dfs_lock();
- if (rt_atomic_load(&(mnt->ref_count)) < 0)
+ if (mnt->flags & MNT_IS_UMOUNT)
{
- LOG_W("bug on mnt(%s) release ref_count(%d).", mnt->fullpath, mnt->ref_count);
+ mnt->fs_ops->umount(mnt);
}
- DLOG(note, "mnt", "mnt(%s),ref_count=%d", mnt->fs_ops->name, rt_atomic_load(&(mnt->ref_count)));
+
+ /* free full path */
+ rt_free(mnt->fullpath);
+ mnt->fullpath = RT_NULL;
+
+ /* destroy self and the ref_count should be 0 */
+ DLOG(msg, "mnt", "mnt", DLOG_MSG, "free mnt(%s)", mnt->fs_ops->name);
+ rt_free(mnt);
dfs_unlock();
}
+ else
+ {
+ DLOG(note, "mnt", "mnt(%s),ref_count=%d", mnt->fs_ops->name, rt_atomic_load(&(mnt->ref_count)));
+ }
}
- return 0;
+ return ret;
}
int dfs_mnt_destroy(struct dfs_mnt* mnt)
@@ -218,33 +231,21 @@ int dfs_mnt_destroy(struct dfs_mnt* mnt)
if (mnt)
{
- ret = dfs_lock();
- if (ret == RT_EOK)
+ if (mnt->flags & MNT_IS_MOUNTED)
{
- if (rt_atomic_load(&(mnt->ref_count)) != 1)
- {
- LOG_W("bug on mnt(%s) ref_count(%d).", mnt->fullpath, mnt->ref_count);
- }
-
+ mnt->flags &= ~MNT_IS_MOUNTED;
+ mnt->flags |= MNT_IS_UMOUNT;
/* remote it from mnt list */
if (mnt->flags & MNT_IS_ADDLIST)
{
dfs_mnt_remove(mnt);
}
-
- /* free full path */
- rt_free(mnt->fullpath);
- mnt->fullpath = RT_NULL;
-
- dfs_unlock();
-
- /* destroy self and the ref_count should be 0 */
- DLOG(msg, "mnt", "mnt", DLOG_MSG, "free mnt(%s)", mnt->fs_ops->name);
- rt_free(mnt);
}
+
+ dfs_mnt_unref(mnt);
}
- return 0;
+ return ret;
}
static struct dfs_mnt* _dfs_mnt_foreach(struct dfs_mnt *mnt, struct dfs_mnt* (*func)(struct dfs_mnt *mnt, void *parameter), void *parameter)
@@ -384,3 +385,14 @@ int dfs_mnt_list(struct dfs_mnt *mnt)
return 0;
}
+
+int dfs_mnt_foreach(struct dfs_mnt* (*func)(struct dfs_mnt *mnt, void *parameter), void *parameter)
+{
+ /* lock file system */
+ dfs_lock();
+ _dfs_mnt_foreach(_root_mnt, func, parameter);
+ /* unlock file system */
+ dfs_unlock();
+
+ return 0;
+}
diff --git a/components/dfs/dfs_v2/src/dfs_posix.c b/components/dfs/dfs_v2/src/dfs_posix.c
index a9c822c5c8..fa5f6dc9f0 100644
--- a/components/dfs/dfs_v2/src/dfs_posix.c
+++ b/components/dfs/dfs_v2/src/dfs_posix.c
@@ -412,7 +412,7 @@ RTM_EXPORT(stat);
*/
int fstat(int fildes, struct stat *buf)
{
- int ret = 0;
+ int ret = -1;
struct dfs_file *file;
if (buf == NULL)
@@ -430,7 +430,10 @@ int fstat(int fildes, struct stat *buf)
return -1;
}
- ret = file->dentry->mnt->fs_ops->stat(file->dentry, buf);
+ if (dfs_is_mounted(file->dentry->mnt) == 0)
+ {
+ ret = file->dentry->mnt->fs_ops->stat(file->dentry, buf);
+ }
return ret;
}
@@ -624,7 +627,7 @@ RTM_EXPORT(statfs);
*/
int fstatfs(int fildes, struct statfs *buf)
{
- int ret = 0;
+ int ret = -1;
struct dfs_file *file;
if (buf == NULL)
@@ -642,7 +645,10 @@ int fstatfs(int fildes, struct statfs *buf)
return -1;
}
- ret = file->dentry->mnt->fs_ops->statfs(file->dentry->mnt, buf);
+ if (dfs_is_mounted(file->dentry->mnt) == 0)
+ {
+ ret = file->dentry->mnt->fs_ops->statfs(file->dentry->mnt, buf);
+ }
return ret;
}
@@ -1223,4 +1229,102 @@ char *getcwd(char *buf, size_t size)
}
RTM_EXPORT(getcwd);
+/**
+ * this function is a POSIX compliant version, which will read specified data
+ * buffer length for an open file descriptor.
+ *
+ * @param fd the file descriptor.
+ * @param buf the buffer to save the read data.
+ * @param len the maximal length of data buffer
+ * @param offset the file pos
+ *
+ * @return the actual read data buffer length. If the returned value is 0, it
+ * may be reach the end of file, please check errno.
+ */
+ssize_t pread(int fd, void *buf, size_t len, off_t offset)
+{
+ ssize_t result;
+ off_t fpos;
+ struct dfs_file *file;
+
+ if (buf == NULL)
+ {
+ rt_set_errno(-EBADF);
+ return -1;
+ }
+
+ file = fd_get(fd);
+ if (file == NULL)
+ {
+ rt_set_errno(-EBADF);
+
+ return -1;
+ }
+
+ /* fpos lock */
+ fpos = dfs_file_get_fpos(file);
+ dfs_file_lseek(file, offset, SEEK_SET);
+ result = dfs_file_read(file, buf, len);
+ dfs_file_lseek(file, fpos, SEEK_SET);
+ /* fpos unlock */
+ dfs_file_set_fpos(file, fpos);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+
+ return -1;
+ }
+
+ return result;
+}
+RTM_EXPORT(pread);
+
+/**
+ * this function is a POSIX compliant version, which will write specified data
+ * buffer length for an open file descriptor.
+ *
+ * @param fd the file descriptor
+ * @param buf the data buffer to be written.
+ * @param len the data buffer length.
+ * @param offset the file pos
+ *
+ * @return the actual written data buffer length.
+ */
+ssize_t pwrite(int fd, const void *buf, size_t len, off_t offset)
+{
+ ssize_t result;
+ off_t fpos;
+ struct dfs_file *file;
+
+ if (buf == NULL)
+ {
+ rt_set_errno(-EBADF);
+ return -1;
+ }
+
+ file = fd_get(fd);
+ if (file == NULL)
+ {
+ rt_set_errno(-EBADF);
+
+ return -1;
+ }
+ /* fpos lock */
+ fpos = dfs_file_get_fpos(file);
+ dfs_file_lseek(file, offset, SEEK_SET);
+ result = dfs_file_write(file, buf, len);
+ dfs_file_lseek(file, fpos, SEEK_SET);
+ /* fpos unlock */
+ dfs_file_set_fpos(file, fpos);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+
+ return -1;
+ }
+
+ return result;
+}
+RTM_EXPORT(pwrite);
+
/**@}*/