SyntheticFileSystem.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #include "SyntheticFileSystem.h"
  2. #include <AK/StdLib.h>
  3. //#define SYNTHFS_DEBUG
  4. RetainPtr<SyntheticFileSystem> SyntheticFileSystem::create()
  5. {
  6. return adopt(*new SyntheticFileSystem);
  7. }
  8. SyntheticFileSystem::SyntheticFileSystem()
  9. {
  10. }
  11. SyntheticFileSystem::~SyntheticFileSystem()
  12. {
  13. }
  14. bool SyntheticFileSystem::initialize()
  15. {
  16. // Add a File for the root directory.
  17. // FIXME: This needs work.
  18. auto rootDir = make<File>();
  19. rootDir->metadata.inode = { id(), RootInodeIndex };
  20. rootDir->parent = { id(), RootInodeIndex };
  21. rootDir->metadata.mode = 0040555;
  22. rootDir->metadata.uid = 0;
  23. rootDir->metadata.gid = 0;
  24. rootDir->metadata.size = 0;
  25. rootDir->metadata.mtime = mepoch;
  26. m_inodes.set(RootInodeIndex, move(rootDir));
  27. #if 0
  28. #ifndef SERENITY
  29. addFile(createTextFile("file", "I'm a synthetic file!\n"));
  30. addFile(createTextFile("message", "Hey! This isn't my bottle!\n"));
  31. #endif
  32. #endif
  33. return true;
  34. }
  35. auto SyntheticFileSystem::createDirectory(String&& name) -> OwnPtr<File>
  36. {
  37. auto file = make<File>();
  38. file->name = move(name);
  39. file->metadata.size = 0;
  40. file->metadata.uid = 0;
  41. file->metadata.gid = 0;
  42. file->metadata.mode = 0040555;
  43. file->metadata.mtime = mepoch;
  44. return file;
  45. }
  46. auto SyntheticFileSystem::createTextFile(String&& name, String&& text) -> OwnPtr<File>
  47. {
  48. auto file = make<File>();
  49. file->data = text.toByteBuffer();
  50. file->name = move(name);
  51. file->metadata.size = file->data.size();
  52. file->metadata.uid = 100;
  53. file->metadata.gid = 200;
  54. file->metadata.mode = 04;
  55. file->metadata.mtime = mepoch;
  56. return file;
  57. }
  58. auto SyntheticFileSystem::createGeneratedFile(String&& name, Function<ByteBuffer()>&& generator) -> OwnPtr<File>
  59. {
  60. auto file = make<File>();
  61. file->generator = move(generator);
  62. file->name = move(name);
  63. file->metadata.size = 0;
  64. file->metadata.uid = 0;
  65. file->metadata.gid = 0;
  66. file->metadata.mode = 0100644;
  67. file->metadata.mtime = mepoch;
  68. return file;
  69. }
  70. InodeIdentifier SyntheticFileSystem::addFile(OwnPtr<File>&& file, InodeIndex parent)
  71. {
  72. ASSERT(file);
  73. auto it = m_inodes.find(parent);
  74. ASSERT(it != m_inodes.end());
  75. InodeIdentifier newInode { id(), generateInodeIndex() };
  76. file->metadata.inode = newInode;
  77. file->parent = { id(), parent };
  78. (*it).value->children.append(file.ptr());
  79. m_inodes.set(newInode.index(), move(file));
  80. return newInode;
  81. }
  82. bool SyntheticFileSystem::removeFile(InodeIndex inode)
  83. {
  84. auto it = m_inodes.find(inode);
  85. if (it == m_inodes.end())
  86. return false;
  87. auto& file = *(*it).value;
  88. auto pit = m_inodes.find(file.parent.index());
  89. if (pit == m_inodes.end())
  90. return false;
  91. auto& parent = *(*pit).value;
  92. for (size_t i = 0; i < parent.children.size(); ++i) {
  93. if (parent.children[i]->metadata.inode.index() != inode) {
  94. continue;
  95. }
  96. parent.children.remove(i);
  97. break;
  98. }
  99. for (auto& child : file.children)
  100. removeFile(child->metadata.inode.index());
  101. m_inodes.remove(inode);
  102. return true;
  103. }
  104. const char* SyntheticFileSystem::className() const
  105. {
  106. return "synthfs";
  107. }
  108. InodeIdentifier SyntheticFileSystem::rootInode() const
  109. {
  110. return { id(), 1 };
  111. }
  112. bool SyntheticFileSystem::enumerateDirectoryInode(InodeIdentifier inode, Function<bool(const DirectoryEntry&)> callback) const
  113. {
  114. ASSERT(inode.fileSystemID() == id());
  115. #ifdef SYNTHFS_DEBUG
  116. kprintf("[synthfs] enumerateDirectoryInode %u\n", inode.index());
  117. #endif
  118. auto it = m_inodes.find(inode.index());
  119. if (it == m_inodes.end())
  120. return false;
  121. const File& synInode = *(*it).value;
  122. if (!synInode.metadata.isDirectory())
  123. return false;
  124. callback({ ".", synInode.metadata.inode });
  125. callback({ "..", synInode.parent });
  126. for (auto& child : synInode.children) {
  127. callback({ child->name, child->metadata.inode });
  128. }
  129. return true;
  130. }
  131. InodeMetadata SyntheticFileSystem::inodeMetadata(InodeIdentifier inode) const
  132. {
  133. ASSERT(inode.fileSystemID() == id());
  134. #ifdef SYNTHFS_DEBUG
  135. kprintf("[synthfs] inodeMetadata(%u)\n", inode.index());
  136. #endif
  137. auto it = m_inodes.find(inode.index());
  138. if (it == m_inodes.end())
  139. return { };
  140. return (*it).value->metadata;
  141. }
  142. bool SyntheticFileSystem::setModificationTime(InodeIdentifier, dword timestamp)
  143. {
  144. (void) timestamp;
  145. kprintf("FIXME: Implement SyntheticFileSystem::setModificationTime().\n");
  146. return false;
  147. }
  148. InodeIdentifier SyntheticFileSystem::createInode(InodeIdentifier parentInode, const String& name, Unix::mode_t mode, unsigned size)
  149. {
  150. (void) parentInode;
  151. (void) name;
  152. (void) mode;
  153. (void) size;
  154. kprintf("FIXME: Implement SyntheticFileSystem::createDirectoryInode().\n");
  155. return { };
  156. }
  157. bool SyntheticFileSystem::writeInode(InodeIdentifier, const ByteBuffer&)
  158. {
  159. kprintf("FIXME: Implement SyntheticFileSystem::writeInode().\n");
  160. return false;
  161. }
  162. Unix::ssize_t SyntheticFileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t offset, Unix::size_t count, byte* buffer) const
  163. {
  164. ASSERT(inode.fileSystemID() == id());
  165. #ifdef SYNTHFS_DEBUG
  166. kprintf("[synthfs] readInode %u\n", inode.index());
  167. #endif
  168. ASSERT(offset >= 0);
  169. ASSERT(buffer);
  170. \
  171. auto it = m_inodes.find(inode.index());
  172. if (it == m_inodes.end())
  173. return false;
  174. const File& file = *(*it).value;
  175. ByteBuffer generatedData;
  176. if (file.generator)
  177. generatedData = file.generator();
  178. auto* data = generatedData ? &generatedData : &file.data;
  179. Unix::ssize_t nread = min(static_cast<Unix::off_t>(data->size() - offset), static_cast<Unix::off_t>(count));
  180. memcpy(buffer, data->pointer() + offset, nread);
  181. return nread;
  182. }
  183. InodeIdentifier SyntheticFileSystem::makeDirectory(InodeIdentifier parentInode, const String& name, Unix::mode_t)
  184. {
  185. (void) parentInode;
  186. (void) name;
  187. kprintf("FIXME: Implement SyntheticFileSystem::makeDirectory().\n");
  188. return { };
  189. }
  190. auto SyntheticFileSystem::generateInodeIndex() -> InodeIndex
  191. {
  192. return m_nextInodeIndex++;
  193. }