Browse Source

[smart][dfs v2] add cromfs (#7994)

Co-authored-by: xyz <xyz@rtt.com>
XYZ 1 năm trước cách đây
mục cha
commit
3602f89121
2 tập tin đã thay đổi với 143 bổ sung73 xóa
  1. 3 1
      components/dfs/Kconfig
  2. 140 72
      components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.c

+ 3 - 1
components/dfs/Kconfig

@@ -158,17 +158,19 @@ endif
     config RT_USING_DFS_ROMFS
         bool "Enable ReadOnly file system on flash"
         default n
-if RT_USING_DFS_V1
+
     config RT_USING_DFS_CROMFS
         bool "Enable ReadOnly compressed file system on flash"
         default n
         # select PKG_USING_ZLIB
 
+if RT_USING_DFS_V1
     config RT_USING_DFS_RAMFS
         bool "Enable RAM file system"
         select RT_USING_MEMHEAP
         default n
 endif
+
     config RT_USING_DFS_TMPFS
         bool "Enable TMP file system"
         default n

+ 140 - 72
components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.c

@@ -12,6 +12,8 @@
 #include <dfs.h>
 #include <dfs_fs.h>
 #include <dfs_file.h>
+#include <dfs_dentry.h>
+#include <dfs_mnt.h>
 
 #include "dfs_cromfs.h"
 
@@ -94,6 +96,7 @@ typedef struct st_cromfs_info
     struct cromfs_avl_struct *cromfs_avl_root;
     rt_list_t cromfs_dirent_cache_head;
     int cromfs_dirent_cache_nr;
+    const void *data;
 } cromfs_info;
 
 typedef struct
@@ -339,6 +342,20 @@ static uint32_t cromfs_noblk_read_bytes(cromfs_info *ci, uint32_t pos, void *buf
     }
 }
 
+static uint32_t cromfs_data_read_bytes(cromfs_info *ci, uint32_t pos, void *buf, uint32_t size)
+{
+    uint32_t ret = 0;
+    uint8_t *data = (uint8_t *)ci->data;
+
+    if (data)
+    {
+        memcpy(buf, data + pos, size);
+        ret = size;
+    }
+
+    return ret;
+}
+
 static uint32_t cromfs_blk_read_bytes(cromfs_info *ci, uint32_t pos, void *buf, uint32_t size)
 {
     uint32_t ret = 0;
@@ -481,7 +498,7 @@ static void cromfs_dirent_cache_destroy(cromfs_info *ci)
 
 /**********************************/
 
-static int dfs_cromfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
+static int dfs_cromfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data)
 {
     struct rt_device_blk_geometry geometry;
     uint32_t len = 0;
@@ -494,17 +511,38 @@ static int dfs_cromfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, con
     }
 
     memset(ci, 0, sizeof *ci);
-    ci->device = fs->dev_id;
+    ci->device = mnt->dev_id;
     ci->partition_size = UINT32_MAX;
-    if (ci->device->type == RT_Device_Class_Block)
+
+    if (ci->device)
+    {
+        rt_err_t ret = rt_device_open(ci->device, RT_DEVICE_OFLAG_RDONLY);
+        if (ret != RT_EOK)
+        {
+            free(ci);
+            return ret;
+        }
+
+        if (ci->device->type == RT_Device_Class_Block)
+        {
+            rt_device_control(ci->device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
+            ci->bytes_per_sector = geometry.bytes_per_sector;
+            ci->read_bytes = cromfs_blk_read_bytes;
+        }
+        else
+        {
+            ci->read_bytes = cromfs_noblk_read_bytes;
+        }
+    }
+    else if (data)
     {
-        rt_device_control(ci->device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
-        ci->bytes_per_sector = geometry.bytes_per_sector;
-        ci->read_bytes = cromfs_blk_read_bytes;
+        ci->data = data;
+        ci->read_bytes = cromfs_data_read_bytes;
     }
     else
     {
-        ci->read_bytes = cromfs_noblk_read_bytes;
+        free(ci);
+        return -RT_EIO;
     }
 
     len = cromfs_read_bytes(ci, 0, &ci->part_info, sizeof ci->part_info);
@@ -515,7 +553,7 @@ static int dfs_cromfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, con
         return -RT_ERROR;
     }
     ci->partition_size = ci->part_info.partition_size;
-    fs->data = ci;
+    mnt->data = ci;
 
     rt_mutex_init(&ci->lock, "crom", RT_IPC_FLAG_FIFO);
     ci->cromfs_avl_root = NULL;
@@ -526,12 +564,12 @@ static int dfs_cromfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, con
     return RT_EOK;
 }
 
