first
This commit is contained in:
11
rt-thread/components/dfs/dfs_v2/filesystems/romfs/SConscript
Normal file
11
rt-thread/components/dfs/dfs_v2/filesystems/romfs/SConscript
Normal file
@@ -0,0 +1,11 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS','RT_USING_DFS_ROMFS'], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
397
rt-thread/components/dfs/dfs_v2/filesystems/romfs/dfs_romfs.c
Normal file
397
rt-thread/components/dfs/dfs_v2/filesystems/romfs/dfs_romfs.c
Normal file
@@ -0,0 +1,397 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <dfs.h>
|
||||
#include <dfs_fs.h>
|
||||
#include <dfs_dentry.h>
|
||||
#include <dfs_file.h>
|
||||
#include <dfs_mnt.h>
|
||||
|
||||
#include "dfs_romfs.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <rtdbg.h>
|
||||
|
||||
static const struct dfs_file_ops _rom_fops;
|
||||
|
||||
static const mode_t romfs_modemap[] =
|
||||
{
|
||||
S_IFREG | 0644, /* regular file */
|
||||
S_IFDIR | 0644, /* directory */
|
||||
0, /* hard link */
|
||||
S_IFLNK | 0777, /* symlink */
|
||||
S_IFBLK | 0600, /* blockdev */
|
||||
S_IFCHR | 0600, /* chardev */
|
||||
S_IFSOCK | 0644, /* socket */
|
||||
S_IFIFO | 0644 /* FIFO */
|
||||
};
|
||||
|
||||
static int dfs_romfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data)
|
||||
{
|
||||
struct romfs_dirent *root_dirent;
|
||||
|
||||
if (data == NULL)
|
||||
return -1;
|
||||
|
||||
root_dirent = (struct romfs_dirent *)data;
|
||||
mnt->data = root_dirent;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dfs_romfs_umount(struct dfs_mnt *fs)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int dfs_romfs_ioctl(struct dfs_file *file, int cmd, void *args)
|
||||
{
|
||||
int ret = RT_EOK;
|
||||
struct romfs_dirent *dirent;
|
||||
|
||||
dirent = (struct romfs_dirent *)file->data;
|
||||
RT_ASSERT(dirent != NULL);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_FIOGETADDR:
|
||||
{
|
||||
*(rt_ubase_t*)args = (rt_ubase_t)dirent->data;
|
||||
break;
|
||||
}
|
||||
case RT_FIOFTRUNCATE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = -RT_EINVAL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
rt_inline int check_dirent(struct romfs_dirent *dirent)
|
||||
{
|
||||
if (dirent == NULL
|
||||
||(dirent->type != ROMFS_DIRENT_FILE && dirent->type != ROMFS_DIRENT_DIR)
|
||||
|| dirent->size == ~0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct romfs_dirent *__dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size)
|
||||
{
|
||||
rt_size_t index, found;
|
||||
const char *subpath, *subpath_end;
|
||||
struct romfs_dirent *dirent;
|
||||
rt_size_t dirent_size;
|
||||
|
||||
/* Check the root_dirent. */
|
||||
if (check_dirent(root_dirent) != 0)
|
||||
return NULL;
|
||||
|
||||
if (path[0] == '/' && path[1] == '\0')
|
||||
{
|
||||
*size = root_dirent->size;
|
||||
return root_dirent;
|
||||
}
|
||||
|
||||
/* goto root directy entries */
|
||||
dirent = (struct romfs_dirent *)root_dirent->data;
|
||||
dirent_size = root_dirent->size;
|
||||
|
||||
/* get the end position of this subpath */
|
||||
subpath_end = path;
|
||||
/* skip /// */
|
||||
while (*subpath_end && *subpath_end == '/')
|
||||
subpath_end ++;
|
||||
subpath = subpath_end;
|
||||
while ((*subpath_end != '/') && *subpath_end)
|
||||
subpath_end ++;
|
||||
|
||||
while (dirent != NULL)
|
||||
{
|
||||
found = 0;
|
||||
|
||||
/* search in folder */
|
||||
for (index = 0; index < dirent_size; index ++)
|
||||
{
|
||||
if (check_dirent(&dirent[index]) != 0)
|
||||
return NULL;
|
||||
if (rt_strlen(dirent[index].name) == (subpath_end - subpath) &&
|
||||
rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
|
||||
{
|
||||
dirent_size = dirent[index].size;
|
||||
|
||||
/* skip /// */
|
||||
while (*subpath_end && *subpath_end == '/')
|
||||
subpath_end ++;
|
||||
subpath = subpath_end;
|
||||
while ((*subpath_end != '/') && *subpath_end)
|
||||
subpath_end ++;
|
||||
|
||||
if (!(*subpath))
|
||||
{
|
||||
*size = dirent_size;
|
||||
return &dirent[index];
|
||||
}
|
||||
|
||||
if (dirent[index].type == ROMFS_DIRENT_DIR)
|
||||
{
|
||||
/* enter directory */
|
||||
dirent = (struct romfs_dirent *)dirent[index].data;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* return file dirent */
|
||||
return &dirent[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
break; /* not found */
|
||||
}
|
||||
|
||||
/* not found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct dfs_vnode *dfs_romfs_lookup (struct dfs_dentry *dentry)
|
||||
{
|
||||
rt_size_t size;
|
||||
struct dfs_vnode *vnode = RT_NULL;
|
||||
struct romfs_dirent *root_dirent = RT_NULL, *dirent = RT_NULL;
|
||||
|
||||
RT_ASSERT(dentry != RT_NULL);
|
||||
RT_ASSERT(dentry->mnt != RT_NULL);
|
||||
|
||||
root_dirent = (struct romfs_dirent *)dentry->mnt->data;
|
||||
if (check_dirent(root_dirent) == 0)
|
||||
{
|
||||
/* create a vnode */
|
||||
DLOG(msg, "rom", "vnode", DLOG_MSG, "dfs_vnode_create()");
|
||||
vnode = dfs_vnode_create();
|
||||
if (vnode)
|
||||
{
|
||||
dirent = __dfs_romfs_lookup(root_dirent, dentry->pathname, &size);
|
||||
if (dirent)
|
||||
{
|
||||
vnode->nlink = 1;
|
||||
vnode->size = dirent->size;
|
||||
if (dirent->type == ROMFS_DIRENT_DIR)
|
||||
{
|
||||
vnode->mode = romfs_modemap[ROMFS_DIRENT_DIR] | (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vnode->type = FT_DIRECTORY;
|
||||
}
|
||||
else if (dirent->type == ROMFS_DIRENT_FILE)
|
||||
{
|
||||
vnode->mode = romfs_modemap[ROMFS_DIRENT_FILE] | (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vnode->type = FT_REGULAR;
|
||||
}
|
||||
|
||||
DLOG(msg, "rom", "rom", DLOG_MSG, "vnode->data = dirent");
|
||||
vnode->data = dirent;
|
||||
vnode->mnt = dentry->mnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no-entry */
|
||||
DLOG(msg, "rom", "vnode", DLOG_MSG, "dfs_vnode_destroy, no-dentry");
|
||||
dfs_vnode_destroy(vnode);
|
||||
vnode = RT_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vnode;
|
||||
}
|
||||
|
||||
static int dfs_romfs_free_vnode(struct dfs_vnode *vnode)
|
||||
{
|
||||
/* nothing to be freed */
|
||||
if (vnode->ref_count <= 1)
|
||||
{
|
||||
vnode->data = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t dfs_romfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
|
||||
{
|
||||
rt_size_t length;
|
||||
struct romfs_dirent *dirent;
|
||||
|
||||
dirent = (struct romfs_dirent *)file->vnode->data;
|
||||
RT_ASSERT(dirent != NULL);
|
||||
|
||||
if (check_dirent(dirent) != 0)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (count < file->vnode->size - *pos)
|
||||
length = count;
|
||||
else
|
||||
length = file->vnode->size - *pos;
|
||||
|
||||
if (length > 0)
|
||||
memcpy(buf, &(dirent->data[*pos]), length);
|
||||
|
||||
/* update file current position */
|
||||
*pos += length;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static int dfs_romfs_close(struct dfs_file *file)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int dfs_romfs_open(struct dfs_file *file)
|
||||
{
|
||||
rt_size_t size;
|
||||
struct romfs_dirent *dirent;
|
||||
struct romfs_dirent *root_dirent;
|
||||
struct dfs_mnt *mnt;
|
||||
|
||||
if (file->flags & (O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_RDWR))
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mnt = file->dentry->mnt;
|
||||
RT_ASSERT(mnt != RT_NULL);
|
||||
|
||||
root_dirent = (struct romfs_dirent *)mnt->data;
|
||||
if (check_dirent(root_dirent) != 0)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* get rom dirent */
|
||||
dirent = __dfs_romfs_lookup(root_dirent, file->dentry->pathname, &size);
|
||||
if (dirent == NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
file->data = dirent;
|
||||
file->fops = &_rom_fops;
|
||||
file->fpos = 0;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int dfs_romfs_stat(struct dfs_dentry *dentry, struct stat *st)
|
||||
{
|
||||
rt_err_t ret = dfs_file_lock();
|
||||
if (ret == RT_EOK)
|
||||
{
|
||||
st->st_dev = 0;
|
||||
st->st_mode = dentry->vnode->mode;
|
||||
st->st_size = dentry->vnode->size;
|
||||
st->st_nlink = dentry->vnode->nlink;
|
||||
st->st_mtime = 0;
|
||||
|
||||
dfs_file_unlock();
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int dfs_romfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
|
||||
{
|
||||
rt_size_t index;
|
||||
const char *name;
|
||||
struct dirent *d;
|
||||
struct romfs_dirent *dirent, *sub_dirent;
|
||||
|
||||
dirent = (struct romfs_dirent *)file->vnode->data;
|
||||
if (check_dirent(dirent) != 0)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR);
|
||||
|
||||
/* enter directory */
|
||||
dirent = (struct romfs_dirent *)dirent->data;
|
||||
|
||||
/* make integer count */
|
||||
count = (count / sizeof(struct dirent));
|
||||
if (count == 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
for (index = 0; index < count && file->fpos < file->vnode->size; index++)
|
||||
{
|
||||
d = dirp + index;
|
||||
|
||||
sub_dirent = &dirent[file->fpos];
|
||||
name = sub_dirent->name;
|
||||
|
||||
/* fill dirent */
|
||||
if (sub_dirent->type == ROMFS_DIRENT_DIR)
|
||||
d->d_type = DT_DIR;
|
||||
else
|
||||
d->d_type = DT_REG;
|
||||
|
||||
d->d_namlen = rt_strlen(name);
|
||||
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||
rt_strncpy(d->d_name, name, DIRENT_NAME_MAX);
|
||||
|
||||
/* move to next position */
|
||||
++ file->fpos;
|
||||
}
|
||||
|
||||
return index * sizeof(struct dirent);
|
||||
}
|
||||
|
||||
static const struct dfs_file_ops _rom_fops =
|
||||
{
|
||||
.open = dfs_romfs_open,
|
||||
.close = dfs_romfs_close,
|
||||
.lseek = generic_dfs_lseek,
|
||||
.read = dfs_romfs_read,
|
||||
.getdents = dfs_romfs_getdents,
|
||||
};
|
||||
|
||||
static const struct dfs_filesystem_ops _romfs_ops =
|
||||
{
|
||||
.name ="rom",
|
||||
.flags = 0,
|
||||
.default_fops = &_rom_fops,
|
||||
.mount = dfs_romfs_mount,
|
||||
.umount = dfs_romfs_umount,
|
||||
.stat = dfs_romfs_stat,
|
||||
.lookup = dfs_romfs_lookup,
|
||||
.free_vnode = dfs_romfs_free_vnode
|
||||
};
|
||||
|
||||
static struct dfs_filesystem_type _romfs =
|
||||
{
|
||||
.fs_ops = &_romfs_ops,
|
||||
};
|
||||
|
||||
int dfs_romfs_init(void)
|
||||
{
|
||||
/* register rom file system */
|
||||
dfs_register(&_romfs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_COMPONENT_EXPORT(dfs_romfs_init);
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019/01/13 Bernard code cleanup
|
||||
*/
|
||||
|
||||
#ifndef __DFS_ROMFS_H__
|
||||
#define __DFS_ROMFS_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#define ROMFS_DIRENT_FILE 0x00
|
||||
#define ROMFS_DIRENT_DIR 0x01
|
||||
|
||||
struct romfs_dirent
|
||||
{
|
||||
rt_uint32_t type; /* dirent type */
|
||||
|
||||
const char *name; /* dirent name */
|
||||
const rt_uint8_t *data; /* file date ptr */
|
||||
rt_size_t size; /* file size */
|
||||
};
|
||||
|
||||
int dfs_romfs_init(void);
|
||||
extern const struct romfs_dirent romfs_root;
|
||||
|
||||
#endif
|
42
rt-thread/components/dfs/dfs_v2/filesystems/romfs/romfs.c
Normal file
42
rt-thread/components/dfs/dfs_v2/filesystems/romfs/romfs.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <dfs_romfs.h>
|
||||
|
||||
static const unsigned char _dummy_dummy_txt[] =
|
||||
{
|
||||
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x21, 0x0d, 0x0a,
|
||||
};
|
||||
|
||||
static const struct romfs_dirent _dummy[] =
|
||||
{
|
||||
{ROMFS_DIRENT_FILE, "dummy.txt", _dummy_dummy_txt, sizeof(_dummy_dummy_txt)},
|
||||
};
|
||||
|
||||
static const unsigned char _dummy_txt[] =
|
||||
{
|
||||
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x21, 0x0d, 0x0a,
|
||||
};
|
||||
|
||||
rt_weak const struct romfs_dirent _root_dirent[] =
|
||||
{
|
||||
{ROMFS_DIRENT_DIR, "dev", RT_NULL, 0},
|
||||
{ROMFS_DIRENT_DIR, "mnt", RT_NULL, 0},
|
||||
{ROMFS_DIRENT_DIR, "proc", RT_NULL, 0},
|
||||
{ROMFS_DIRENT_DIR, "etc", RT_NULL, 0},
|
||||
{ROMFS_DIRENT_DIR, "bin", RT_NULL, 0},
|
||||
{ROMFS_DIRENT_DIR, "dummy", (rt_uint8_t *)_dummy, sizeof(_dummy) / sizeof(_dummy[0])},
|
||||
{ROMFS_DIRENT_FILE, "dummy.txt", _dummy_txt, sizeof(_dummy_txt)},
|
||||
};
|
||||
|
||||
rt_weak const struct romfs_dirent romfs_root =
|
||||
{
|
||||
ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_root_dirent, sizeof(_root_dirent) / sizeof(_root_dirent[0])
|
||||
};
|
Reference in New Issue
Block a user