devfs.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #include "devfs.h"
  2. #include "internal.h"
  3. #include <filesystem/VFS/VFS.h>
  4. #include <common/glib.h>
  5. #include <common/string.h>
  6. #include <mm/slab.h>
  7. struct vfs_super_block_operations_t devfs_sb_ops;
  8. struct vfs_dir_entry_operations_t devfs_dentry_ops;
  9. struct vfs_file_operations_t devfs_file_ops;
  10. struct vfs_inode_operations_t devfs_inode_ops;
  11. struct vfs_dir_entry_t *devfs_root_dentry; // 根结点的dentry
  12. struct vfs_superblock_t devfs_sb = {0};
  13. const char __devfs_mount_path[] = "/dev";
  14. /**
  15. * @brief 创建devfs的super block
  16. *
  17. * @param blk 未使用(devfs为伪文件系统,不需要物理设备)
  18. * @return struct vfs_superblock_t*
  19. */
  20. struct vfs_superblock_t *devfs_read_superblock(struct block_device *blk)
  21. {
  22. devfs_sb.blk_device = NULL;
  23. devfs_sb.root = devfs_root_dentry;
  24. devfs_sb.sb_ops = &devfs_sb_ops;
  25. devfs_sb.dir_ops = &devfs_dentry_ops;
  26. // todo: 为devfs增加私有信息
  27. devfs_sb.private_sb_info = NULL;
  28. kdebug("devfs read superblock done");
  29. return &devfs_sb;
  30. }
  31. static void devfs_write_superblock(struct vfs_superblock_t *sb) {return ; }
  32. static void devfs_put_superblock(struct vfs_superblock_t *sb) {return ; }
  33. static void devfs_write_inode(struct vfs_index_node_t *inode) {return ; }
  34. struct vfs_super_block_operations_t devfs_sb_ops =
  35. {
  36. .write_superblock = &devfs_write_superblock,
  37. .put_superblock = &devfs_put_superblock,
  38. .write_inode = &devfs_write_inode,
  39. };
  40. static long devfs_compare(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename) {return 0; }
  41. static long devfs_hash(struct vfs_dir_entry_t *dEntry, char *filename) {return 0; }
  42. static long devfs_release(struct vfs_dir_entry_t *dEntry) { return 0; }
  43. static long devfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode) {return 0; }
  44. struct vfs_dir_entry_operations_t devfs_dentry_ops =
  45. {
  46. .compare = &devfs_compare,
  47. .hash = &devfs_hash,
  48. .release = &devfs_release,
  49. .iput = &devfs_iput,
  50. };
  51. static long devfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
  52. {
  53. return 0;
  54. }
  55. static long devfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) {return 0; }
  56. static long devfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {return 0; }
  57. static long devfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {return 0; }
  58. static long devfs_lseek(struct vfs_file_t *file_ptr, long offset, long origin) {return 0; }
  59. static long devfs_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg) { return 0; }
  60. static long devfs_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t filler)
  61. {
  62. // 循环读取目录下的目录项
  63. struct vfs_dir_entry_t *dentry = file_ptr->dEntry;
  64. struct List *list = &dentry->subdirs_list;
  65. // 先切换到position处
  66. for (int i = 0; i <= file_ptr->position; ++i)
  67. {
  68. list = list_next(list);
  69. if (list == &dentry->subdirs_list) // 找完了
  70. goto failed;
  71. }
  72. // 存在目录项
  73. // 增加偏移量
  74. ++file_ptr->position;
  75. // 获取目标dentry(由于是子目录项,因此是child_node_list)
  76. struct vfs_dir_entry_t *target_dent = container_of(list, struct vfs_dir_entry_t, child_node_list);
  77. // kdebug("target name=%s, namelen=%d", target_dent->name, target_dent->name_length);
  78. char *name = (char *)kzalloc(target_dent->name_length + 1, 0);
  79. strncpy(name, target_dent->name, target_dent->name_length);
  80. uint32_t dentry_type;
  81. if (target_dent->dir_inode->attribute & VFS_IF_DIR)
  82. dentry_type = VFS_IF_DIR;
  83. else
  84. dentry_type = VFS_IF_DEVICE;
  85. return filler(dirent, file_ptr->position - 1, name, target_dent->name_length, dentry_type, file_ptr->position - 1);
  86. failed:;
  87. return 0;
  88. }
  89. struct vfs_file_operations_t devfs_file_ops =
  90. {
  91. .open = &devfs_open,
  92. .close = &devfs_close,
  93. .read = &devfs_read,
  94. .write = &devfs_write,
  95. .lseek = &devfs_lseek,
  96. .ioctl = &devfs_ioctl,
  97. .readdir = &devfs_readdir,
  98. };
  99. /**
  100. * @brief 创建新的文件
  101. * @param parent_inode 父目录的inode结构体
  102. * @param dest_dEntry 新文件的dentry
  103. * @param mode 创建模式
  104. */
  105. static long devfs_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry, int mode)
  106. {
  107. return 0;
  108. }
  109. static struct vfs_dir_entry_t *devfs_lookup(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry)
  110. {
  111. /*
  112. 由于devfs是伪文件系统,其所有的搜索都依赖于dentry缓存。
  113. 因此,不需要根据inode来搜索目标目录项。除非目录项不存在,否则不会调用这个函数。
  114. 当本函数调用的时候,也就意味着devfs中没有这个文件/文件夹。
  115. 综上,本函数直接返回NULL即可
  116. */
  117. return NULL;
  118. }
  119. /**
  120. * @brief 在devfs中创建文件夹(作用是完善子文件夹的inode信息)
  121. *
  122. * @param inode 父目录的inode
  123. * @param dEntry 目标dentry
  124. * @param mode 创建模式
  125. * @return long 错误码
  126. */
  127. static long devfs_mkdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry, int mode)
  128. {
  129. dEntry->dir_inode = vfs_alloc_inode();
  130. dEntry->dir_inode->file_ops = &devfs_file_ops;
  131. dEntry->dir_inode->inode_ops = &devfs_inode_ops;
  132. dEntry->dir_ops = &devfs_dentry_ops;
  133. // todo: 增加private inode info
  134. dEntry->dir_inode->private_inode_info = NULL;
  135. dEntry->dir_inode->sb = &devfs_sb;
  136. dEntry->dir_inode->attribute = VFS_IF_DIR;
  137. return 0;
  138. }
  139. static long devfs_rmdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry) { return 0; }
  140. 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; }
  141. static long devfs_getAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {return 0; }
  142. static long devfs_setAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {return 0; }
  143. struct vfs_inode_operations_t devfs_inode_ops = {
  144. .create = &devfs_create,
  145. .lookup = &devfs_lookup,
  146. .mkdir = &devfs_mkdir,
  147. .rmdir = &devfs_rmdir,
  148. .rename = &devfs_rename,
  149. .getAttr = &devfs_getAttr,
  150. .setAttr = &devfs_setAttr,
  151. };
  152. struct vfs_filesystem_type_t devfs_fs_type =
  153. {
  154. .name = "DEVFS",
  155. .fs_flags = 0,
  156. .read_superblock = devfs_read_superblock,
  157. .next = NULL,
  158. };
  159. static __always_inline void __devfs_init_root_inode()
  160. {
  161. devfs_root_dentry->dir_inode = vfs_alloc_inode();
  162. devfs_root_dentry->dir_inode->file_ops = &devfs_file_ops;
  163. devfs_root_dentry->dir_inode->inode_ops = &devfs_inode_ops;
  164. // todo: 增加private inode info
  165. devfs_root_dentry->dir_inode->private_inode_info = NULL;
  166. devfs_root_dentry->dir_inode->sb = &devfs_sb;
  167. devfs_root_dentry->dir_inode->attribute = VFS_IF_DIR;
  168. }
  169. /**
  170. * @brief 初始化devfs的根dentry
  171. */
  172. static __always_inline void __devfs_init_root_dentry()
  173. {
  174. devfs_root_dentry = (struct vfs_dir_entry_t *)kzalloc(sizeof(struct vfs_dir_entry_t), 0);
  175. list_init(&devfs_root_dentry->child_node_list);
  176. list_init(&devfs_root_dentry->subdirs_list);
  177. devfs_root_dentry->dir_ops = &devfs_dentry_ops;
  178. __devfs_init_root_inode();
  179. }
  180. /**
  181. * @brief 在devfs中注册设备
  182. *
  183. * @param device_type 设备主类型
  184. * @param sub_type 设备子类型
  185. * @param file_ops 设备的文件操作接口
  186. * @return int 错误码
  187. */
  188. int devfs_register_device(uint16_t device_type, uint16_t sub_type, struct vfs_file_operations_t *file_ops)
  189. {
  190. int retval = 0;
  191. // 申请private info结构体
  192. struct devfs_private_inode_info_t *private_info = (struct devfs_private_inode_info_t *)kzalloc(sizeof(struct devfs_private_inode_info_t), 0);
  193. private_info->f_ops = file_ops;
  194. private_info->type = device_type;
  195. private_info->sub_type = sub_type;
  196. struct vfs_dir_entry_t *dentry = NULL; // 该指针由对应类型设备的注册函数设置
  197. switch (device_type)
  198. {
  199. case DEV_TYPE_CHAR:
  200. retval = __devfs_chardev_register(private_info, &dentry);
  201. break;
  202. default:
  203. kerror("Unsupported device type [ %d ].", device_type);
  204. retval = -ENOTSUP;
  205. goto failed;
  206. break;
  207. }
  208. return retval;
  209. failed:;
  210. kfree(private_info);
  211. return retval;
  212. }
  213. /**
  214. * @brief 初始化devfs
  215. *
  216. */
  217. void devfs_init()
  218. {
  219. __devfs_init_root_dentry();
  220. vfs_register_filesystem(&devfs_fs_type);
  221. vfs_mount_fs(__devfs_mount_path, "DEVFS", NULL);
  222. __devfs_chardev_init();
  223. }