vfs.cpp 13 KB

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