rootfs.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include "rootfs.h"
  2. #include <filesystem/VFS/VFS.h>
  3. #include <common/string.h>
  4. #include <filesystem/VFS/mount.h>
  5. static struct vfs_superblock_t rootfs_sb = {0};
  6. extern struct vfs_superblock_t *vfs_root_sb;
  7. /**
  8. * @brief 释放dentry本身所占的内存
  9. *
  10. * @param dentry
  11. */
  12. static inline void __release_dentry(struct vfs_dir_entry_t *dentry)
  13. {
  14. kfree(dentry->name);
  15. kfree(dentry);
  16. }
  17. struct vfs_super_block_operations_t rootfs_sb_ops = {
  18. .put_superblock = NULL,
  19. .write_inode = NULL,
  20. .write_superblock = NULL,
  21. };
  22. static struct vfs_dir_entry_t *rootfs_lookup(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry)
  23. {
  24. return NULL;
  25. }
  26. struct vfs_inode_operations_t rootfs_inode_ops = {
  27. .create = NULL,
  28. .getAttr = NULL,
  29. .lookup = NULL,
  30. .lookup = &rootfs_lookup,
  31. .mkdir = NULL,
  32. .rename = NULL,
  33. .rmdir = NULL,
  34. .setAttr = NULL,
  35. };
  36. static long rootfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
  37. {
  38. return 0;
  39. }
  40. static long rootfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) { return 0; }
  41. static long rootfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) { return 0; }
  42. static long rootfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) { return 0; }
  43. static long rootfs_lseek(struct vfs_file_t *file_ptr, long offset, long origin) { return 0; }
  44. static long rootfs_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg) { return 0; }
  45. static long rootfs_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t filler)
  46. {
  47. // 循环读取目录下的目录项
  48. struct vfs_dir_entry_t *dentry = file_ptr->dEntry;
  49. struct List *list = &dentry->subdirs_list;
  50. // 先切换到position处
  51. for (int i = 0; i <= file_ptr->position; ++i)
  52. {
  53. list = list_next(list);
  54. if (list == &dentry->subdirs_list) // 找完了
  55. goto failed;
  56. }
  57. // 存在目录项
  58. // 增加偏移量
  59. ++file_ptr->position;
  60. // 获取目标dentry(由于是子目录项,因此是child_node_list)
  61. struct vfs_dir_entry_t *target_dent = container_of(list, struct vfs_dir_entry_t, child_node_list);
  62. // kdebug("target name=%s, namelen=%d", target_dent->name, target_dent->name_length);
  63. char *name = (char *)kzalloc(target_dent->name_length + 1, 0);
  64. strncpy(name, target_dent->name, target_dent->name_length);
  65. uint32_t dentry_type = target_dent->dir_inode->attribute;
  66. return filler(dirent, file_ptr->position - 1, name, target_dent->name_length, dentry_type, file_ptr->position - 1);
  67. failed:;
  68. return 0;
  69. }
  70. static long rootfs_compare(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename) { return 0; }
  71. static long rootfs_hash(struct vfs_dir_entry_t *dEntry, char *filename) { return 0; }
  72. static long rootfs_release(struct vfs_dir_entry_t *dEntry) { return 0; }
  73. static long rootfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode) { return 0; }
  74. struct vfs_dir_entry_operations_t rootfs_dentry_ops =
  75. {
  76. .compare = &rootfs_compare,
  77. .hash = &rootfs_hash,
  78. .release = &rootfs_release,
  79. .iput = &rootfs_iput,
  80. };
  81. struct vfs_file_operations_t rootfs_file_ops = {
  82. .open = &rootfs_open,
  83. .close = &rootfs_close,
  84. .read = &rootfs_read,
  85. .write = &rootfs_write,
  86. .lseek = &rootfs_lseek,
  87. .ioctl = &rootfs_ioctl,
  88. .readdir = &rootfs_readdir,
  89. };
  90. /**
  91. * @brief 为在rootfs下创建目录(仅仅是形式上的目录,为了支持文件系统挂载)
  92. *
  93. * @param name 目录名称
  94. * @return int
  95. */
  96. static int rootfs_add_dir(const char *name)
  97. {
  98. {
  99. // 检查名称重复
  100. struct List *list = &rootfs_sb.root->subdirs_list;
  101. while (list_next(list) != &rootfs_sb.root->subdirs_list)
  102. {
  103. list = list_next(list);
  104. struct vfs_dir_entry_t *tmp = container_of(list, struct vfs_dir_entry_t, child_node_list);
  105. if (strcmp(tmp->name, name) == 0)
  106. return -EEXIST;
  107. }
  108. }
  109. struct vfs_dir_entry_t *dentry = vfs_alloc_dentry(strlen(name) + 1);
  110. strcpy(dentry->name, name);
  111. dentry->name_length = strlen(name);
  112. dentry->parent = rootfs_sb.root;
  113. list_append(&rootfs_sb.root->subdirs_list, &dentry->child_node_list);
  114. return 0;
  115. }
  116. void rootfs_init()
  117. {
  118. // 初始化超级块
  119. rootfs_sb.blk_device = NULL;
  120. rootfs_sb.private_sb_info = NULL;
  121. rootfs_sb.sb_ops = &rootfs_sb_ops;
  122. rootfs_sb.dir_ops = &rootfs_dentry_ops;
  123. // 初始化dentry
  124. rootfs_sb.root = vfs_alloc_dentry(sizeof("/"));
  125. struct vfs_dir_entry_t *dentry = rootfs_sb.root;
  126. strncpy(dentry->name, "/", 2);
  127. dentry->name_length = 1;
  128. dentry->parent = dentry;
  129. // 初始化root inode
  130. dentry->dir_inode = vfs_alloc_inode();
  131. dentry->dir_inode->sb = &rootfs_sb;
  132. dentry->dir_inode->inode_ops = &rootfs_inode_ops;
  133. dentry->dir_inode->file_ops = &rootfs_file_ops;
  134. dentry->dir_inode->attribute = VFS_IF_DIR;
  135. // 直接将vfs的根superblock设置为rootfs的超级块
  136. vfs_root_sb = &rootfs_sb;
  137. // 创建/dev等目录的dentry(以便文件系统的mount)
  138. if (rootfs_add_dir("dev") != 0)
  139. kerror("create dir 'dev' in rootfs failed");
  140. }
  141. /**
  142. * @brief 当新的根文件系统被挂载后,将原有的挂载在rootfs下的文件系统,迁移到新的根文件系统上
  143. *
  144. */
  145. static void rootfs_migrate()
  146. {
  147. kdebug("Migrating rootfs's dentries...");
  148. struct List *list = &rootfs_sb.root->subdirs_list;
  149. if (unlikely(list_empty(list)))
  150. return;
  151. list = list_next(list);
  152. while (list != &rootfs_sb.root->subdirs_list)
  153. {
  154. struct vfs_dir_entry_t *tmp = container_of(list, struct vfs_dir_entry_t, child_node_list);
  155. if (tmp->dir_inode != NULL)
  156. {
  157. list = list_next(list); // 获取下一个列表结点(不然的话下面的几行代码就覆盖掉了正确的值了)
  158. tmp->parent = vfs_root_sb->root;
  159. list_init(&tmp->child_node_list);
  160. list_append(&vfs_root_sb->root->subdirs_list, &tmp->child_node_list);
  161. }
  162. else
  163. {
  164. list = list_next(list); // 不迁移空的dentry,直接释放他们
  165. list_del(&tmp->child_node_list);
  166. __release_dentry(tmp);
  167. }
  168. }
  169. }
  170. /**
  171. * @brief 当磁盘文件系统被成功挂载后,释放rootfs所占的空间
  172. *
  173. */
  174. void rootfs_umount()
  175. {
  176. // 将原有的“dev”文件夹等进行迁移
  177. rootfs_migrate();
  178. kinfo("Umounting rootfs...");
  179. // 遍历mount链表,删除所有父目录是rootfs的dentry
  180. struct mountpoint *mp = NULL;
  181. while (1)
  182. {
  183. mp = mount_find_mnt_list_by_parent(rootfs_sb.root);
  184. if (mp == NULL)
  185. break;
  186. // 释放dentry(由于没有创建inode,因此不需要释放)
  187. __release_dentry(mp->dentry);
  188. // 释放mountpoint结构体
  189. mount_release_mountpoint(mp);
  190. }
  191. // 释放root dentry及其inode
  192. kfree(rootfs_sb.root->dir_inode);
  193. __release_dentry(rootfs_sb.root);
  194. }