vfs.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #pragma once
  2. #include <memory>
  3. #include <bits/alltypes.h>
  4. #include <stdint.h>
  5. #include <sys/stat.h>
  6. #include <sys/types.h>
  7. #include <types/path.hpp>
  8. #include <kernel/vfs/dentry.hpp>
  9. #include <kernel/vfs/file.hpp>
  10. #include <kernel/vfs/inode.hpp>
  11. #include <kernel/vfs/vfs.hpp>
  12. #define NODE_MAJOR(node) (((node) >> 8) & 0xFFU)
  13. #define NODE_MINOR(node) ((node)&0xFFU)
  14. namespace fs {
  15. constexpr dev_t make_device(uint32_t major, uint32_t minor) {
  16. return ((major << 8) & 0xFF00U) | (minor & 0xFFU);
  17. }
  18. // buf, buf_size, offset, cnt
  19. using blkdev_read =
  20. std::function<ssize_t(char*, std::size_t, std::size_t, std::size_t)>;
  21. // buf, offset, cnt
  22. using blkdev_write =
  23. std::function<ssize_t(const char*, std::size_t, std::size_t)>;
  24. struct blkdev_ops {
  25. blkdev_read read;
  26. blkdev_write write;
  27. };
  28. // buf, buf_size, cnt
  29. using chrdev_read = std::function<ssize_t(char*, std::size_t, std::size_t)>;
  30. // buf, cnt
  31. using chrdev_write = std::function<ssize_t(const char*, std::size_t)>;
  32. struct chrdev_ops {
  33. chrdev_read read;
  34. chrdev_write write;
  35. };
  36. struct PACKED user_dirent {
  37. ino_t d_ino; // inode number
  38. uint32_t d_off; // ignored
  39. uint16_t d_reclen; // length of this struct user_dirent
  40. char d_name[1]; // file name with a padding zero
  41. // uint8_t d_type; // file type, with offset of (d_reclen - 1)
  42. };
  43. struct PACKED user_dirent64 {
  44. ino64_t d_ino; // inode number
  45. uint64_t d_off; // implementation-defined field, ignored
  46. uint16_t d_reclen; // length of this struct user_dirent
  47. uint8_t d_type; // file type, with offset of (d_reclen - 1)
  48. char d_name[1]; // file name with a padding zero
  49. };
  50. struct fs_context {
  51. dentry_pointer root;
  52. };
  53. struct mount_data {
  54. fs::vfs* fs;
  55. std::string source;
  56. std::string mount_point;
  57. std::string fstype;
  58. unsigned long flags;
  59. };
  60. inline std::map<struct dentry*, mount_data> mounts;
  61. int register_block_device(dev_t node, const blkdev_ops& ops);
  62. int register_char_device(dev_t node, const chrdev_ops& ops);
  63. // return value: pointer to created vfs object
  64. // 1. const char*: source, such as "/dev/sda" or "proc"
  65. // 2. unsigned long: flags, such as MS_RDONLY | MS_RELATIME
  66. // 3. const void*: data, for filesystem use, such as "uid=1000"
  67. using create_fs_func_t =
  68. std::function<vfs*(const char*, unsigned long, const void*)>;
  69. int register_fs(const char* name, create_fs_func_t);
  70. void partprobe();
  71. ssize_t block_device_read(dev_t node, char* buf, size_t buf_size, size_t offset,
  72. size_t n);
  73. ssize_t block_device_write(dev_t node, const char* buf, size_t offset,
  74. size_t n);
  75. ssize_t char_device_read(dev_t node, char* buf, size_t buf_size, size_t n);
  76. ssize_t char_device_write(dev_t node, const char* buf, size_t n);
  77. int creat(struct dentry* at, mode_t mode);
  78. int mkdir(struct dentry* at, mode_t mode);
  79. int mknod(struct dentry* at, mode_t mode, dev_t sn);
  80. int unlink(struct dentry* at);
  81. int symlink(struct dentry* at, const char* target);
  82. int statx(struct inode* inode, struct statx* stat, unsigned int mask);
  83. int readlink(struct inode* inode, char* buf, size_t buf_size);
  84. int truncate(struct inode* file, size_t size);
  85. size_t read(struct inode* file, char* buf, size_t buf_size, size_t offset,
  86. size_t n);
  87. size_t write(struct inode* file, const char* buf, size_t offset, size_t n);
  88. int mount(dentry* mnt, const char* source, const char* mount_point,
  89. const char* fstype, unsigned long flags, const void* data);
  90. #define current_open(...) \
  91. fs::open(current_process->fs_context, current_process->cwd.get(), \
  92. __VA_ARGS__)
  93. std::pair<dentry_pointer, int> open(const fs_context& context, dentry* cwd,
  94. types::path_iterator path,
  95. bool follow_symlinks = true,
  96. int recurs_no = 0);
  97. } // namespace fs