FileSystem.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #include <AK/Assertions.h>
  2. #include <AK/HashMap.h>
  3. #include <LibC/errno_numbers.h>
  4. #include "FileSystem.h"
  5. static dword s_lastFileSystemID;
  6. static HashMap<dword, FS*>* s_fs_map;
  7. static HashTable<Inode*>* s_inode_set;
  8. static HashMap<dword, FS*>& all_fses()
  9. {
  10. if (!s_fs_map)
  11. s_fs_map = new HashMap<dword, FS*>();
  12. return *s_fs_map;
  13. }
  14. static HashTable<Inode*>& all_inodes()
  15. {
  16. if (!s_inode_set)
  17. s_inode_set = new HashTable<Inode*>();
  18. return *s_inode_set;
  19. }
  20. void FS::initialize_globals()
  21. {
  22. s_lastFileSystemID = 0;
  23. s_fs_map = nullptr;
  24. s_inode_set = nullptr;
  25. }
  26. FS::FS()
  27. : m_fsid(++s_lastFileSystemID)
  28. {
  29. all_fses().set(m_fsid, this);
  30. }
  31. FS::~FS()
  32. {
  33. all_fses().remove(m_fsid);
  34. }
  35. FS* FS::from_fsid(dword id)
  36. {
  37. auto it = all_fses().find(id);
  38. if (it != all_fses().end())
  39. return (*it).value;
  40. return nullptr;
  41. }
  42. ByteBuffer Inode::read_entire(FileDescriptor* descriptor)
  43. {
  44. size_t initial_size = metadata().size ? metadata().size : 4096;
  45. auto contents = ByteBuffer::create_uninitialized(initial_size);
  46. ssize_t nread;
  47. byte buffer[4096];
  48. byte* out = contents.pointer();
  49. Unix::off_t offset = 0;
  50. for (;;) {
  51. nread = read_bytes(offset, sizeof(buffer), buffer, descriptor);
  52. ASSERT(nread <= (ssize_t)sizeof(buffer));
  53. if (nread <= 0)
  54. break;
  55. memcpy(out, buffer, nread);
  56. out += nread;
  57. offset += nread;
  58. ASSERT(offset <= (ssize_t)initial_size); // FIXME: Support dynamically growing the buffer.
  59. }
  60. if (nread < 0) {
  61. kprintf("Inode::read_entire: ERROR: %d\n", nread);
  62. return nullptr;
  63. }
  64. contents.trim(offset);
  65. return contents;
  66. }
  67. FS::DirectoryEntry::DirectoryEntry(const char* n, InodeIdentifier i, byte ft)
  68. : name_length(strlen(n))
  69. , inode(i)
  70. , fileType(ft)
  71. {
  72. memcpy(name, n, name_length);
  73. name[name_length] = '\0';
  74. }
  75. FS::DirectoryEntry::DirectoryEntry(const char* n, size_t nl, InodeIdentifier i, byte ft)
  76. : name_length(nl)
  77. , inode(i)
  78. , fileType(ft)
  79. {
  80. memcpy(name, n, nl);
  81. name[nl] = '\0';
  82. }
  83. Inode::Inode(FS& fs, unsigned index)
  84. : m_fs(fs)
  85. , m_index(index)
  86. {
  87. all_inodes().set(this);
  88. }
  89. Inode::~Inode()
  90. {
  91. all_inodes().remove(this);
  92. }
  93. void Inode::will_be_destroyed()
  94. {
  95. if (m_metadata_dirty)
  96. flush_metadata();
  97. }
  98. int Inode::set_atime(Unix::time_t)
  99. {
  100. return -ENOTIMPL;
  101. }
  102. int Inode::set_ctime(Unix::time_t)
  103. {
  104. return -ENOTIMPL;
  105. }
  106. int Inode::set_mtime(Unix::time_t)
  107. {
  108. return -ENOTIMPL;
  109. }
  110. int Inode::increment_link_count()
  111. {
  112. return -ENOTIMPL;
  113. }
  114. int Inode::decrement_link_count()
  115. {
  116. return -ENOTIMPL;
  117. }
  118. void FS::sync()
  119. {
  120. for (auto* inode : all_inodes()) {
  121. if (inode->is_metadata_dirty())
  122. inode->flush_metadata();
  123. }
  124. }