devfs.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. #include <common/spinlock.h>
  8. #include <debug/bug.h>
  9. struct vfs_super_block_operations_t devfs_sb_ops;
  10. struct vfs_dir_entry_operations_t devfs_dentry_ops;
  11. struct vfs_file_operations_t devfs_file_ops;
  12. struct vfs_inode_operations_t devfs_inode_ops;
  13. struct vfs_dir_entry_t *devfs_root_dentry; // 根结点的dentry
  14. struct vfs_superblock_t devfs_sb = {0};
  15. const char __devfs_mount_path[] = "/dev";
  16. static spinlock_t devfs_global_lock; // devfs的全局锁
  17. static uint64_t __tmp_uuid = 0; // devfs的临时uuid变量(todo:在引入uuid lib之后删除这里)
  18. static inline uint64_t __devfs_get_uuid()
  19. {
  20. // todo : 更改为使用uuid库来生成uuid
  21. return ++__tmp_uuid;
  22. }
  23. /**
  24. * @brief 创建devfs的super block
  25. *
  26. * @param blk 未使用(devfs为伪文件系统,不需要物理设备)
  27. * @return struct vfs_superblock_t*
  28. */
  29. struct vfs_superblock_t *devfs_read_superblock(struct block_device *blk)
  30. {
  31. devfs_sb.blk_device = NULL;
  32. devfs_sb.root = devfs_root_dentry;
  33. devfs_sb.sb_ops = &devfs_sb_ops;
  34. devfs_sb.dir_ops = &devfs_dentry_ops;
  35. // todo: 为devfs增加私有信息
  36. devfs_sb.private_sb_info = NULL;
  37. kdebug("devfs read superblock done");
  38. return &devfs_sb;
  39. }
  40. static void devfs_write_superblock(struct vfs_superblock_t *sb) { return; }
  41. static void devfs_put_superblock(struct vfs_superblock_t *sb) { return; }
  42. static void devfs_write_inode(struct vfs_index_node_t *inode) { return; }
  43. struct vfs_super_block_operations_t devfs_sb_ops =
  44. {
  45. .write_superblock = &devfs_write_superblock,
  46. .put_superblock = &devfs_put_superblock,
  47. .write_inode = &devfs_write_inode,
  48. };
  49. static long devfs_compare(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename) { return 0; }
  50. static long devfs_hash(struct vfs_dir_entry_t *dEntry, char *filename) { return 0; }
  51. static long devfs_release(struct vfs_dir_entry_t *dEntry) { return 0; }
  52. static long devfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode) { return 0; }
  53. struct vfs_dir_entry_operations_t devfs_dentry_ops =
  54. {
  55. .compare = &devfs_compare,
  56. .hash = &devfs_hash,
  57. .release = &devfs_release,
  58. .iput = &devfs_iput,
  59. };
  60. static long devfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
  61. {
  62. return 0;
  63. }
  64. static long devfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) { return 0; }
  65. static long devfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) { return 0; }
  66. static long devfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) { return 0; }
  67. static long devfs_lseek(struct vfs_file_t *file_ptr, long offset, long origin) { return 0; }
  68. static long devfs_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg) { return 0; }
  69. static long devfs_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t filler)
  70. {
  71. // 循环读取目录下的目录项
  72. struct vfs_dir_entry_t *dentry = file_ptr->dEntry;
  73. struct List *list = &dentry->subdirs_list;
  74. // 先切换到position处
  75. for (int i = 0; i <= file_ptr->position; ++i)
  76. {
  77. list = list_next(list);
  78. if (list == &dentry->subdirs_list) // 找完了
  79. goto failed;
  80. }
  81. // 存在目录项
  82. // 增加偏移量
  83. ++file_ptr->position;
  84. // 获取目标dentry(由于是子目录项,因此是child_node_list)
  85. struct vfs_dir_entry_t *target_dent = container_of(list, struct vfs_dir_entry_t, child_node_list);
  86. // kdebug("target name=%s, namelen=%d", target_dent->name, target_dent->name_length);
  87. char *name = (char *)kzalloc(target_dent->name_length + 1, 0);
  88. strncpy(name, target_dent->name, target_dent->name_length);
  89. uint32_t dentry_type;
  90. if (target_dent->dir_inode->attribute & VFS_IF_DIR)
  91. dentry_type = VFS_IF_DIR;
  92. else
  93. dentry_type = VFS_IF_DEVICE;
  94. return filler(dirent, file_ptr->position - 1, name, target_dent->name_length, dentry_type, file_ptr->position - 1);
  95. failed:;
  96. return 0;
  97. }
  98. struct vfs_file_operations_t devfs_file_ops =
  99. {
  100. .open = &devfs_open,
  101. .close = &devfs_close,
  102. .read = &devfs_read,
  103. .write = &devfs_write,
  104. .lseek = &devfs_lseek,
  105. .ioctl = &devfs_ioctl,
  106. .readdir = &devfs_readdir,
  107. };
  108. /**
  109. * @brief 创建新的文件
  110. * @param parent_inode 父目录的inode结构体
  111. * @param dest_dEntry 新文件的dentry
  112. * @param mode 创建模式
  113. */
  114. static long devfs_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry, int mode)
  115. {
  116. return 0;
  117. }
  118. static struct vfs_dir_entry_t *devfs_lookup(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry)
  119. {
  120. /*
  121. 由于devfs是伪文件系统,其所有的搜索都依赖于dentry缓存。
  122. 因此,不需要根据inode来搜索目标目录项。除非目录项不存在,否则不会调用这个函数。
  123. 当本函数调用的时候,也就意味着devfs中没有这个文件/文件夹。
  124. 综上,本函数直接返回NULL即可
  125. */
  126. return NULL;
  127. }
  128. /**
  129. * @brief 在devfs中创建文件夹(作用是完善子文件夹的inode信息)
  130. *
  131. * @param inode 父目录的inode
  132. * @param dEntry 目标dentry
  133. * @param mode 创建模式
  134. * @return long 错误码
  135. */
  136. static long devfs_mkdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry, int mode)
  137. {
  138. dEntry->dir_inode = vfs_alloc_inode();
  139. dEntry->dir_inode->file_ops = &devfs_file_ops;
  140. dEntry->dir_inode->inode_ops = &devfs_inode_ops;
  141. dEntry->dir_ops = &devfs_dentry_ops;
  142. // todo: 增加private inode info
  143. dEntry->dir_inode->private_inode_info = NULL;
  144. dEntry->dir_inode->sb = &devfs_sb;
  145. dEntry->dir_inode->attribute = VFS_IF_DIR;
  146. return 0;
  147. }
  148. static long devfs_rmdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry) { return 0; }
  149. 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; }
  150. static long devfs_getAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) { return 0; }
  151. static long devfs_setAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) { return 0; }
  152. struct vfs_inode_operations_t devfs_inode_ops = {
  153. .create = &devfs_create,
  154. .lookup = &devfs_lookup,
  155. .mkdir = &devfs_mkdir,
  156. .rmdir = &devfs_rmdir,
  157. .rename = &devfs_rename,
  158. .getAttr = &devfs_getAttr,
  159. .setAttr = &devfs_setAttr,
  160. };
  161. struct vfs_filesystem_type_t devfs_fs_type =
  162. {
  163. .name = "DEVFS",
  164. .fs_flags = 0,
  165. .read_superblock = devfs_read_superblock,
  166. .next = NULL,
  167. };
  168. static __always_inline void __devfs_init_root_inode()
  169. {
  170. devfs_root_dentry->dir_inode = vfs_alloc_inode();
  171. devfs_root_dentry->dir_inode->file_ops = &devfs_file_ops;
  172. devfs_root_dentry->dir_inode->inode_ops = &devfs_inode_ops;
  173. // todo: 增加private inode info
  174. devfs_root_dentry->dir_inode->private_inode_info = NULL;
  175. devfs_root_dentry->dir_inode->sb = &devfs_sb;
  176. devfs_root_dentry->dir_inode->attribute = VFS_IF_DIR;
  177. }
  178. /**
  179. * @brief 初始化devfs的根dentry
  180. */
  181. static __always_inline void __devfs_init_root_dentry()
  182. {
  183. devfs_root_dentry = (struct vfs_dir_entry_t *)kzalloc(sizeof(struct vfs_dir_entry_t), 0);
  184. list_init(&devfs_root_dentry->child_node_list);
  185. list_init(&devfs_root_dentry->subdirs_list);
  186. devfs_root_dentry->dir_ops = &devfs_dentry_ops;
  187. __devfs_init_root_inode();
  188. }
  189. /**
  190. * @brief 在devfs中注册设备
  191. *
  192. * @param device_type 设备主类型
  193. * @param sub_type 设备子类型
  194. * @param file_ops 设备的文件操作接口
  195. * @param ret_private_inode_info_ptr 返回的指向inode私有信息结构体的指针
  196. * @return int 错误码
  197. */
  198. int devfs_register_device(uint16_t device_type, uint16_t sub_type, struct vfs_file_operations_t *file_ops, struct devfs_private_inode_info_t **ret_private_inode_info_ptr)
  199. {
  200. spin_lock(&devfs_global_lock);
  201. int retval = 0;
  202. // 申请private info结构体
  203. struct devfs_private_inode_info_t *private_info = (struct devfs_private_inode_info_t *)kzalloc(sizeof(struct devfs_private_inode_info_t), 0);
  204. private_info->f_ops = file_ops;
  205. private_info->type = device_type;
  206. private_info->sub_type = sub_type;
  207. private_info->uuid = __devfs_get_uuid();
  208. struct vfs_dir_entry_t *dentry = NULL; // 该指针由对应类型设备的注册函数设置
  209. switch (device_type)
  210. {
  211. case DEV_TYPE_CHAR:
  212. retval = __devfs_chardev_register(private_info, &dentry);
  213. break;
  214. default:
  215. kerror("Unsupported device type [ %d ].", device_type);
  216. retval = -ENOTSUP;
  217. goto failed;
  218. break;
  219. }
  220. if (ret_private_inode_info_ptr != NULL)
  221. *ret_private_inode_info_ptr = private_info;
  222. spin_unlock(&devfs_global_lock);
  223. return retval;
  224. failed:;
  225. kfree(private_info);
  226. spin_unlock(&devfs_global_lock);
  227. return retval;
  228. }
  229. /**
  230. * @brief 卸载设备
  231. *
  232. * @param private_inode_info 待卸载的设备的inode私有信息
  233. * @param put_private_info 设备被卸载后,执行的函数
  234. * @return int 错误码
  235. */
  236. int devfs_unregister_device(struct devfs_private_inode_info_t *private_inode_info)
  237. {
  238. int retval = 0;
  239. spin_lock(&devfs_global_lock);
  240. struct vfs_dir_entry_t *base_dentry = NULL;
  241. struct vfs_dir_entry_t *target_dentry = NULL;
  242. // 找到父目录的dentry
  243. {
  244. char base_path[64] = {0};
  245. switch (private_inode_info->type)
  246. {
  247. case DEV_TYPE_CHAR:
  248. strcpy(base_path, "/dev/char");
  249. break;
  250. default:
  251. retval = -ENOTSUP;
  252. goto out;
  253. break;
  254. }
  255. base_dentry = vfs_path_walk(base_path, 0);
  256. // bug
  257. if (unlikely(base_dentry == NULL))
  258. {
  259. BUG_ON(1);
  260. retval = -ENODEV;
  261. goto out;
  262. }
  263. }
  264. // 遍历子目录,寻找拥有指定inode的dentry(暂时不支持一个inode对应多个dentry的情况)
  265. // todo: 支持链接文件的卸载
  266. struct List *tmp_list = NULL, *target_list = NULL;
  267. list_for_each_safe(target_list, tmp_list, &base_dentry->subdirs_list)
  268. {
  269. target_dentry = list_entry(target_list, struct vfs_dir_entry_t, child_node_list);
  270. if (target_dentry->dir_inode == private_inode_info->inode)
  271. {
  272. spin_lock(&target_dentry->lockref.lock);
  273. retval = vfs_dentry_put(target_dentry);
  274. if (retval < 0)
  275. {
  276. kerror("Error when try to unregister device");
  277. spin_unlock(&target_dentry->lockref.lock);
  278. }
  279. else if (retval == 0) // 该设备的所有dentry均被卸载完成,不必继续迭代
  280. break;
  281. }
  282. }
  283. retval = 0;
  284. out:;
  285. spin_unlock(&devfs_global_lock);
  286. return retval;
  287. }
  288. /**
  289. * @brief 初始化devfs
  290. *
  291. */
  292. void devfs_init()
  293. {
  294. __devfs_init_root_dentry();
  295. vfs_register_filesystem(&devfs_fs_type);
  296. spin_init(&devfs_global_lock);
  297. vfs_mount_fs(__devfs_mount_path, "DEVFS", NULL);
  298. __devfs_chardev_init();
  299. }