From 2716a9e2d7ceb92e66ed486b4d6797caf8be4efd Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 27 Oct 2018 00:14:24 +0200 Subject: [PATCH] Greatly improve /proc/PID/stack by tracing the ebp frame chain. I also added a generator cache to FileHandle. This way, multiple reads to a generated file (i.e in a synthfs) can transparently handle multiple calls to read() without the contents changing between calls. The cache is discarded at EOF (or when the FileHandle is destroyed.) --- AK/ByteBuffer.h | 5 + Kernel/ProcFileSystem.cpp | 213 ++++++++++++---------- Kernel/StdLib.h | 10 + Kernel/Task.cpp | 20 ++ Kernel/Task.h | 4 + Kernel/_fs_contents | Bin 1024000 -> 1024000 bytes Kernel/i386.cpp | 6 +- Kernel/init.cpp | 11 ++ Kernel/kmalloc.cpp | 5 + Kernel/kmalloc.h | 2 + Kernel/system.h | 1 + Kernel/types.h | 4 + Userland/cat.cpp | 2 +- VirtualFileSystem/Ext2FileSystem.cpp | 3 +- VirtualFileSystem/Ext2FileSystem.h | 2 +- VirtualFileSystem/FileHandle.cpp | 4 +- VirtualFileSystem/FileHandle.h | 4 + VirtualFileSystem/FileSystem.cpp | 4 +- VirtualFileSystem/FileSystem.h | 6 +- VirtualFileSystem/InodeIdentifier.cpp | 2 +- VirtualFileSystem/SyntheticFileSystem.cpp | 16 +- VirtualFileSystem/SyntheticFileSystem.h | 2 +- 22 files changed, 210 insertions(+), 116 deletions(-) diff --git a/AK/ByteBuffer.h b/AK/ByteBuffer.h index 3147d90534..c576ad2b74 100644 --- a/AK/ByteBuffer.h +++ b/AK/ByteBuffer.h @@ -24,6 +24,11 @@ public: m_impl = move(other.m_impl); return *this; } + ByteBuffer& operator=(const ByteBuffer& other) + { + m_impl = other.m_impl.copyRef(); + return *this; + } static ByteBuffer createEmpty() { return ByteBuffer(Buffer::createUninitialized(0)); } static ByteBuffer createUninitialized(size_t size) { return ByteBuffer(Buffer::createUninitialized(size)); } diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp index 9560faad69..a763549e11 100644 --- a/Kernel/ProcFileSystem.cpp +++ b/Kernel/ProcFileSystem.cpp @@ -2,6 +2,7 @@ #include "Task.h" #include #include "system.h" +#include "MemoryManager.h" static ProcFileSystem* s_the; @@ -25,6 +26,64 @@ ProcFileSystem::~ProcFileSystem() { } +ByteBuffer procfs$pid_vm(const Task& task) +{ + InterruptDisabler disabler; + char* buffer; + auto stringImpl = StringImpl::createUninitialized(80 + task.regionCount() * 80, buffer); + memset(buffer, 0, stringImpl->length()); + char* ptr = buffer; + ptr += ksprintf(ptr, "BEGIN END SIZE NAME\n"); + for (auto& region : task.regions()) { + ptr += ksprintf(ptr, "%x -- %x %x %s\n", + region->linearAddress.get(), + region->linearAddress.offset(region->size - 1).get(), + region->size, + region->name.characters()); + } + *ptr = '\0'; + return ByteBuffer::copy((byte*)buffer, ptr - buffer); +} + +ByteBuffer procfs$pid_stack(Task& task) +{ + InterruptDisabler disabler; + if (current != &task) { + MemoryManager::the().unmapRegionsForTask(*current); + MemoryManager::the().mapRegionsForTask(task); + } + struct RecognizedSymbol { + dword address; + const KSym* ksym; + }; + Vector recognizedSymbols; + if (auto* eipKsym = ksymbolicate(task.tss().eip)) + recognizedSymbols.append({ task.tss().eip, eipKsym }); + for (dword* stackPtr = (dword*)task.framePtr(); task.isValidAddressForKernel(LinearAddress((dword)stackPtr)); stackPtr = (dword*)*stackPtr) { + dword retaddr = stackPtr[1]; + if (auto* ksym = ksymbolicate(retaddr)) + recognizedSymbols.append({ retaddr, ksym }); + } + size_t bytesNeeded = 0; + for (auto& symbol : recognizedSymbols) { + bytesNeeded += symbol.ksym->name.length() + 8 + 16; + } + auto buffer = ByteBuffer::createUninitialized(bytesNeeded); + char* bufptr = (char*)buffer.pointer(); + + for (auto& symbol : recognizedSymbols) { + // FIXME: This doesn't actually create a file! + unsigned offset = symbol.address - symbol.ksym->address; + bufptr += ksprintf(bufptr, "%p %s +%u\n", symbol.address, symbol.ksym->name.characters(), offset); + } + buffer.trim(bufptr - (char*)buffer.pointer()); + if (current != &task) { + MemoryManager::the().unmapRegionsForTask(task); + MemoryManager::the().mapRegionsForTask(*current); + } + return buffer; +} + void ProcFileSystem::addProcess(Task& task) { ASSERT_INTERRUPTS_DISABLED(); @@ -32,58 +91,8 @@ void ProcFileSystem::addProcess(Task& task) ksprintf(buf, "%d", task.pid()); auto dir = addFile(createDirectory(buf)); m_pid2inode.set(task.pid(), dir.index()); - addFile(createGeneratedFile("vm", [&task] { - InterruptDisabler disabler; - char* buffer; - auto stringImpl = StringImpl::createUninitialized(80 + task.regionCount() * 80, buffer); - memset(buffer, 0, stringImpl->length()); - char* ptr = buffer; - ptr += ksprintf(ptr, "BEGIN END SIZE NAME\n"); - for (auto& region : task.regions()) { - ptr += ksprintf(ptr, "%x -- %x %x %s\n", - region->linearAddress.get(), - region->linearAddress.offset(region->size - 1).get(), - region->size, - region->name.characters()); - } - *ptr = '\0'; - return ByteBuffer::copy((byte*)buffer, ptr - buffer); - }), dir.index()); - addFile(createGeneratedFile("stack", [&task] { - InterruptDisabler disabler; - auto& syms = ksyms(); - dword firstKsymAddress = syms.first().address; - dword lastKsymAddress = syms.last().address; - struct RecognizedSymbol { - dword address; - const char* name; - dword offset; - }; - Vector recognizedSymbols; - size_t bytesNeeded = 0; - for (dword* stackPtr = (dword*)task.stackPtr(); (dword)stackPtr < task.stackTop(); ++stackPtr) { - if (*stackPtr < firstKsymAddress || *stackPtr > lastKsymAddress) - continue; - const char* name = nullptr; - unsigned offset = 0; - for (unsigned i = 0; i < syms.size(); ++i) { - if (*stackPtr < syms[i+1].address) { - name = syms[i].name.characters(); - offset = *stackPtr - syms[i].address; - bytesNeeded += syms[i].name.length() + 8 + 16; - break; - } - } - recognizedSymbols.append({ *stackPtr, name, offset }); - } - auto buffer = ByteBuffer::createUninitialized(bytesNeeded); - char* ptr = (char*)buffer.pointer(); - for (auto& symbol : recognizedSymbols) { - kprintf("%p %s +%u\n", symbol.address, symbol.name, symbol.offset); - } - buffer.trim(ptr - (char*)buffer.pointer()); - return buffer; - }), dir.index()); + addFile(createGeneratedFile("vm", [&task] { return procfs$pid_vm(task); }), dir.index()); + addFile(createGeneratedFile("stack", [&task] { return procfs$pid_stack(task); }), dir.index()); } void ProcFileSystem::removeProcess(Task& task) @@ -97,56 +106,62 @@ void ProcFileSystem::removeProcess(Task& task) m_pid2inode.remove(pid); } +ByteBuffer procfs$mounts() +{ + InterruptDisabler disabler; + auto buffer = ByteBuffer::createUninitialized(VirtualFileSystem::the().mountCount() * 80); + char* ptr = (char*)buffer.pointer(); + VirtualFileSystem::the().forEachMount([&ptr] (auto& mount) { + auto& fs = mount.fileSystem(); + ptr += ksprintf(ptr, "%s @ ", fs.className()); + if (!mount.host().isValid()) + ptr += ksprintf(ptr, "/\n", fs.className()); + else + ptr += ksprintf(ptr, "%u:%u\n", mount.host().fileSystemID(), mount.host().index()); + }); + buffer.trim(ptr - (char*)buffer.pointer()); + return buffer; +} + +ByteBuffer procfs$kmalloc() +{ + InterruptDisabler disabler; + auto buffer = ByteBuffer::createUninitialized(128); + char* ptr = (char*)buffer.pointer(); + ptr += ksprintf(ptr, "alloc: %u\nfree: %u\n", sum_alloc, sum_free); + buffer.trim(ptr - (char*)buffer.pointer()); + return buffer; +} + +ByteBuffer procfs$summary() +{ + InterruptDisabler disabler; + auto tasks = Task::allTasks(); + auto buffer = ByteBuffer::createUninitialized(tasks.size() * 256); + char* ptr = (char*)buffer.pointer(); + ptr += ksprintf(ptr, "PID OWNER STATE PPID NSCHED FDS NAME\n"); + for (auto* task : tasks) { + ptr += ksprintf(ptr, "%w %w:%w %b %w %x %w %s\n", + task->pid(), + task->uid(), + task->gid(), + task->state(), + task->parentPID(), + task->timesScheduled(), + task->fileHandleCount(), + task->name().characters()); + } + *ptr = '\0'; + buffer.trim(ptr - (char*)buffer.pointer()); + return buffer; +} + bool ProcFileSystem::initialize() { SyntheticFileSystem::initialize(); - - addFile(createGeneratedFile("mounts", [] { - InterruptDisabler disabler; - auto buffer = ByteBuffer::createUninitialized(VirtualFileSystem::the().mountCount() * 80); - char* ptr = (char*)buffer.pointer(); - VirtualFileSystem::the().forEachMount([&ptr] (auto& mount) { - auto& fs = mount.fileSystem(); - ptr += ksprintf(ptr, "%s @ ", fs.className()); - if (!mount.host().isValid()) - ptr += ksprintf(ptr, "/\n", fs.className()); - else - ptr += ksprintf(ptr, "%u:%u\n", mount.host().fileSystemID(), mount.host().index()); - }); - buffer.trim(ptr - (char*)buffer.pointer()); - return buffer; - })); - - addFile(createGeneratedFile("kmalloc", [] { - InterruptDisabler disabler; - auto buffer = ByteBuffer::createUninitialized(128); - char* ptr = (char*)buffer.pointer(); - ptr += ksprintf(ptr, "alloc: %u\nfree: %u\n", sum_alloc, sum_free); - buffer.trim(ptr - (char*)buffer.pointer()); - return buffer; - })); - - addFile(createGeneratedFile("summary", [] { - InterruptDisabler disabler; - auto tasks = Task::allTasks(); - auto buffer = ByteBuffer::createUninitialized(tasks.size() * 256); - char* ptr = (char*)buffer.pointer(); - ptr += ksprintf(ptr, "PID OWNER STATE PPID NSCHED FDS NAME\n"); - for (auto* task : tasks) { - ptr += ksprintf(ptr, "%w %w:%w %b %w %x %w %s\n", - task->pid(), - task->uid(), - task->gid(), - task->state(), - task->parentPID(), - task->timesScheduled(), - task->fileHandleCount(), - task->name().characters()); - } - *ptr = '\0'; - buffer.trim(ptr - (char*)buffer.pointer()); - return buffer; - })); + addFile(createGeneratedFile("mounts", procfs$mounts)); + addFile(createGeneratedFile("kmalloc", procfs$kmalloc)); + addFile(createGeneratedFile("summary", procfs$summary)); return true; } diff --git a/Kernel/StdLib.h b/Kernel/StdLib.h index f507773e55..ee7cd18c33 100644 --- a/Kernel/StdLib.h +++ b/Kernel/StdLib.h @@ -2,7 +2,17 @@ #include "types.h" +#if 0 +inline void memcpy(void *dest, const void *src, DWORD n) +{ + BYTE* bdest = (BYTE*)dest; + const BYTE* bsrc = (const BYTE*)src; + for (; n; --n) + *(bdest++) = *(bsrc++); +} +#else void memcpy(void*, const void*, DWORD); +#endif void strcpy(char*, const char*); int strcmp(char const*, const char*); DWORD strlen(const char*); diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index 79fd9d7c37..91fffcd15b 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -885,3 +885,23 @@ Task::Region::Region(LinearAddress a, size_t s, RetainPtr&& z, String&& n) Task::Region::~Region() { } + +bool Task::isValidAddressForKernel(LinearAddress laddr) const +{ + InterruptDisabler disabler; + if (laddr.get() >= ksyms().first().address && laddr.get() <= ksyms().last().address) + return true; + if (is_kmalloc_address((void*)laddr.get())) + return true; + return isValidAddressForUser(laddr); +} + +bool Task::isValidAddressForUser(LinearAddress laddr) const +{ + InterruptDisabler disabler; + for (auto& region: m_regions) { + if (laddr >= region->linearAddress && laddr < region->linearAddress.offset(region->size)) + return true; + } + return false; +} diff --git a/Kernel/Task.h b/Kernel/Task.h index dd06be7022..957b28699e 100644 --- a/Kernel/Task.h +++ b/Kernel/Task.h @@ -122,9 +122,13 @@ public: size_t fileHandleCount() const { return m_fileHandles.size(); } + dword framePtr() const { return m_tss.ebp; } dword stackPtr() const { return m_tss.esp; } dword stackTop() const { return m_tss.ss == 0x10 ? m_stackTop0 : m_stackTop3; } + bool isValidAddressForKernel(LinearAddress) const; + bool isValidAddressForUser(LinearAddress) const; + private: friend class MemoryManager; friend bool scheduleNewTask(); diff --git a/Kernel/_fs_contents b/Kernel/_fs_contents index cff5e6f4916190479fb98de75f2925f1bec586d3..5971aa3cec200f94111667d44823dfdbb3c75919 100644 GIT binary patch delta 13392 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 G{~Q3i+09Y_ delta 4437 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 zJ()$ezi;9aWZWjeq`(exception_state_dump); - kprintf("%s page fault: %u(%s), %s laddr=%p\n", - current->isRing0() ? "Kernel" : "User", - current->pid(), + kprintf("Ring%u page fault in %s(%u), %s laddr=%p\n", + regs.cs & 3, current->name().characters(), + current->pid(), exception_code & 2 ? "write" : "read", faultAddress); diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 8368e071c9..7e220a6ced 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -65,6 +65,17 @@ Vector& ksyms() return *s_ksyms; } +const KSym* ksymbolicate(dword address) +{ + if (address < ksyms().first().address || address > ksyms().last().address) + return nullptr; + for (unsigned i = 0; i < ksyms().size(); ++i) { + if (address < ksyms()[i + 1].address) + return &ksyms()[i]; + } + return nullptr; +} + static void loadKernelMap(const ByteBuffer& buffer) { s_ksyms = new Vector; diff --git a/Kernel/kmalloc.cpp b/Kernel/kmalloc.cpp index 082307ac3b..fbb56569c6 100644 --- a/Kernel/kmalloc.cpp +++ b/Kernel/kmalloc.cpp @@ -29,6 +29,11 @@ PRIVATE BYTE alloc_map[POOL_SIZE / CHUNK_SIZE / 8]; volatile DWORD sum_alloc = 0; volatile DWORD sum_free = POOL_SIZE; +bool is_kmalloc_address(void* ptr) +{ + return ptr >= (void*)BASE_PHYS && ptr <= ((void*)BASE_PHYS + POOL_SIZE); +} + PUBLIC void kmalloc_init() { diff --git a/Kernel/kmalloc.h b/Kernel/kmalloc.h index 3862b68aef..e0b5ac4955 100644 --- a/Kernel/kmalloc.h +++ b/Kernel/kmalloc.h @@ -4,6 +4,8 @@ void kmalloc_init(); void *kmalloc(DWORD size) __attribute__ ((malloc)); void kfree(void*); +bool is_kmalloc_address(void*); + extern volatile DWORD sum_alloc; extern volatile DWORD sum_free; diff --git a/Kernel/system.h b/Kernel/system.h index 03de208bbb..0839f28d45 100644 --- a/Kernel/system.h +++ b/Kernel/system.h @@ -10,6 +10,7 @@ struct KSym { }; Vector& ksyms() PURE; +const KSym* ksymbolicate(dword address) PURE; struct system_t { diff --git a/Kernel/types.h b/Kernel/types.h index 63f2a22846..c7e135fbfb 100644 --- a/Kernel/types.h +++ b/Kernel/types.h @@ -74,6 +74,10 @@ public: void set(dword address) { m_address = address; } void mask(dword m) { m_address &= m; } + bool operator<=(const LinearAddress& other) const { return m_address <= other.m_address; } + bool operator>=(const LinearAddress& other) const { return m_address >= other.m_address; } + bool operator>(const LinearAddress& other) const { return m_address > other.m_address; } + bool operator<(const LinearAddress& other) const { return m_address < other.m_address; } bool operator==(const LinearAddress& other) const { return m_address == other.m_address; } byte* asPtr() { return reinterpret_cast(m_address); } diff --git a/Userland/cat.cpp b/Userland/cat.cpp index c6c11b4127..fd0044a7fe 100644 --- a/Userland/cat.cpp +++ b/Userland/cat.cpp @@ -15,7 +15,7 @@ int main(int argc, char** argv) return 1; } for (;;) { - char buf[4096]; + char buf[1024]; ssize_t nread = read(fd, buf, sizeof(buf)); if (nread == 0) break; diff --git a/VirtualFileSystem/Ext2FileSystem.cpp b/VirtualFileSystem/Ext2FileSystem.cpp index 1b79224488..9314722a5f 100644 --- a/VirtualFileSystem/Ext2FileSystem.cpp +++ b/VirtualFileSystem/Ext2FileSystem.cpp @@ -268,7 +268,7 @@ Vector Ext2FileSystem::blockListForInode(const ext2_inode& e2inode) co return list; } -Unix::ssize_t Ext2FileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t offset, Unix::size_t count, byte* buffer) const +Unix::ssize_t Ext2FileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t offset, Unix::size_t count, byte* buffer, FileHandle*) const { ASSERT(offset >= 0); ASSERT(inode.fileSystemID() == id()); @@ -293,6 +293,7 @@ Unix::ssize_t Ext2FileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t static const unsigned maxInlineSymlinkLength = 60; if (isSymbolicLink(e2inode->i_mode) && e2inode->i_size < maxInlineSymlinkLength) { Unix::ssize_t nread = min((Unix::off_t)e2inode->i_size - offset, static_cast(count)); + kprintf("nread = %d\n", nread); memcpy(buffer, e2inode->i_block + offset, nread); return nread; } diff --git a/VirtualFileSystem/Ext2FileSystem.h b/VirtualFileSystem/Ext2FileSystem.h index f7b73465ef..a0f8a74d3e 100644 --- a/VirtualFileSystem/Ext2FileSystem.h +++ b/VirtualFileSystem/Ext2FileSystem.h @@ -44,7 +44,7 @@ private: virtual InodeMetadata inodeMetadata(InodeIdentifier) const override; virtual bool setModificationTime(InodeIdentifier, dword timestamp) override; virtual InodeIdentifier createInode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size) override; - virtual Unix::ssize_t readInodeBytes(InodeIdentifier, Unix::off_t offset, Unix::size_t count, byte* buffer) const override; + virtual Unix::ssize_t readInodeBytes(InodeIdentifier, Unix::off_t offset, Unix::size_t count, byte* buffer, FileHandle*) const override; virtual InodeIdentifier makeDirectory(InodeIdentifier parentInode, const String& name, Unix::mode_t) override; bool isDirectoryInode(unsigned) const; diff --git a/VirtualFileSystem/FileHandle.cpp b/VirtualFileSystem/FileHandle.cpp index c1a67dfe25..4e61f1b172 100644 --- a/VirtualFileSystem/FileHandle.cpp +++ b/VirtualFileSystem/FileHandle.cpp @@ -102,7 +102,7 @@ Unix::ssize_t FileHandle::read(byte* buffer, Unix::size_t count) // FIXME: What should happen to m_currentOffset? return m_vnode->characterDevice()->read(buffer, count); } - Unix::ssize_t nread = m_vnode->fileSystem()->readInodeBytes(m_vnode->inode, m_currentOffset, count, buffer); + Unix::ssize_t nread = m_vnode->fileSystem()->readInodeBytes(m_vnode->inode, m_currentOffset, count, buffer, this); m_currentOffset += nread; return nread; } @@ -125,7 +125,7 @@ ByteBuffer FileHandle::readEntireFile() return buffer; } - return m_vnode->fileSystem()->readEntireInode(m_vnode->inode); + return m_vnode->fileSystem()->readEntireInode(m_vnode->inode, this); } bool FileHandle::isDirectory() const diff --git a/VirtualFileSystem/FileHandle.h b/VirtualFileSystem/FileHandle.h index 9bbabdcf0c..cc3cc4ee0a 100644 --- a/VirtualFileSystem/FileHandle.h +++ b/VirtualFileSystem/FileHandle.h @@ -32,6 +32,8 @@ public: void setBlocking(bool b) { m_isBlocking = b; } #endif + ByteBuffer& generatorCache() { return m_generatorCache; } + private: friend class VirtualFileSystem; @@ -39,6 +41,8 @@ private: Unix::off_t m_currentOffset { 0 }; + ByteBuffer m_generatorCache; + #ifdef SERENITY int m_fd { -1 }; bool m_isBlocking { true }; diff --git a/VirtualFileSystem/FileSystem.cpp b/VirtualFileSystem/FileSystem.cpp index e8b774e767..e5529b5168 100644 --- a/VirtualFileSystem/FileSystem.cpp +++ b/VirtualFileSystem/FileSystem.cpp @@ -50,7 +50,7 @@ InodeIdentifier FileSystem::childOfDirectoryInodeWithName(InodeIdentifier inode, return foundInode; } -ByteBuffer FileSystem::readEntireInode(InodeIdentifier inode) const +ByteBuffer FileSystem::readEntireInode(InodeIdentifier inode, FileHandle* handle) const { ASSERT(inode.fileSystemID() == id()); @@ -67,7 +67,7 @@ ByteBuffer FileSystem::readEntireInode(InodeIdentifier inode) const byte* out = contents.pointer(); Unix::off_t offset = 0; for (;;) { - nread = readInodeBytes(inode, offset, sizeof(buffer), buffer); + nread = readInodeBytes(inode, offset, sizeof(buffer), buffer, handle); if (nread <= 0) break; memcpy(out, buffer, nread); diff --git a/VirtualFileSystem/FileSystem.h b/VirtualFileSystem/FileSystem.h index a32e8c4077..c6e345d4aa 100644 --- a/VirtualFileSystem/FileSystem.h +++ b/VirtualFileSystem/FileSystem.h @@ -16,6 +16,8 @@ static const dword mepoch = 476763780; +class FileHandle; + class FileSystem : public Retainable { public: static void initializeGlobals(); @@ -30,7 +32,7 @@ public: virtual bool writeInode(InodeIdentifier, const ByteBuffer&) = 0; virtual InodeMetadata inodeMetadata(InodeIdentifier) const = 0; - virtual Unix::ssize_t readInodeBytes(InodeIdentifier, Unix::off_t offset, Unix::size_t count, byte* buffer) const = 0; + virtual Unix::ssize_t readInodeBytes(InodeIdentifier, Unix::off_t offset, Unix::size_t count, byte* buffer, FileHandle*) const = 0; struct DirectoryEntry { String name; @@ -44,7 +46,7 @@ public: virtual InodeIdentifier makeDirectory(InodeIdentifier parentInode, const String& name, Unix::mode_t) = 0; InodeIdentifier childOfDirectoryInodeWithName(InodeIdentifier, const String& name) const; - ByteBuffer readEntireInode(InodeIdentifier) const; + ByteBuffer readEntireInode(InodeIdentifier, FileHandle* = nullptr) const; protected: FileSystem(); diff --git a/VirtualFileSystem/InodeIdentifier.cpp b/VirtualFileSystem/InodeIdentifier.cpp index 45aa2dd1ca..f89e7ef8ef 100644 --- a/VirtualFileSystem/InodeIdentifier.cpp +++ b/VirtualFileSystem/InodeIdentifier.cpp @@ -5,5 +5,5 @@ ByteBuffer InodeIdentifier::readEntireFile() const { if (!fileSystem()) return { }; - return fileSystem()->readEntireInode(*this); + return fileSystem()->readEntireInode(*this, nullptr); } diff --git a/VirtualFileSystem/SyntheticFileSystem.cpp b/VirtualFileSystem/SyntheticFileSystem.cpp index f36deeed9c..51f48c8c9c 100644 --- a/VirtualFileSystem/SyntheticFileSystem.cpp +++ b/VirtualFileSystem/SyntheticFileSystem.cpp @@ -1,4 +1,5 @@ #include "SyntheticFileSystem.h" +#include "FileHandle.h" #include //#define SYNTHFS_DEBUG @@ -188,7 +189,7 @@ bool SyntheticFileSystem::writeInode(InodeIdentifier, const ByteBuffer&) return false; } -Unix::ssize_t SyntheticFileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t offset, Unix::size_t count, byte* buffer) const +Unix::ssize_t SyntheticFileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t offset, Unix::size_t count, byte* buffer, FileHandle* handle) const { InterruptDisabler disabler; @@ -204,12 +205,21 @@ Unix::ssize_t SyntheticFileSystem::readInodeBytes(InodeIdentifier inode, Unix::o return false; const File& file = *(*it).value; ByteBuffer generatedData; - if (file.generator) - generatedData = file.generator(); + if (file.generator) { + if (!handle) { + generatedData = file.generator(); + } else { + if (!handle->generatorCache()) + handle->generatorCache() = file.generator(); + generatedData = handle->generatorCache(); + } + } auto* data = generatedData ? &generatedData : &file.data; Unix::ssize_t nread = min(static_cast(data->size() - offset), static_cast(count)); memcpy(buffer, data->pointer() + offset, nread); + if (nread == 0 && handle && handle->generatorCache()) + handle->generatorCache().clear(); return nread; } diff --git a/VirtualFileSystem/SyntheticFileSystem.h b/VirtualFileSystem/SyntheticFileSystem.h index dc129caf56..2831d6d239 100644 --- a/VirtualFileSystem/SyntheticFileSystem.h +++ b/VirtualFileSystem/SyntheticFileSystem.h @@ -17,7 +17,7 @@ public: virtual InodeMetadata inodeMetadata(InodeIdentifier) const override; virtual bool setModificationTime(InodeIdentifier, dword timestamp) override; virtual InodeIdentifier createInode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size) override; - virtual Unix::ssize_t readInodeBytes(InodeIdentifier, Unix::off_t offset, Unix::size_t count, byte* buffer) const override; + virtual Unix::ssize_t readInodeBytes(InodeIdentifier, Unix::off_t offset, Unix::size_t count, byte* buffer, FileHandle*) const override; virtual InodeIdentifier makeDirectory(InodeIdentifier parentInode, const String& name, Unix::mode_t) override; protected: