#include #include #include "FileSystem.h" static dword s_lastFileSystemID; static HashMap* map; static HashMap& fileSystems() { if (!map) map = new HashMap(); return *map; } void FileSystem::initializeGlobals() { s_lastFileSystemID = 0; map = 0; } FileSystem::FileSystem() : m_id(++s_lastFileSystemID) { fileSystems().set(m_id, this); } FileSystem::~FileSystem() { fileSystems().remove(m_id); } FileSystem* FileSystem::fromID(dword id) { auto it = fileSystems().find(id); if (it != fileSystems().end()) return (*it).value; return nullptr; } InodeIdentifier FileSystem::childOfDirectoryInodeWithName(InodeIdentifier inode, const String& name) const { InodeIdentifier foundInode; enumerateDirectoryInode(inode, [&] (const DirectoryEntry& entry) { if (entry.name == name) { foundInode = entry.inode; return false; } return true; }); return foundInode; } String FileSystem::nameOfChildInDirectory(InodeIdentifier parent, InodeIdentifier child) const { String name; bool success = enumerateDirectoryInode(parent, [&] (auto& entry) { if (entry.inode == child) { name = entry.name; return false; } return true; }); ASSERT(success); return name; } ByteBuffer FileSystem::readEntireInode(InodeIdentifier inode, FileHandle* handle) const { ASSERT(inode.fileSystemID() == id()); auto metadata = inodeMetadata(inode); if (!metadata.isValid()) { kprintf("[fs] readInode: metadata lookup for inode %u failed\n", inode.index()); return nullptr; } size_t initialSize = metadata.size ? metadata.size : 4096; auto contents = ByteBuffer::createUninitialized(initialSize); Unix::ssize_t nread; byte buffer[4096]; byte* out = contents.pointer(); Unix::off_t offset = 0; for (;;) { nread = readInodeBytes(inode, offset, sizeof(buffer), buffer, handle); //kprintf("nread: %u, bufsiz: %u, initialSize: %u\n", nread, sizeof(buffer), initialSize); ASSERT(nread <= sizeof(buffer)); if (nread <= 0) break; memcpy(out, buffer, nread); out += nread; offset += nread; ASSERT(offset <= initialSize); // FIXME: Support dynamically growing the buffer. } if (nread < 0) { kprintf("[fs] readInode: ERROR: %d\n", nread); return nullptr; } contents.trim(offset); return contents; }