From 8f6998c902c8f0603c30f9bb927ef30e50426410 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 31 Oct 2018 21:31:56 +0100 Subject: [PATCH] Add SpinLock to IDE disk access. This forces serialization of accesses. This driver needs to be redesigned. --- Kernel/Disk.cpp | 4 ++++ LibC/assert.cpp | 8 ++++---- LibC/pwd.cpp | 10 ++++++++++ LibC/stdio.cpp | 10 ++++++++++ Userland/sh.cpp | 10 +++++++++- VirtualFileSystem/Ext2FileSystem.cpp | 3 +++ VirtualFileSystem/VirtualFileSystem.cpp | 25 +++++++++++++++++-------- 7 files changed, 57 insertions(+), 13 deletions(-) diff --git a/Kernel/Disk.cpp b/Kernel/Disk.cpp index 3c971efdbb..5b868fe882 100644 --- a/Kernel/Disk.cpp +++ b/Kernel/Disk.cpp @@ -73,8 +73,11 @@ void interrupt() interrupted = true; } +static SpinLock* s_diskLock; + void initialize() { + s_diskLock = new SpinLock; disableIRQ(); interrupted = false; registerInterruptHandler(IRQ_VECTOR_BASE + IRQ_FIXED_DISK, ide_ISR); @@ -135,6 +138,7 @@ static CHS lba2chs(BYTE drive_index, DWORD lba) bool readSectors(DWORD startSector, WORD count, BYTE* outbuf) { + LOCKER(*s_diskLock); #ifdef DISK_DEBUG kprintf("%s: Disk::readSectors request (%u sector(s) @ %u)\n", current->name().characters(), diff --git a/LibC/assert.cpp b/LibC/assert.cpp index 4aa774c3fd..a8c499e1d0 100644 --- a/LibC/assert.cpp +++ b/LibC/assert.cpp @@ -1,12 +1,12 @@ -#include "assert.h" -#include "stdlib.h" -#include "stdio.h" +#include +#include +#include extern "C" { extern void __assertion_failed(const char* msg, const char* file, unsigned line, const char* func) { - printf("ASSERTION FAILED: %s\n%s:%u in %s\n", msg, file, line, func); + fprintf(stderr, "ASSERTION FAILED: %s\n%s:%u in %s\n", msg, file, line, func); abort(); } diff --git a/LibC/pwd.cpp b/LibC/pwd.cpp index 99325ff516..0c49cb3f1c 100644 --- a/LibC/pwd.cpp +++ b/LibC/pwd.cpp @@ -5,6 +5,8 @@ #include #include +extern "C" { + struct passwd_with_strings : public passwd { char name_buffer[256]; char passwd_buffer[256]; @@ -24,6 +26,10 @@ void setpwent() rewind(__pwdb_stream); } else { __pwdb_stream = fopen("/etc/passwd", "r"); + if (!__pwdb_stream) { + perror("open /etc/passwd"); + } + assert(__pwdb_stream); __pwdb_entry = (struct passwd_with_strings*)mmap(nullptr, getpagesize()); set_mmap_name(__pwdb_entry, getpagesize(), "setpwent"); } @@ -67,6 +73,7 @@ struct passwd* getpwent() if (!__pwdb_stream) setpwent(); + assert(__pwdb_stream); if (feof(__pwdb_stream)) return nullptr; @@ -76,6 +83,7 @@ next_entry: char* s = fgets(buffer, sizeof(buffer), __pwdb_stream); if (!s) return nullptr; + assert(__pwdb_stream); if (feof(__pwdb_stream)) return nullptr; String line(s); @@ -116,3 +124,5 @@ next_entry: strncpy(__pwdb_entry->shell_buffer, e_shell.characters(), e_shell.length()); return __pwdb_entry; } + +} diff --git a/LibC/stdio.cpp b/LibC/stdio.cpp index ec4d86ff41..84ecd38190 100644 --- a/LibC/stdio.cpp +++ b/LibC/stdio.cpp @@ -13,16 +13,19 @@ extern "C" { int fileno(FILE* stream) { + assert(stream); return stream->fd; } int feof(FILE* stream) { + assert(stream); return stream->eof; } char* fgets(char* buffer, int size, FILE* stream) { + assert(stream); ssize_t nread = 0; for (;;) { if (nread >= size) @@ -41,6 +44,7 @@ char* fgets(char* buffer, int size, FILE* stream) int fgetc(FILE* stream) { + assert(stream); char ch; fread(&ch, sizeof(char), 1, stream); return ch; @@ -58,6 +62,7 @@ int getchar() int fputc(int ch, FILE* stream) { + assert(stream); write(stream->fd, &ch, 1); return (byte)ch; } @@ -74,11 +79,13 @@ int putchar(int ch) void clearerr(FILE* stream) { + assert(stream); stream->eof = false; } size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream) { + assert(stream); ssize_t nread = read(stream->fd, ptr, nmemb * size); if (nread < 0) return 0; @@ -89,6 +96,7 @@ size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream) size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream) { + assert(stream); ssize_t nwritten = write(stream->fd, ptr, nmemb * size); if (nwritten < 0) return 0; @@ -97,6 +105,7 @@ size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream) int fseek(FILE* stream, long offset, int whence) { + assert(stream); off_t off = lseek(stream->fd, offset, whence); if (off < 0) return off; @@ -105,6 +114,7 @@ int fseek(FILE* stream, long offset, int whence) long ftell(FILE* stream) { + assert(stream); return lseek(stream->fd, 0, SEEK_CUR); } diff --git a/Userland/sh.cpp b/Userland/sh.cpp index ecf62221c9..3a660c0d01 100644 --- a/Userland/sh.cpp +++ b/Userland/sh.cpp @@ -5,10 +5,12 @@ #include #include #include +#include #include struct GlobalState { String cwd; + String username; char ttyname[32]; char hostname[32]; }; @@ -19,7 +21,7 @@ static void prompt() if (getuid() == 0) printf("# "); else - printf("\033[31;1m%s\033[0m:\033[37;1m%s\033[0m:\033[32;1m%s\033[0m$> ", g->ttyname, g->hostname, g->cwd.characters()); + printf("\033[31;1m%s\033[0m@\033[37;1m%s\033[0m:\033[32;1m%s\033[0m$> ", g->username.characters(), g->hostname, g->cwd.characters()); } static int sh_pwd(int, const char**) @@ -170,6 +172,12 @@ int main(int, char**) rc = ttyname_r(0, g->ttyname, sizeof(g->ttyname)); if (rc < 0) perror("ttyname_r"); + { + auto* pw = getpwuid(getuid()); + if (pw) + g->username = pw->pw_name; + endpwent(); + } greeting(); diff --git a/VirtualFileSystem/Ext2FileSystem.cpp b/VirtualFileSystem/Ext2FileSystem.cpp index efcabe46dc..189750a421 100644 --- a/VirtualFileSystem/Ext2FileSystem.cpp +++ b/VirtualFileSystem/Ext2FileSystem.cpp @@ -129,6 +129,9 @@ bool Ext2FileSystem::initialize() return false; } + // Preheat the BGD cache. + blockGroupDescriptor(0); + #ifdef EXT2_DEBUG for (unsigned i = 1; i <= m_blockGroupCount; ++i) { auto& group = blockGroupDescriptor(i); diff --git a/VirtualFileSystem/VirtualFileSystem.cpp b/VirtualFileSystem/VirtualFileSystem.cpp index 8c71e8a40e..19de414dcf 100644 --- a/VirtualFileSystem/VirtualFileSystem.cpp +++ b/VirtualFileSystem/VirtualFileSystem.cpp @@ -59,6 +59,8 @@ auto VirtualFileSystem::makeNode(InodeIdentifier inode) -> RetainPtr if (!metadata.isValid()) return nullptr; + InterruptDisabler disabler; + CharacterDevice* characterDevice = nullptr; if (metadata.isCharacterDevice()) { auto it = m_characterDevices.find(encodedDevice(metadata.majorDevice, metadata.minorDevice)); @@ -91,6 +93,7 @@ auto VirtualFileSystem::makeNode(InodeIdentifier inode) -> RetainPtr auto VirtualFileSystem::makeNode(CharacterDevice& device) -> RetainPtr { + InterruptDisabler disabler; auto vnode = allocateNode(); ASSERT(vnode); @@ -106,17 +109,23 @@ auto VirtualFileSystem::makeNode(CharacterDevice& device) -> RetainPtr auto VirtualFileSystem::getOrCreateNode(InodeIdentifier inode) -> RetainPtr { - auto it = m_inode2vnode.find(inode); - if (it != m_inode2vnode.end()) - return (*it).value; + { + InterruptDisabler disabler; + auto it = m_inode2vnode.find(inode); + if (it != m_inode2vnode.end()) + return (*it).value; + } return makeNode(inode); } auto VirtualFileSystem::getOrCreateNode(CharacterDevice& device) -> RetainPtr { - auto it = m_device2vnode.find(encodedDevice(device.major(), device.minor())); - if (it != m_device2vnode.end()) - return (*it).value; + { + InterruptDisabler disabler; + auto it = m_device2vnode.find(encodedDevice(device.major(), device.minor())); + if (it != m_device2vnode.end()) + return (*it).value; + } return makeNode(device); } @@ -152,7 +161,7 @@ bool VirtualFileSystem::mountRoot(RetainPtr&& fileSystem) return false; } if (!node->inode.metadata().isDirectory()) { - kprintf("VFS: root inode for / is not in use :(\n"); + kprintf("VFS: root inode for / is not a directory :(\n"); return false; } @@ -168,7 +177,6 @@ bool VirtualFileSystem::mountRoot(RetainPtr&& fileSystem) auto VirtualFileSystem::allocateNode() -> RetainPtr { - if (m_nodeFreeList.isEmpty()) { kprintf("VFS: allocateNode has no nodes left\n"); return nullptr; @@ -182,6 +190,7 @@ auto VirtualFileSystem::allocateNode() -> RetainPtr void VirtualFileSystem::freeNode(Node* node) { + InterruptDisabler disabler; ASSERT(node); ASSERT(node->inUse()); if (node->inode.isValid()) {