Browse Source

update dfs (#7887)

geniusgogo 1 year ago
parent
commit
69d94315b8

+ 1 - 1
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)
     if (d_file == NULL)
         return -ENOENT;
         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 |
     st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
                   S_IWUSR | S_IWGRP | S_IWOTH;
                   S_IWUSR | S_IWGRP | S_IWOTH;
     if (d_file->type == TMPFS_TYPE_DIR)
     if (d_file->type == TMPFS_TYPE_DIR)

+ 11 - 27
components/dfs/dfs_v1/src/dfs_file.c

@@ -591,39 +591,23 @@ int dfs_file_stat(const char *path, struct stat *buf)
         return -ENOENT;
         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);
         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
     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);
     rt_free(fullpath);

+ 4 - 0
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)
 int dfs_devfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data)
 {
 {
     RT_ASSERT(mnt != RT_NULL);
     RT_ASSERT(mnt != RT_NULL);
+
+    rt_atomic_add(&(mnt->ref_count), 1);
+    mnt->flags |= MNT_IS_LOCKED;
+
     return RT_EOK;
     return RT_EOK;
 }
 }
 
 

+ 25 - 13
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)
     else if (file->vnode->type == FT_REGULAR)
     {
     {
         FIL *fd = RT_NULL;
         FIL *fd = RT_NULL;
+
         fd = (FIL *)(file->vnode->data);
         fd = (FIL *)(file->vnode->data);
         RT_ASSERT(fd != RT_NULL);
         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);
     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);
     result = f_read(fd, buf, len, &byte_read);
     /* update position */
     /* update position */
-    file->fpos  = fd->fptr;
-    *pos = file->fpos;
+    *pos = fd->fptr;
     if (result == FR_OK)
     if (result == FR_OK)
         return byte_read;
         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);
     result = f_write(fd, buf, len, &byte_write);
     /* update position and file size */
     /* update position and file size */
