123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- #include "devfs.h"
- #include "internal.h"
- #include <filesystem/VFS/VFS.h>
- #include <common/glib.h>
- #include <common/string.h>
- #include <mm/slab.h>
- struct vfs_super_block_operations_t devfs_sb_ops;
- struct vfs_dir_entry_operations_t devfs_dentry_ops;
- struct vfs_file_operations_t devfs_file_ops;
- struct vfs_inode_operations_t devfs_inode_ops;
- struct vfs_dir_entry_t *devfs_root_dentry; // 根结点的dentry
- struct vfs_superblock_t devfs_sb = {0};
- const char __devfs_mount_path[] = "/dev";
- /**
- * @brief 创建devfs的super block
- *
- * @param blk 未使用(devfs为伪文件系统,不需要物理设备)
- * @return struct vfs_superblock_t*
- */
- struct vfs_superblock_t *devfs_read_superblock(struct block_device *blk)
- {
- devfs_sb.blk_device = NULL;
- devfs_sb.root = devfs_root_dentry;
- devfs_sb.sb_ops = &devfs_sb_ops;
- devfs_sb.dir_ops = &devfs_dentry_ops;
- // todo: 为devfs增加私有信息
- devfs_sb.private_sb_info = NULL;
- kdebug("devfs read superblock done");
- return &devfs_sb;
- }
- static void devfs_write_superblock(struct vfs_superblock_t *sb) {return ; }
- static void devfs_put_superblock(struct vfs_superblock_t *sb) {return ; }
- static void devfs_write_inode(struct vfs_index_node_t *inode) {return ; }
- struct vfs_super_block_operations_t devfs_sb_ops =
- {
- .write_superblock = &devfs_write_superblock,
- .put_superblock = &devfs_put_superblock,
- .write_inode = &devfs_write_inode,
- };
- static long devfs_compare(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename) {return 0; }
- static long devfs_hash(struct vfs_dir_entry_t *dEntry, char *filename) {return 0; }
- static long devfs_release(struct vfs_dir_entry_t *dEntry) { return 0; }
- static long devfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode) {return 0; }
- struct vfs_dir_entry_operations_t devfs_dentry_ops =
- {
- .compare = &devfs_compare,
- .hash = &devfs_hash,
- .release = &devfs_release,
- .iput = &devfs_iput,
- };
- static long devfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
- {
- return 0;
- }
- static long devfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) {return 0; }
- static long devfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {return 0; }
- static long devfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {return 0; }
- static long devfs_lseek(struct vfs_file_t *file_ptr, long offset, long origin) {return 0; }
- static long devfs_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg) { return 0; }
- static long devfs_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t filler)
- {
- // 循环读取目录下的目录项
- struct vfs_dir_entry_t *dentry = file_ptr->dEntry;
- struct List *list = &dentry->subdirs_list;
- // 先切换到position处
- for (int i = 0; i <= file_ptr->position; ++i)
- {
- list = list_next(list);
- if (list == &dentry->subdirs_list) // 找完了
- goto failed;
- }
- // 存在目录项
- // 增加偏移量
- ++file_ptr->position;
- // 获取目标dentry(由于是子目录项,因此是child_node_list)
- struct vfs_dir_entry_t *target_dent = container_of(list, struct vfs_dir_entry_t, child_node_list);
- // kdebug("target name=%s, namelen=%d", target_dent->name, target_dent->name_length);
- char *name = (char *)kzalloc(target_dent->name_length + 1, 0);
- strncpy(name, target_dent->name, target_dent->name_length);
- uint32_t dentry_type;
- if (target_dent->dir_inode->attribute & VFS_IF_DIR)
- dentry_type = VFS_IF_DIR;
- else
- dentry_type = VFS_IF_DEVICE;
- return filler(dirent, file_ptr->position - 1, name, target_dent->name_length, dentry_type, file_ptr->position - 1);
- failed:;
- return 0;
- }
- struct vfs_file_operations_t devfs_file_ops =
- {
- .open = &devfs_open,
- .close = &devfs_close,
- .read = &devfs_read,
- .write = &devfs_write,
- .lseek = &devfs_lseek,
- .ioctl = &devfs_ioctl,
- .readdir = &devfs_readdir,
- };
- /**
- * @brief 创建新的文件
- * @param parent_inode 父目录的inode结构体
- * @param dest_dEntry 新文件的dentry
- * @param mode 创建模式
- */
- static long devfs_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry, int mode)
- {
- return 0;
- }
- static struct vfs_dir_entry_t *devfs_lookup(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry)
- {
- /*
- 由于devfs是伪文件系统,其所有的搜索都依赖于dentry缓存。
- 因此,不需要根据inode来搜索目标目录项。除非目录项不存在,否则不会调用这个函数。
- 当本函数调用的时候,也就意味着devfs中没有这个文件/文件夹。
- 综上,本函数直接返回NULL即可
- */
- return NULL;
- }
- /**
- * @brief 在devfs中创建文件夹(作用是完善子文件夹的inode信息)
- *
- * @param inode 父目录的inode
- * @param dEntry 目标dentry
- * @param mode 创建模式
- * @return long 错误码
- */
- static long devfs_mkdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry, int mode)
- {
- dEntry->dir_inode = vfs_alloc_inode();
- dEntry->dir_inode->file_ops = &devfs_file_ops;
- dEntry->dir_inode->inode_ops = &devfs_inode_ops;
- dEntry->dir_ops = &devfs_dentry_ops;
- // todo: 增加private inode info
- dEntry->dir_inode->private_inode_info = NULL;
- dEntry->dir_inode->sb = &devfs_sb;
- dEntry->dir_inode->attribute = VFS_IF_DIR;
- return 0;
- }
- static long devfs_rmdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry) { return 0; }
- static long devfs_rename(struct vfs_index_node_t *old_inode, struct vfs_dir_entry_t *old_dEntry, struct vfs_index_node_t *new_inode, struct vfs_dir_entry_t *new_dEntry) {return 0; }
- static long devfs_getAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {return 0; }
- static long devfs_setAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {return 0; }
- struct vfs_inode_operations_t devfs_inode_ops = {
- .create = &devfs_create,
- .lookup = &devfs_lookup,
- .mkdir = &devfs_mkdir,
- .rmdir = &devfs_rmdir,
- .rename = &devfs_rename,
- .getAttr = &devfs_getAttr,
- .setAttr = &devfs_setAttr,
- };
- struct vfs_filesystem_type_t devfs_fs_type =
- {
- .name = "DEVFS",
- .fs_flags = 0,
- .read_superblock = devfs_read_superblock,
- .next = NULL,
- };
- static __always_inline void __devfs_init_root_inode()
- {
- devfs_root_dentry->dir_inode = vfs_alloc_inode();
- devfs_root_dentry->dir_inode->file_ops = &devfs_file_ops;
- devfs_root_dentry->dir_inode->inode_ops = &devfs_inode_ops;
- // todo: 增加private inode info
- devfs_root_dentry->dir_inode->private_inode_info = NULL;
- devfs_root_dentry->dir_inode->sb = &devfs_sb;
- devfs_root_dentry->dir_inode->attribute = VFS_IF_DIR;
- }
- /**
- * @brief 初始化devfs的根dentry
- */
- static __always_inline void __devfs_init_root_dentry()
- {
- devfs_root_dentry = (struct vfs_dir_entry_t *)kzalloc(sizeof(struct vfs_dir_entry_t), 0);
- list_init(&devfs_root_dentry->child_node_list);
- list_init(&devfs_root_dentry->subdirs_list);
- devfs_root_dentry->dir_ops = &devfs_dentry_ops;
- __devfs_init_root_inode();
- }
- /**
- * @brief 在devfs中注册设备
- *
- * @param device_type 设备主类型
- * @param sub_type 设备子类型
- * @param file_ops 设备的文件操作接口
- * @return int 错误码
- */
- int devfs_register_device(uint16_t device_type, uint16_t sub_type, struct vfs_file_operations_t *file_ops)
- {
- int retval = 0;
- // 申请private info结构体
- struct devfs_private_inode_info_t *private_info = (struct devfs_private_inode_info_t *)kzalloc(sizeof(struct devfs_private_inode_info_t), 0);
- private_info->f_ops = file_ops;
- private_info->type = device_type;
- private_info->sub_type = sub_type;
- struct vfs_dir_entry_t *dentry = NULL; // 该指针由对应类型设备的注册函数设置
- switch (device_type)
- {
- case DEV_TYPE_CHAR:
- retval = __devfs_chardev_register(private_info, &dentry);
- break;
- default:
- kerror("Unsupported device type [ %d ].", device_type);
- retval = -ENOTSUP;
- goto failed;
- break;
- }
- return retval;
- failed:;
- kfree(private_info);
- return retval;
- }
- /**
- * @brief 初始化devfs
- *
- */
- void devfs_init()
- {
- __devfs_init_root_dentry();
- vfs_register_filesystem(&devfs_fs_type);
- vfs_mount_fs(__devfs_mount_path, "DEVFS", NULL);
- __devfs_chardev_init();
-
- }
|