#include "rootfs.h" #include #include #include static struct vfs_superblock_t rootfs_sb = {0}; extern struct vfs_superblock_t *vfs_root_sb; /** * @brief 释放dentry本身所占的内存 * * @param dentry */ static inline void __release_dentry(struct vfs_dir_entry_t *dentry) { kfree(dentry->name); kfree(dentry); } struct vfs_super_block_operations_t rootfs_sb_ops = { .put_superblock = NULL, .write_inode = NULL, .write_superblock = NULL, }; static struct vfs_dir_entry_t *rootfs_lookup(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry) { return NULL; } struct vfs_inode_operations_t rootfs_inode_ops = { .create = NULL, .getAttr = NULL, .lookup = NULL, .lookup = &rootfs_lookup, .mkdir = NULL, .rename = NULL, .rmdir = NULL, .setAttr = NULL, }; static long rootfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) { return 0; } static long rootfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) { return 0; } static long rootfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) { return 0; } static long rootfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) { return 0; } static long rootfs_lseek(struct vfs_file_t *file_ptr, long offset, long origin) { return 0; } static long rootfs_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg) { return 0; } static long rootfs_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 = target_dent->dir_inode->attribute; return filler(dirent, file_ptr->position - 1, name, target_dent->name_length, dentry_type, file_ptr->position - 1); failed:; return 0; } static long rootfs_compare(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename) { return 0; } static long rootfs_hash(struct vfs_dir_entry_t *dEntry, char *filename) { return 0; } static long rootfs_release(struct vfs_dir_entry_t *dEntry) { return 0; } static long rootfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode) { return 0; } struct vfs_dir_entry_operations_t rootfs_dentry_ops = { .compare = &rootfs_compare, .hash = &rootfs_hash, .release = &rootfs_release, .iput = &rootfs_iput, }; struct vfs_file_operations_t rootfs_file_ops = { .open = &rootfs_open, .close = &rootfs_close, .read = &rootfs_read, .write = &rootfs_write, .lseek = &rootfs_lseek, .ioctl = &rootfs_ioctl, .readdir = &rootfs_readdir, }; /** * @brief 为在rootfs下创建目录(仅仅是形式上的目录,为了支持文件系统挂载) * * @param name 目录名称 * @return int */ static int rootfs_add_dir(const char *name) { { // 检查名称重复 struct List *list = &rootfs_sb.root->subdirs_list; while (list_next(list) != &rootfs_sb.root->subdirs_list) { list = list_next(list); struct vfs_dir_entry_t *tmp = container_of(list, struct vfs_dir_entry_t, child_node_list); if (strcmp(tmp->name, name) == 0) return -EEXIST; } } struct vfs_dir_entry_t *dentry = vfs_alloc_dentry(strlen(name) + 1); strcpy(dentry->name, name); dentry->name_length = strlen(name); dentry->parent = rootfs_sb.root; list_append(&rootfs_sb.root->subdirs_list, &dentry->child_node_list); return 0; } void rootfs_init() { // 初始化超级块 rootfs_sb.blk_device = NULL; rootfs_sb.private_sb_info = NULL; rootfs_sb.sb_ops = &rootfs_sb_ops; rootfs_sb.dir_ops = &rootfs_dentry_ops; // 初始化dentry rootfs_sb.root = vfs_alloc_dentry(sizeof("/")); struct vfs_dir_entry_t *dentry = rootfs_sb.root; strncpy(dentry->name, "/", 2); dentry->name_length = 1; dentry->parent = dentry; // 初始化root inode dentry->dir_inode = vfs_alloc_inode(); dentry->dir_inode->sb = &rootfs_sb; dentry->dir_inode->inode_ops = &rootfs_inode_ops; dentry->dir_inode->file_ops = &rootfs_file_ops; dentry->dir_inode->attribute = VFS_IF_DIR; // 直接将vfs的根superblock设置为rootfs的超级块 vfs_root_sb = &rootfs_sb; // 创建/dev等目录的dentry(以便文件系统的mount) if (rootfs_add_dir("dev") != 0) kerror("create dir 'dev' in rootfs failed"); // 创建/procfs目录的dentry if (rootfs_add_dir("proc") != 0) kerror("create dir 'proc' in rootfs failed"); } /** * @brief 当新的根文件系统被挂载后,将原有的挂载在rootfs下的文件系统,迁移到新的根文件系统上 * */ static void rootfs_migrate() { kdebug("Migrating rootfs's dentries..."); struct List *list = &rootfs_sb.root->subdirs_list; if (unlikely(list_empty(list))) return; list = list_next(list); while (list != &rootfs_sb.root->subdirs_list) { struct vfs_dir_entry_t *tmp = container_of(list, struct vfs_dir_entry_t, child_node_list); if (tmp->dir_inode != NULL) { list = list_next(list); // 获取下一个列表结点(不然的话下面的几行代码就覆盖掉了正确的值了) tmp->parent = vfs_root_sb->root; list_init(&tmp->child_node_list); list_append(&vfs_root_sb->root->subdirs_list, &tmp->child_node_list); } else { list = list_next(list); // 不迁移空的dentry,直接释放他们 list_del(&tmp->child_node_list); __release_dentry(tmp); } } } /** * @brief 当磁盘文件系统被成功挂载后,释放rootfs所占的空间 * */ void rootfs_umount() { // 将原有的“dev”文件夹等进行迁移 rootfs_migrate(); kinfo("Umounting rootfs..."); // 遍历mount链表,删除所有父目录是rootfs的dentry struct mountpoint *mp = NULL; while (1) { mp = mount_find_mnt_list_by_parent(rootfs_sb.root); if (mp == NULL) break; // 释放dentry(由于没有创建inode,因此不需要释放) __release_dentry(mp->dentry); // 释放mountpoint结构体 mount_release_mountpoint(mp); } // 释放root dentry及其inode kfree(rootfs_sb.root->dir_inode); __release_dentry(rootfs_sb.root); }