FileSystem.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include <AK/Assertions.h>
  2. #include <AK/HashMap.h>
  3. #include <AK/StringBuilder.h>
  4. #include <LibC/errno_numbers.h>
  5. #include "FileSystem.h"
  6. #include <Kernel/VM/MemoryManager.h>
  7. #include <Kernel/LocalSocket.h>
  8. static dword s_lastFileSystemID;
  9. static HashMap<dword, FS*>* s_fs_map;
  10. static HashTable<Inode*>* s_inode_set;
  11. static HashMap<dword, FS*>& all_fses()
  12. {
  13. if (!s_fs_map)
  14. s_fs_map = new HashMap<dword, FS*>();
  15. return *s_fs_map;
  16. }
  17. HashTable<Inode*>& all_inodes()
  18. {
  19. if (!s_inode_set)
  20. s_inode_set = new HashTable<Inode*>();
  21. return *s_inode_set;
  22. }
  23. FS::FS()
  24. : m_lock("FS")
  25. , m_fsid(++s_lastFileSystemID)
  26. {
  27. all_fses().set(m_fsid, this);
  28. }
  29. FS::~FS()
  30. {
  31. all_fses().remove(m_fsid);
  32. }
  33. FS* FS::from_fsid(dword id)
  34. {
  35. auto it = all_fses().find(id);
  36. if (it != all_fses().end())
  37. return (*it).value;
  38. return nullptr;
  39. }
  40. ByteBuffer Inode::read_entire(FileDescriptor* descriptor) const
  41. {
  42. size_t initial_size = metadata().size ? metadata().size : 4096;
  43. StringBuilder builder(initial_size);
  44. ssize_t nread;
  45. byte buffer[4096];
  46. off_t offset = 0;
  47. for (;;) {
  48. nread = read_bytes(offset, sizeof(buffer), buffer, descriptor);
  49. ASSERT(nread <= (ssize_t)sizeof(buffer));
  50. if (nread <= 0)
  51. break;
  52. builder.append((const char*)buffer, nread);
  53. offset += nread;
  54. }
  55. if (nread < 0) {
  56. kprintf("Inode::read_entire: ERROR: %d\n", nread);
  57. return nullptr;
  58. }
  59. return builder.to_byte_buffer();
  60. }
  61. FS::DirectoryEntry::DirectoryEntry(const char* n, InodeIdentifier i, byte ft)
  62. : name_length(strlen(n))
  63. , inode(i)
  64. , file_type(ft)
  65. {
  66. memcpy(name, n, name_length);
  67. name[name_length] = '\0';
  68. }
  69. FS::DirectoryEntry::DirectoryEntry(const char* n, size_t nl, InodeIdentifier i, byte ft)
  70. : name_length(nl)
  71. , inode(i)
  72. , file_type(ft)
  73. {
  74. memcpy(name, n, nl);
  75. name[nl] = '\0';
  76. }
  77. Inode::Inode(FS& fs, unsigned index)
  78. : m_lock("Inode")
  79. , m_fs(fs)
  80. , m_index(index)
  81. {
  82. all_inodes().set(this);
  83. }
  84. Inode::~Inode()
  85. {
  86. all_inodes().remove(this);
  87. }
  88. void Inode::will_be_destroyed()
  89. {
  90. if (m_metadata_dirty)
  91. flush_metadata();
  92. }
  93. void Inode::inode_contents_changed(off_t offset, ssize_t size, const byte* data)
  94. {
  95. if (m_vmo)
  96. m_vmo->inode_contents_changed(Badge<Inode>(), offset, size, data);
  97. }
  98. void Inode::inode_size_changed(size_t old_size, size_t new_size)
  99. {
  100. if (m_vmo)
  101. m_vmo->inode_size_changed(Badge<Inode>(), old_size, new_size);
  102. }
  103. int Inode::set_atime(time_t)
  104. {
  105. return -ENOTIMPL;
  106. }
  107. int Inode::set_ctime(time_t)
  108. {
  109. return -ENOTIMPL;
  110. }
  111. int Inode::set_mtime(time_t)
  112. {
  113. return -ENOTIMPL;
  114. }
  115. int Inode::increment_link_count()
  116. {
  117. return -ENOTIMPL;
  118. }
  119. int Inode::decrement_link_count()
  120. {
  121. return -ENOTIMPL;
  122. }
  123. void FS::sync()
  124. {
  125. Vector<Retained<Inode>> inodes;
  126. {
  127. InterruptDisabler disabler;
  128. for (auto* inode : all_inodes()) {
  129. if (inode->is_metadata_dirty())
  130. inodes.append(*inode);
  131. }
  132. }
  133. for (auto& inode : inodes) {
  134. ASSERT(inode->is_metadata_dirty());
  135. inode->flush_metadata();
  136. }
  137. }
  138. void Inode::set_vmo(VMObject& vmo)
  139. {
  140. m_vmo = vmo.make_weak_ptr();
  141. }
  142. bool Inode::bind_socket(LocalSocket& socket)
  143. {
  144. ASSERT(!m_socket);
  145. m_socket = socket;
  146. return true;
  147. }
  148. bool Inode::unbind_socket()
  149. {
  150. ASSERT(m_socket);
  151. m_socket = nullptr;
  152. return true;
  153. }