vfs.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. #include <kernel/errno.h>
  2. #include <kernel/mem.h>
  3. #include <kernel/stdio.h>
  4. #include <kernel/syscall.hpp>
  5. #include <kernel/tty.h>
  6. #include <kernel/vfs.hpp>
  7. #include <types/allocator.hpp>
  8. #include <types/list.hpp>
  9. #include <types/status.h>
  10. #include <types/stdint.h>
  11. #include <types/string.hpp>
  12. #include <types/vector.hpp>
  13. using types::allocator_traits;
  14. using types::kernel_allocator;
  15. using types::string;
  16. using types::vector;
  17. struct tmpfs_file_entry {
  18. size_t ino;
  19. char filename[128];
  20. };
  21. fs::vfs::dentry::dentry(dentry* _parent, inode* _ind, const name_type& _name)
  22. : parent(_parent)
  23. , ind(_ind)
  24. , flags { 0 }
  25. , name(_name)
  26. {
  27. }
  28. fs::vfs::dentry::dentry(dentry* _parent, inode* _ind, name_type&& _name)
  29. : parent(_parent)
  30. , ind(_ind)
  31. , flags { 0 }
  32. , name(types::move(_name))
  33. {
  34. }
  35. fs::vfs::dentry::dentry(dentry&& val)
  36. : children(types::move(val.children))
  37. , idx_children(types::move(val.idx_children))
  38. , parent(val.parent)
  39. , ind(val.ind)
  40. , flags { val.flags }
  41. , name(types::move(val.name))
  42. {
  43. for (auto& item : children)
  44. item.parent = this;
  45. }
  46. fs::vfs::dentry* fs::vfs::dentry::append(inode* ind, const name_type& name)
  47. {
  48. auto iter = children.emplace_back(this, ind, name);
  49. idx_children.insert(iter->name, iter.ptr());
  50. return iter.ptr();
  51. }
  52. fs::vfs::dentry* fs::vfs::dentry::append(inode* ind, name_type&& name)
  53. {
  54. auto iter = children.emplace_back(this, ind, types::move(name));
  55. idx_children.insert(iter->name, iter.ptr());
  56. return iter.ptr();
  57. }
  58. fs::vfs::dentry* fs::vfs::dentry::find(const name_type& name)
  59. {
  60. if (ind->flags.in.directory && !flags.in.present)
  61. ind->fs->load_dentry(this);
  62. auto iter = idx_children.find(name);
  63. if (!iter) {
  64. errno = ENOTFOUND;
  65. return nullptr;
  66. }
  67. return iter->value;
  68. }
  69. fs::vfs::dentry* fs::vfs::dentry::replace(dentry* val)
  70. {
  71. // TODO: prevent the dirent to be swapped out of memory
  72. parent->idx_children.find(this->name)->value = val;
  73. return this;
  74. }
  75. void fs::vfs::dentry::invalidate(void)
  76. {
  77. // TODO: write back
  78. flags.in.dirty = 0;
  79. children.clear();
  80. idx_children.clear();
  81. flags.in.present = 0;
  82. }
  83. fs::vfs::vfs(void)
  84. : _last_inode_no(0)
  85. , _root(nullptr, nullptr, "/")
  86. {
  87. }
  88. fs::ino_t fs::vfs::_assign_inode_id(void)
  89. {
  90. return ++_last_inode_no;
  91. }
  92. fs::inode* fs::vfs::cache_inode(inode_flags flags, uint32_t perm, size_t size, void* impl_data)
  93. {
  94. auto iter = _inodes.emplace_back(inode { flags, perm, impl_data, _assign_inode_id(), this, size });
  95. _idx_inodes.insert(iter->ino, iter.ptr());
  96. return iter.ptr();
  97. }
  98. fs::inode* fs::vfs::get_inode(ino_t ino)
  99. {
  100. auto iter = _idx_inodes.find(ino);
  101. // TODO: load inode from disk if not found
  102. if (!iter)
  103. return nullptr;
  104. else
  105. return iter->value;
  106. }
  107. void fs::vfs::register_root_node(inode* root)
  108. {
  109. if (!_root.ind)
  110. _root.ind = root;
  111. }
  112. int fs::vfs::load_dentry(dentry*)
  113. {
  114. syscall(0x03);
  115. return GB_FAILED;
  116. }
  117. int fs::vfs::mount(dentry* mnt, vfs* new_fs)
  118. {
  119. if (!mnt->ind->flags.in.directory) {
  120. errno = ENOTDIR;
  121. return GB_FAILED;
  122. }
  123. auto* new_ent = new_fs->root();
  124. new_ent->parent = mnt->parent;
  125. new_ent->name = mnt->name;
  126. auto* orig_ent = mnt->replace(new_ent);
  127. _mount_recover_list.insert(new_ent, orig_ent);
  128. return GB_OK;
  129. }
  130. size_t fs::vfs::inode_read(inode*, char*, size_t, size_t, size_t)
  131. {
  132. syscall(0x03);
  133. return 0xffffffff;
  134. }
  135. size_t fs::vfs::inode_write(inode*, const char*, size_t, size_t)
  136. {
  137. syscall(0x03);
  138. return 0xffffffff;
  139. }
  140. int fs::vfs::inode_mkfile(dentry*, const char*)
  141. {
  142. syscall(0x03);
  143. return GB_FAILED;
  144. }
  145. int fs::vfs::inode_mknode(dentry*, const char*, node_t)
  146. {
  147. syscall(0x03);
  148. return GB_FAILED;
  149. }
  150. int fs::vfs::inode_rmfile(dentry*, const char*)
  151. {
  152. syscall(0x03);
  153. return GB_FAILED;
  154. }
  155. int fs::vfs::inode_mkdir(dentry*, const char*)
  156. {
  157. syscall(0x03);
  158. return GB_FAILED;
  159. }
  160. int fs::vfs::inode_stat(dentry*, stat*)
  161. {
  162. syscall(0x03);
  163. return GB_FAILED;
  164. }
  165. class tmpfs : public virtual fs::vfs {
  166. protected:
  167. inline vector<tmpfs_file_entry>* mk_fe_vector(void)
  168. {
  169. return allocator_traits<kernel_allocator<vector<tmpfs_file_entry>>>::allocate_and_construct();
  170. }
  171. inline vector<char>* mk_data_vector(void)
  172. {
  173. return allocator_traits<kernel_allocator<vector<char>>>::allocate_and_construct();
  174. }
  175. void mklink(fs::inode* dir, fs::inode* inode, const char* filename)
  176. {
  177. auto* fes = static_cast<vector<struct tmpfs_file_entry>*>(dir->impl);
  178. struct tmpfs_file_entry ent = {
  179. .ino = inode->ino,
  180. .filename = { 0 },
  181. };
  182. snprintf(ent.filename, sizeof(ent.filename), filename);
  183. fes->push_back(ent);
  184. dir->size += sizeof(tmpfs_file_entry);
  185. }
  186. virtual int load_dentry(dentry* ent) override
  187. {
  188. if (!ent->ind->flags.in.directory) {
  189. errno = ENOTDIR;
  190. return GB_FAILED;
  191. }
  192. auto& entries = *static_cast<vector<tmpfs_file_entry>*>(ent->ind->impl);
  193. for (const auto& entry : entries)
  194. ent->append(get_inode(entry.ino), entry.filename);
  195. ent->flags.in.present = 1;
  196. return GB_OK;
  197. }
  198. public:
  199. explicit tmpfs(void)
  200. {
  201. auto& in = *cache_inode({ INODE_DIR | INODE_MNT }, 0777, 0, mk_fe_vector());
  202. mklink(&in, &in, ".");
  203. mklink(&in, &in, "..");
  204. register_root_node(&in);
  205. }
  206. virtual int inode_mkfile(dentry* dir, const char* filename) override
  207. {
  208. auto& file = *cache_inode({ .v = INODE_FILE }, 0777, 0, mk_data_vector());
  209. mklink(dir->ind, &file, filename);
  210. dir->invalidate();
  211. return GB_OK;
  212. }
  213. virtual int inode_mknode(dentry* dir, const char* filename, fs::node_t sn) override
  214. {
  215. auto& node = *cache_inode({ .v = INODE_NODE }, 0777, 0, (void*)sn.v);
  216. mklink(dir->ind, &node, filename);
  217. dir->invalidate();
  218. return GB_OK;
  219. }
  220. virtual int inode_mkdir(dentry* dir, const char* dirname) override
  221. {
  222. auto& new_dir = *cache_inode({ .v = INODE_DIR }, 0777, 0, mk_fe_vector());
  223. mklink(&new_dir, &new_dir, ".");
  224. mklink(dir->ind, &new_dir, dirname);
  225. mklink(&new_dir, dir->ind, "..");
  226. dir->invalidate();
  227. return GB_OK;
  228. }
  229. virtual size_t inode_read(fs::inode* file, char* buf, size_t buf_size, size_t offset, size_t n) override
  230. {
  231. if (file->flags.in.file != 1)
  232. return 0;
  233. auto* data = static_cast<vector<char>*>(file->impl);
  234. size_t fsize = data->size();
  235. if (offset + n > fsize)
  236. n = fsize - offset;
  237. if (buf_size < n) {
  238. n = buf_size;
  239. }
  240. memcpy(buf, data->data() + offset, n);
  241. return n;
  242. }
  243. virtual size_t inode_write(fs::inode* file, const char* buf, size_t offset, size_t n) override
  244. {
  245. if (file->flags.in.file != 1)
  246. return 0;
  247. auto* data = static_cast<vector<char>*>(file->impl);
  248. for (size_t i = data->size(); i < offset + n; ++i) {
  249. data->push_back(0);
  250. }
  251. memcpy(data->data() + offset, buf, n);
  252. return n;
  253. }
  254. virtual int inode_stat(dentry* dir, fs::stat* stat) override
  255. {
  256. auto* file_inode = dir->ind;
  257. stat->st_ino = file_inode->ino;
  258. stat->st_size = file_inode->size;
  259. if (file_inode->flags.in.file) {
  260. stat->st_rdev.v = 0;
  261. stat->st_blksize = 1;
  262. stat->st_blocks = file_inode->size;
  263. }
  264. if (file_inode->flags.in.directory) {
  265. stat->st_rdev.v = 0;
  266. stat->st_blksize = sizeof(tmpfs_file_entry);
  267. stat->st_blocks = file_inode->size;
  268. }
  269. if (file_inode->flags.in.special_node) {
  270. stat->st_rdev.v = (uint32_t)file_inode->impl;
  271. stat->st_blksize = 0;
  272. stat->st_blocks = 0;
  273. }
  274. return GB_OK;
  275. }
  276. };
  277. // 8 * 8 for now
  278. static fs::special_node sns[8][8];
  279. size_t fs::vfs_read(fs::inode* file, char* buf, size_t buf_size, size_t offset, size_t n)
  280. {
  281. if (file->flags.in.special_node) {
  282. fs::node_t sn {
  283. .v = (uint32_t)file->impl
  284. };
  285. auto* ptr = &sns[sn.in.major][sn.in.minor];
  286. auto* ops = &ptr->ops;
  287. if (ops && ops->read)
  288. return ops->read(ptr, buf, buf_size, offset, n);
  289. else {
  290. errno = EINVAL;
  291. return 0xffffffff;
  292. }
  293. } else {
  294. return file->fs->inode_read(file, buf, buf_size, offset, n);
  295. }
  296. }
  297. size_t fs::vfs_write(fs::inode* file, const char* buf, size_t offset, size_t n)
  298. {
  299. if (file->flags.in.special_node) {
  300. fs::node_t sn {
  301. .v = (uint32_t)file->impl
  302. };
  303. auto* ptr = &sns[sn.in.major][sn.in.minor];
  304. auto* ops = &ptr->ops;
  305. if (ops && ops->write)
  306. return ops->write(ptr, buf, offset, n);
  307. else {
  308. errno = EINVAL;
  309. return 0xffffffff;
  310. }
  311. } else {
  312. return file->fs->inode_write(file, buf, offset, n);
  313. }
  314. }
  315. int fs::vfs_mkfile(fs::vfs::dentry* dir, const char* filename)
  316. {
  317. return dir->ind->fs->inode_mkfile(dir, filename);
  318. }
  319. int fs::vfs_mknode(fs::vfs::dentry* dir, const char* filename, fs::node_t sn)
  320. {
  321. return dir->ind->fs->inode_mknode(dir, filename, sn);
  322. }
  323. int fs::vfs_rmfile(fs::vfs::dentry* dir, const char* filename)
  324. {
  325. return dir->ind->fs->inode_rmfile(dir, filename);
  326. }
  327. int fs::vfs_mkdir(fs::vfs::dentry* dir, const char* dirname)
  328. {
  329. return dir->ind->fs->inode_mkdir(dir, dirname);
  330. }
  331. fs::vfs::dentry* fs::vfs_open(const char* path)
  332. {
  333. if (path[0] == '/' && path[1] == 0x00) {
  334. return fs::fs_root;
  335. }
  336. auto* cur = fs::fs_root;
  337. size_t n = 0;
  338. switch (*(path++)) {
  339. // absolute path
  340. case '/':
  341. while (true) {
  342. if (path[n] == 0x00) {
  343. cur = cur->find(string(path, n));
  344. return cur;
  345. }
  346. if (path[n] == '/') {
  347. cur = cur->find(string(path, n));
  348. if (path[n + 1] == 0x00) {
  349. return cur;
  350. } else {
  351. path += (n + 1);
  352. n = 0;
  353. continue;
  354. }
  355. }
  356. ++n;
  357. }
  358. break;
  359. // empty string
  360. case 0x00:
  361. return nullptr;
  362. break;
  363. // relative path
  364. default:
  365. return nullptr;
  366. break;
  367. }
  368. return nullptr;
  369. }
  370. int fs::vfs_stat(const char* filename, stat* stat)
  371. {
  372. auto ent = vfs_open(filename);
  373. return vfs_stat(ent, stat);
  374. }
  375. int fs::vfs_stat(fs::vfs::dentry* ent, stat* stat)
  376. {
  377. return ent->ind->fs->inode_stat(ent, stat);
  378. }
  379. fs::vfs::dentry* fs::fs_root;
  380. static types::list<fs::vfs*>* fs_es;
  381. void fs::register_special_block(
  382. uint16_t major,
  383. uint16_t minor,
  384. fs::special_node_read read,
  385. fs::special_node_write write,
  386. uint32_t data1,
  387. uint32_t data2)
  388. {
  389. fs::special_node& sn = sns[major][minor];
  390. sn.ops.read = read;
  391. sn.ops.write = write;
  392. sn.data1 = data1;
  393. sn.data2 = data2;
  394. }
  395. fs::vfs* fs::register_fs(vfs* fs)
  396. {
  397. fs_es->push_back(fs);
  398. return fs;
  399. }
  400. size_t b_null_read(fs::special_node*, char* buf, size_t buf_size, size_t, size_t n)
  401. {
  402. if (n >= buf_size)
  403. n = buf_size;
  404. memset(buf, 0x00, n);
  405. return n;
  406. }
  407. size_t b_null_write(fs::special_node*, const char*, size_t, size_t n)
  408. {
  409. return n;
  410. }
  411. void init_vfs(void)
  412. {
  413. using namespace fs;
  414. // null
  415. register_special_block(0, 0, b_null_read, b_null_write, 0, 0);
  416. fs_es = types::kernel_allocator_new<types::list<vfs*>>();
  417. auto* rootfs = types::kernel_allocator_new<tmpfs>();
  418. fs_es->push_back(rootfs);
  419. fs_root = rootfs->root();
  420. vfs_mkdir(fs_root, "dev");
  421. vfs_mkdir(fs_root, "root");
  422. vfs_mkdir(fs_root, "mnt");
  423. vfs_mkfile(fs_root, "init");
  424. auto* init = vfs_open("/init");
  425. const char* str = "#/bin/sh\nexec /bin/sh\n";
  426. vfs_write(init->ind, str, 0, strlen(str));
  427. auto* dev = vfs_open("/dev");
  428. vfs_mknode(dev, "null", { .in { .major = 0, .minor = 0 } });
  429. vfs_mknode(dev, "console", { .in { .major = 1, .minor = 0 } });
  430. vfs_mknode(dev, "hda", { .in { .major = 2, .minor = 0 } });
  431. stat _stat {};
  432. vfs_stat("/init", &_stat);
  433. vfs_stat("/", &_stat);
  434. vfs_stat("/dev", &_stat);
  435. vfs_stat("/dev/null", &_stat);
  436. vfs_stat("/dev/console", &_stat);
  437. vfs_stat("/dev/hda", &_stat);
  438. }