-static int dfs_cromfs_unmount(struct dfs_filesystem *fs)
+static int dfs_cromfs_unmount(struct dfs_mnt *mnt)
 {
     rt_err_t result = RT_EOK;
     cromfs_info *ci = NULL;
 
-    ci = (cromfs_info *)fs->data;
+    ci = (cromfs_info *)mnt->data;
 
     result =  rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
     if (result != RT_EOK)
@@ -557,6 +595,11 @@ static int dfs_cromfs_unmount(struct dfs_filesystem *fs)
         free(fi);
     }
 
+    if (ci->device)
+    {
+        rt_device_close(ci->device);
+    }
+
     rt_mutex_detach(&ci->lock);
 
     free(ci);
@@ -564,11 +607,6 @@ static int dfs_cromfs_unmount(struct dfs_filesystem *fs)
     return RT_EOK;
 }
 
-static int dfs_cromfs_ioctl(struct dfs_file *file, int cmd, void *args)
-{
-    return -EIO;
-}
-
 static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, uint32_t *size, uint32_t *osize)
 {
     uint32_t cur_size = 0, cur_pos = 0, cur_osize = 0;
@@ -648,7 +686,7 @@ static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, ui
             }
             name_block = (di_iter->dirent.name_size + CROMFS_ALIGN_SIZE_MASK) >> CROMFS_ALIGN_SIZE_BIT;
             di_iter += (1 + name_block);
-            if ((uint32_t)di_iter - (uint32_t)di_mem >= cur_size)
+            if ((uint32_t)(intptr_t)di_iter - (uint32_t)(intptr_t)di_mem >= cur_size)
             {
                 break;
             }
@@ -664,7 +702,7 @@ static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, ui
     return cur_pos;
 }
 
-static uint32_t dfs_cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, uint32_t *size, uint32_t *osize)
+static uint32_t __dfs_cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, uint32_t *size, uint32_t *osize)
 {
     rt_err_t result = RT_EOK;
     uint32_t ret = 0;
@@ -718,25 +756,23 @@ end:
     return ret;
 }
 
-static int dfs_cromfs_read(struct dfs_file *file, void *buf, size_t count)
+static ssize_t dfs_cromfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
 {
     rt_err_t result = RT_EOK;
-    struct dfs_filesystem *fs = NULL;
     file_info *fi = NULL;
     cromfs_info *ci = NULL;
     uint32_t length = 0;
 
-    fs = (struct dfs_filesystem *)file->vnode->fs;
-    ci = (cromfs_info *)fs->data;
+    ci = (cromfs_info *)file->dentry->mnt->data;
     fi = (file_info *)file->vnode->data;
 
-    if (count < file->vnode->size - file->pos)
+    if (count < file->vnode->size - *pos)
     {
         length = count;
     }
     else
     {
-        length = file->vnode->size - file->pos;
+        length = file->vnode->size - *pos;
     }
 
     if (length > 0)
@@ -759,7 +795,7 @@ static int dfs_cromfs_read(struct dfs_file *file, void *buf, size_t count)
                 return 0;
             }
 
-            memcpy(buf, fi->buff + file->pos, length);
+            memcpy(buf, fi->buff + *pos, length);
         }
         else
         {
@@ -773,7 +809,7 @@ static int dfs_cromfs_read(struct dfs_file *file, void *buf, size_t count)
             di_mem = cromfs_dirent_cache_get(ci, fi->partition_pos, fi->size);
             if (di_mem)
             {
-                memcpy(buf, (char*)di_mem + file->pos, length);
+                memcpy(buf, (char*)di_mem + *pos, length);
             }
             rt_mutex_release(&ci->lock);
             if (!di_mem)
@@ -782,22 +818,12 @@ static int dfs_cromfs_read(struct dfs_file *file, void *buf, size_t count)
             }
         }
         /* update file current position */