-    file->fpos  = fd->fptr;
-    *pos = file->fpos;
+    *pos = fd->fptr;
     file->vnode->size = f_size(fd);
     file->vnode->size = f_size(fd);
     if (result == FR_OK)
     if (result == FR_OK)
         return byte_write;
         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)
 off_t dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
 {
 {
     FRESULT result = FR_OK;
     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)
     if (file->vnode->type == FT_REGULAR)
     {
     {
         FIL *fd;
         FIL *fd;
@@ -633,7 +647,6 @@ off_t dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
         if (result == FR_OK)
         if (result == FR_OK)
         {
         {
             /* return current position */
             /* return current position */
-            file->fpos = fd->fptr;
             return 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)
         if (result == FR_OK)
         {
         {
             /* update file position */
             /* update file position */
-            file->fpos = offset;
-            return file->fpos;
+            return offset;
         }
         }
     }
     }
 
 

+ 1 - 6
components/dfs/dfs_v2/filesystems/mqueue/dfs_mqueue.c

@@ -230,11 +230,6 @@ static struct dfs_filesystem_type _mqueue = {
 
 
 int dfs_mqueue_init(void) {
 int dfs_mqueue_init(void) {
     /* register mqueue file system */
     /* 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);
 INIT_COMPONENT_EXPORT(dfs_mqueue_init);

+ 28 - 15
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;
     d_file = (struct tmpfs_file *)file->vnode->data;
     RT_ASSERT(d_file != NULL);
     RT_ASSERT(d_file != NULL);
 
 
-    if (count < file->vnode->size - file->fpos)
+    if (count < file->vnode->size - *pos)
         length = count;
         length = count;
     else
     else
-        length = file->vnode->size - file->fpos;
+        length = file->vnode->size - *pos;
 
 
     if (length > 0)
     if (length > 0)
-        memcpy(buf, &(d_file->data[file->fpos]), length);
+        memcpy(buf, &(d_file->data[*pos]), length);
 
 
     /* update file current position */
     /* update file current position */
-    file->fpos += length;
-    *pos = file->fpos;
+    *pos += length;
 
 
     return 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;
     superblock = d_file->sb;
     RT_ASSERT(superblock != NULL);
     RT_ASSERT(superblock != NULL);
 
 
-    if (count + file->fpos > file->vnode->size)
+    if (count + *pos > file->vnode->size)
     {
     {
         rt_uint8_t *ptr;
         rt_uint8_t *ptr;
-        ptr = rt_realloc(d_file->data, file->fpos + count);
+        ptr = rt_realloc(d_file->data, *pos + count);
         if (ptr == NULL)
         if (ptr == NULL)
         {
         {
             rt_set_errno(-ENOMEM);
             rt_set_errno(-ENOMEM);
             return 0;
             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 */
         /* update d_file and file size */
         d_file->data = ptr;
         d_file->data = ptr;
-        d_file->size = file->fpos + count;
+        d_file->size = *pos + count;
         file->vnode->size = d_file->size;
         file->vnode->size = d_file->size;
         LOG_D("tmpfile ptr:%x, size:%d", ptr, d_file->size);
         LOG_D("tmpfile ptr:%x, size:%d", ptr, d_file->size);
     }
     }
 
 
     if (count > 0)
     if (count > 0)
-        memcpy(d_file->data + file->fpos, buf, count);
+        memcpy(d_file->data + *pos, buf, count);
 
 
     /* update file current position */
     /* update file current position */
-    file->fpos += count;
-    *pos = file->fpos;
+    *pos += count;
 
 
     return count;
     return count;
 }
 }
 
 
 static off_t dfs_tmpfs_lseek(struct dfs_file *file, off_t offset, int wherece)
 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;
     return -EIO;

+ 2 - 0
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_open(struct dfs_file *file, const char *path, int flags, mode_t mode);
 int dfs_file_close(struct dfs_file *file);
 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_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);
 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);
 off_t generic_dfs_lseek(struct dfs_file *file, off_t offset, int whence);

+ 3 - 1
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 *next;
 };
 };
 
 
+struct dfs_filesystem_type *dfs_filesystems(void);
 int dfs_unregister(struct dfs_filesystem_type *fs);
 int dfs_unregister(struct dfs_filesystem_type *fs);
 int dfs_register(struct dfs_filesystem_type *fs);
 int dfs_register(struct dfs_filesystem_type *fs);
 const char *dfs_filesystem_get_mounted_path(struct rt_device *device);
 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,
             const char *filesystemtype,
             unsigned long rwflag,
             unsigned long rwflag,
             const void *data);
             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_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_mkfs(const char *fs_name, const char *device_name);
 int dfs_statfs(const char *path, struct statfs *buffer);
 int dfs_statfs(const char *path, struct statfs *buffer);
 int dfs_filesystem_get_partition(struct dfs_partition *part,
 int dfs_filesystem_get_partition(struct dfs_partition *part,

+ 5 - 0
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_ALLOCED 0x1          /* the mnt struct is allocated */
 #define MNT_IS_ADDLIST 0x2          /* the mnt struct is added into list */
 #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_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 */
     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);
 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
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 2 - 2
components/dfs/dfs_v2/src/dfs.c

@@ -197,7 +197,7 @@ int fdt_fd_new(struct dfs_fdtable *fdt)
     dfs_file_lock();
     dfs_file_lock();
 
 
     /* find an empty fd entry */
     /* 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 */
     /* can't find an empty fd entry */
     if (idx < 0)
     if (idx < 0)
     {
     {
@@ -452,7 +452,7 @@ sysret_t sys_dup(int oldfd)
 int sys_dup(int oldfd)
 int sys_dup(int oldfd)
 #endif
 #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
 #ifdef RT_USING_SMART
     return (sysret_t)newfd;
     return (sysret_t)newfd;

+ 7 - 2
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 *dfs_dentry_lookup(struct dfs_mnt *mnt, const char *path, uint32_t flags)
 {
 {
     struct dfs_dentry *dentry;
     struct dfs_dentry *dentry;
-    struct dfs_vnode *vnode;
+    struct dfs_vnode *vnode = RT_NULL;
     int mntpoint_len = strlen(mnt->fullpath);
     int mntpoint_len = strlen(mnt->fullpath);
 
 
     if (rt_strncmp(mnt->fullpath, path, mntpoint_len) == 0)
     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)
             if (dentry)
             {
             {
                 DLOG(msg, "dentry", mnt->fs_ops->name, DLOG_MSG, "vnode=fs_ops->lookup(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)
                 if (vnode)
                 {
                 {
                     DLOG(msg, mnt->fs_ops->name, "dentry", DLOG_MSG_RET, "return vnode");
                     DLOG(msg, mnt->fs_ops->name, "dentry", DLOG_MSG_RET, "return vnode");

+ 190 - 53
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;
     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)
 void dfs_file_set_fpos(struct dfs_file *file, off_t fpos)
 {
 {
     if (file)
     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;
         file->fpos = fpos;
         rt_mutex_release(&file->pos_lock);
         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)
 struct dfs_dentry* dfs_file_follow_link(struct dfs_dentry *dentry)
 {
 {
     int ret = 0;
     int ret = 0;
+    struct dfs_dentry *tmp = dfs_dentry_ref(dentry);
 
 
     if (dentry && dentry->vnode && dentry->vnode->type == FT_SYMLINK)
     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
             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)
                 if (ret > 0)
                 {
                 {
                     struct dfs_mnt *mnt = NULL;
                     struct dfs_mnt *mnt = NULL;
 
 
                     if (buf[0] != '/')
                     if (buf[0] != '/')
                     {
                     {
-                        char *dir = dfs_dentry_pathname(dentry);
+                        char *dir = dfs_dentry_pathname(tmp);
 
 
                         /* is the relative directory */
                         /* is the relative directory */
                         if (dir)
                         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);
                         struct dfs_dentry *de = dfs_dentry_lookup(mnt, buf, 0);
 
 
                         /* release the old dentry */
                         /* release the old dentry */
-                        dfs_dentry_unref(dentry);
-                        dentry = de;
+                        dfs_dentry_unref(tmp);
+                        tmp = de;
                     }
                     }
                 }
                 }
                 else
                 else
                 {
                 {
                     break;
                     break;
                 }
                 }
-            } while (dentry && dentry->vnode->type == FT_SYMLINK);
+            } while (tmp && tmp->vnode->type == FT_SYMLINK);
         }
         }
 
 
         rt_free(buf);
         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)
                     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)
                     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)
                     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)
                     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 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;
     char *fullpath = RT_NULL;
     struct dfs_dentry *dentry = RT_NULL;
     struct dfs_dentry *dentry = RT_NULL;
     int fflags = dfs_fflags(oflags);
     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 */
                         /* follow symbol link */
                         target_dentry = dfs_file_follow_link(dentry);
                         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;
                                 mode &= ~S_IFMT;
                                 DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->create_vnode");
                                 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)
                                 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)
                     if (permission && file->fops->open)
                     {
                     {
                         DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fops->open(file)");
                         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)
                         if (ret < 0)
                         {
                         {
                             LOG_E("open %s failed in file system: %s", path, dentry->mnt->fs_ops->name);
                             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)
                 if (file->fops->truncate)
                 {
                 {
                     DLOG(msg, "dfs_file", dentry->mnt->fs_ops->name, DLOG_MSG, "fops->truncate(file, 0)");
                     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)
             if (ref_count == 1 && file->fops && file->fops->close)
             {
             {
                 DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->close(file)");
                 DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->close(file)");
+
                 ret = file->fops->close(file);
                 ret = file->fops->close(file);
 
 
                 if (ret == 0) /* close file sucessfully */
                 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)
         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);
             ret = rw_verify_area(file, &pos, len);
             if (ret > 0)
             if (ret > 0)
             {
             {
                 len = ret;
                 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)
         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);
             ret = rw_verify_area(file, &pos, len);
             if (ret > 0)
             if (ret > 0)
             {
             {
                 len = ret;
                 len = ret;
                 DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG,
                 DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG,
                     "dfs_file_write(fd, buf, %d)", len);
                     "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
     else
         return -EINVAL;
         return -EINVAL;
 
 
-    dfs_file_set_fpos(file, foffset);
-
     return foffset;
     return foffset;
 }
 }
 
 
 off_t dfs_file_lseek(struct dfs_file *file, off_t offset, int wherece)
 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)
                 if (mnt->fs_ops->stat)
                 {
                 {
                     DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
                     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 */
                 /* unref dentry */
@@ -770,7 +835,11 @@ int dfs_file_lstat(const char *path, struct stat *buf)
                 if (mnt->fs_ops->stat)
                 if (mnt->fs_ops->stat)
                 {
                 {
                     DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
                     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 */
                 /* unref dentry */
@@ -845,7 +914,11 @@ int dfs_file_setattr(const char *path, struct dfs_attr *attr)
                 if (mnt->fs_ops->setattr)
                 if (mnt->fs_ops->setattr)
                 {
                 {
                     DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->setattr(dentry, attr)");
                     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 */
                 /* unref dentry */
@@ -870,7 +943,14 @@ int dfs_file_ioctl(struct dfs_file *file, int cmd, void *args)
     {
     {
         if (file->fops && file->fops->ioctl)
         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
         else
         {
         {
@@ -953,7 +1033,14 @@ int dfs_file_fsync(struct dfs_file *file)
     {
     {
         if (file->fops->flush)
         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)
                         if (mnt->fs_ops->unlink)
                         {
                         {
-                            ret = mnt->fs_ops->unlink(dentry);
+                            if (dfs_is_mounted(mnt) == 0)
+                            {
+                                ret = mnt->fs_ops->unlink(dentry);
+                            }
                         }
                         }
                     }
                     }
                     else
                     else
@@ -1096,7 +1186,10 @@ int dfs_file_link(const char *oldname, const char *newname)
         {
         {
             if (mnt->fs_ops->link)
             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
                                 else
                                 {
                                 {
@@ -1280,7 +1376,10 @@ int dfs_file_readlink(const char *path, char *buf, int bufsize)
             {
             {
                 if (mnt->fs_ops->readlink)
                 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
                 else
                 {
                 {
@@ -1361,7 +1460,10 @@ int dfs_file_rename(const char *old_file, const char *new_file)
         {
         {
             if (mnt->fs_ops->rename)
             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)
         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
         else
         {
         {
@@ -1413,7 +1522,14 @@ int dfs_file_flush(struct dfs_file *file)
     {
     {
         if (file->fops->flush)
         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
         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)
             if (file->fops && file->fops->getdents)
             {
             {
                 DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "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};
                     struct stat stat = {0};
                     DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
                     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))
                     if (ret == RT_EOK && S_ISDIR(stat.st_mode))
                     {
                     {
                         ret = RT_EOK;
                         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)
         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)
             if (ret != 0)
             {
             {
                 ret = ret > 0 ? ret : -ret;
                 ret = ret > 0 ? ret : -ret;

+ 33 - 18
components/dfs/dfs_v2/src/dfs_fs.c

@@ -43,6 +43,11 @@ static struct dfs_filesystem_type **_find_filesystem(const char *name)
     return type;
     return type;
 }
 }
 
 
+struct dfs_filesystem_type *dfs_filesystems(void)
+{
+    return file_systems;
+}
+
 int dfs_register(struct dfs_filesystem_type *fs)
 int dfs_register(struct dfs_filesystem_type *fs)
 {
 {
     int ret = 0;
     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");
                             DLOG(msg, type->fs_ops->name, "dfs", DLOG_MSG_RET, "mount OK, ret root_dentry");
 
 
                             mnt_child = mnt_parent;
                             mnt_child = mnt_parent;
+                            mnt_child->flags |= MNT_IS_MOUNTED;
+
                             DLOG(note_right, "mnt", "mount sucessfully");
                             DLOG(note_right, "mnt", "mount sucessfully");
                             DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_insert(, mnt_child)");
                             DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_insert(, mnt_child)");
                             dfs_mnt_insert(RT_NULL, mnt_child);
                             dfs_mnt_insert(RT_NULL, mnt_child);
@@ -202,7 +209,7 @@ int dfs_mount(const char *device_name,
                     ret = -1;
                     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);
                 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);
                 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);
                             ret = mnt_child->fs_ops->mount(mnt_child, rwflag, data);
                             if (ret == RT_EOK)
                             if (ret == RT_EOK)
                             {
                             {
+                                mnt_child->flags |= MNT_IS_MOUNTED;
+
                                 LOG_D("mount %s sucessfully", fullpath);
                                 LOG_D("mount %s sucessfully", fullpath);
                                 DLOG(msg, mnt_child->fs_ops->name, "dfs", DLOG_MSG_RET, "mount OK");
                                 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;
     return ret;
 }
 }
 
 
-int dfs_umount(const char *specialfile)
+int dfs_umount(const char *specialfile, int flags)
 {
 {
     int ret = -RT_ERROR;
     int ret = -RT_ERROR;
     char *fullpath = RT_NULL;
     char *fullpath = RT_NULL;
@@ -301,22 +310,13 @@ int dfs_umount(const char *specialfile)
             if (strcmp(mnt->fullpath, fullpath) == 0)
             if (strcmp(mnt->fullpath, fullpath) == 0)
             {
             {
                 /* is the mount point */
                 /* 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
                 else
                 {
                 {
@@ -345,7 +345,19 @@ int dfs_umount(const char *specialfile)
 /* for compatibility */
 /* for compatibility */
 int dfs_unmount(const char *specialfile)
 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)
 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)
         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);
+            }
         }
         }
     }
     }
 
 

+ 37 - 25
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 */
                 /* it's root mnt */
                 mnt = child;
                 mnt = child;
+                mnt->flags |= MNT_IS_LOCKED;
 
 
                 /* ref to gobal root */
                 /* ref to gobal root */
                 if (_root_mnt)
                 if (_root_mnt)
@@ -194,22 +195,34 @@ int dfs_mnt_unref(struct dfs_mnt* mnt)
 
 
     if (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();
             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)
 int dfs_mnt_destroy(struct dfs_mnt* mnt)
@@ -218,33 +231,21 @@ int dfs_mnt_destroy(struct dfs_mnt* mnt)
 
 
     if (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 */
             /* remote it from mnt list */
             if (mnt->flags & MNT_IS_ADDLIST)
             if (mnt->flags & MNT_IS_ADDLIST)
             {
             {
                 dfs_mnt_remove(mnt);
                 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)
 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;
     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;
+}

+ 108 - 4
components/dfs/dfs_v2/src/dfs_posix.c

@@ -412,7 +412,7 @@ RTM_EXPORT(stat);
  */
  */
 int fstat(int fildes, struct stat *buf)
 int fstat(int fildes, struct stat *buf)
 {
 {
-    int ret = 0;
+    int ret = -1;
     struct dfs_file *file;
     struct dfs_file *file;
 
 
     if (buf == NULL)
     if (buf == NULL)
@@ -430,7 +430,10 @@ int fstat(int fildes, struct stat *buf)
         return -1;
         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;
     return ret;
 }
 }
@@ -624,7 +627,7 @@ RTM_EXPORT(statfs);
  */
  */
 int fstatfs(int fildes, struct statfs *buf)
 int fstatfs(int fildes, struct statfs *buf)
 {
 {
-    int ret = 0;
+    int ret = -1;
     struct dfs_file *file;
     struct dfs_file *file;
 
 
     if (buf == NULL)
     if (buf == NULL)
@@ -642,7 +645,10 @@ int fstatfs(int fildes, struct statfs *buf)
         return -1;
         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;
     return ret;
 }
 }
@@ -1223,4 +1229,102 @@ char *getcwd(char *buf, size_t size)
 }
 }
 RTM_EXPORT(getcwd);
 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);
+
 /**@}*/
 /**@}*/