-        file->pos += length;
+        *pos += length;
     }
 
     return length;
 }
 
-static int dfs_cromfs_lseek(struct dfs_file *file, off_t offset)
-{
-    if (offset <= file->vnode->size)
-    {
-        file->pos = offset;
-        return file->pos;
-    }
-    return -EIO;
-}
-
 static file_info *get_file_info(cromfs_info *ci, uint32_t partition_pos, int inc_ref)
 {
     struct cromfs_avl_struct* node = cromfs_avl_find(partition_pos, ci->cromfs_avl_root);
@@ -893,7 +919,6 @@ static void deref_file_info(cromfs_info *ci, uint32_t partition_pos)
 static int dfs_cromfs_close(struct dfs_file *file)
 {
     file_info *fi = NULL;
-    struct dfs_filesystem *fs = NULL;
     cromfs_info *ci = NULL;
     rt_err_t result = 0;
 
@@ -904,8 +929,7 @@ static int dfs_cromfs_close(struct dfs_file *file)
     }
 
     fi = (file_info *)file->vnode->data;
-    fs = (struct dfs_filesystem *)file->vnode->fs;
-    ci = (cromfs_info *)fs->data;
+    ci = (cromfs_info *)file->dentry->mnt->data;
 
     result =  rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
     if (result != RT_EOK)
@@ -921,7 +945,6 @@ static int dfs_cromfs_close(struct dfs_file *file)
 static int dfs_cromfs_open(struct dfs_file *file)
 {
     int ret = 0;
-    struct dfs_filesystem *fs = NULL;
     file_info *fi = NULL;
     cromfs_info *ci = NULL;
     uint32_t file_pos = 0;
@@ -942,14 +965,13 @@ static int dfs_cromfs_open(struct dfs_file *file)
         {
             return -ENOENT;
         }
-        file->pos = 0;
+        file->fpos = 0;
         return 0;
     }
 
-    fs = file->vnode->fs;
-    ci = (cromfs_info *)fs->data;
+    ci = (cromfs_info *)file->dentry->mnt->data;
 
-    file_pos = dfs_cromfs_lookup(ci, file->vnode->path, &is_dir, &size, &osize);
+    file_pos = __dfs_cromfs_lookup(ci, file->dentry->pathname, &is_dir, &size, &osize);
     if (file_pos == CROMFS_POS_ERROR)
     {
         ret = -ENOENT;
@@ -1005,23 +1027,23 @@ static int dfs_cromfs_open(struct dfs_file *file)
     {
         file->vnode->size = osize;
     }
-    file->pos = 0;
+    file->fpos = 0;
 
     ret = RT_EOK;
 end:
     return ret;
 }
 
-static int dfs_cromfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
+static int dfs_cromfs_stat(struct dfs_dentry *dentry, struct stat *st)
 {
     uint32_t size = 0, osize = 0;
     int is_dir = 0;
     cromfs_info *ci = NULL;
     uint32_t file_pos = 0;
 
-    ci = (cromfs_info *)fs->data;
+    ci = (cromfs_info *)dentry->mnt->data;
 
-    file_pos = dfs_cromfs_lookup(ci, path, &is_dir, &size, &osize);
+    file_pos = __dfs_cromfs_lookup(ci, dentry->pathname, &is_dir, &size, &osize);
     if (file_pos == CROMFS_POS_ERROR)
     {
         return -ENOENT;
@@ -1100,12 +1122,12 @@ static int dfs_cromfs_getdents(struct dfs_file *file, struct dirent *dirp, uint3
         return -EINVAL;
     }
 
-    for (index = 0; index < count && file->pos < file->vnode->size; index++)
+    for (index = 0; index < count && file->fpos < file->vnode->size; index++)
     {
         uint32_t name_size = 0;
 
         d = dirp + index;
-        sub_dirent = &dirent[file->pos >> CROMFS_ALIGN_SIZE_BIT];
+        sub_dirent = &dirent[file->fpos >> CROMFS_ALIGN_SIZE_BIT];
         name = sub_dirent->dirent.name;
 
         /* fill dirent */
@@ -1125,7 +1147,7 @@ static int dfs_cromfs_getdents(struct dfs_file *file, struct dirent *dirp, uint3
 
         name_size = (sub_dirent->dirent.name_size + CROMFS_ALIGN_SIZE_MASK) & ~CROMFS_ALIGN_SIZE_MASK;
         /* move to next position */
-        file->pos += (name_size + sizeof *sub_dirent);
+        file->fpos += (name_size + sizeof *sub_dirent);
     }
 
     free(dirent);
@@ -1133,32 +1155,78 @@ static int dfs_cromfs_getdents(struct dfs_file *file, struct dirent *dirp, uint3
     return index * sizeof(struct dirent);
 }
 
+static struct dfs_vnode *dfs_cromfs_lookup (struct dfs_dentry *dentry)
+{
+    struct dfs_vnode *vnode = RT_NULL;
+    cromfs_info *ci = NULL;
+
+    RT_ASSERT(dentry != RT_NULL);
+    RT_ASSERT(dentry->mnt != RT_NULL);
+
+    ci = (cromfs_info *)dentry->mnt->data;
+    if (ci)
+    {
+        uint32_t size = 0, osize = 0;
+        int is_dir = 0;
+        uint32_t file_pos = __dfs_cromfs_lookup(ci, dentry->pathname, &is_dir, &size, &osize);
+
+        if (file_pos != CROMFS_POS_ERROR)
+        {
+            vnode = dfs_vnode_create();
+            if (vnode)
+            {
+                vnode->nlink = 1;
+
+                if (is_dir)
+                {
+                    vnode->mode = S_IFDIR | (0555);
+                    vnode->type = FT_DIRECTORY;
+                    vnode->size = size;
+                }
+                else
+                {
+                    vnode->mode = S_IFREG | (0555);
+                    vnode->type = FT_REGULAR;
+                    vnode->size = osize;
+                }
+
+                vnode->mnt = dentry->mnt;
+            }
+        }
+    }
+
+    return vnode;
+}
+
+static int dfs_cromfs_free_vnode(struct dfs_vnode *vnode)
+{
+    return 0;
+}
+
 static const struct dfs_file_ops _crom_fops =
 {
-    dfs_cromfs_open,
-    dfs_cromfs_close,
-    dfs_cromfs_ioctl,
-    dfs_cromfs_read,
-    NULL,
-    NULL,
-    dfs_cromfs_lseek,
-    dfs_cromfs_getdents,
+    .open           = dfs_cromfs_open,
+    .close          = dfs_cromfs_close,
+    .lseek          = generic_dfs_lseek,
+    .read           = dfs_cromfs_read,
+    .getdents       = dfs_cromfs_getdents,
+};
+
+static const struct dfs_filesystem_ops _cromfs_ops =
+{
+    .name           = "crom",
+    .flags          = 0,
+    .default_fops   = &_crom_fops,
+    .mount          = dfs_cromfs_mount,
+    .umount         = dfs_cromfs_unmount,
+    .stat           = dfs_cromfs_stat,
+    .lookup         = dfs_cromfs_lookup,
+    .free_vnode     = dfs_cromfs_free_vnode
 };
 
-static const struct dfs_filesystem_ops _cromfs =
+static struct dfs_filesystem_type _cromfs =
 {
-    "crom",
-    DFS_FS_FLAG_DEFAULT,
-    &_crom_fops,
-
-    dfs_cromfs_mount,
-    dfs_cromfs_unmount,
-    NULL,
-    NULL,
-
-    NULL,
-    dfs_cromfs_stat,
-    NULL,
+    .fs_ops           = &_cromfs_ops,
 };
 
 int dfs_cromfs_init(void)