mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:07:34 +00:00
Add SpinLock to IDE disk access.
This forces serialization of accesses. This driver needs to be redesigned.
This commit is contained in:
parent
dec5683e9c
commit
8f6998c902
7 changed files with 57 additions and 13 deletions
|
@ -73,8 +73,11 @@ void interrupt()
|
||||||
interrupted = true;
|
interrupted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SpinLock* s_diskLock;
|
||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
{
|
{
|
||||||
|
s_diskLock = new SpinLock;
|
||||||
disableIRQ();
|
disableIRQ();
|
||||||
interrupted = false;
|
interrupted = false;
|
||||||
registerInterruptHandler(IRQ_VECTOR_BASE + IRQ_FIXED_DISK, ide_ISR);
|
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)
|
bool readSectors(DWORD startSector, WORD count, BYTE* outbuf)
|
||||||
{
|
{
|
||||||
|
LOCKER(*s_diskLock);
|
||||||
#ifdef DISK_DEBUG
|
#ifdef DISK_DEBUG
|
||||||
kprintf("%s: Disk::readSectors request (%u sector(s) @ %u)\n",
|
kprintf("%s: Disk::readSectors request (%u sector(s) @ %u)\n",
|
||||||
current->name().characters(),
|
current->name().characters(),
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#include "assert.h"
|
#include <assert.h>
|
||||||
#include "stdlib.h"
|
#include <stdlib.h>
|
||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
extern void __assertion_failed(const char* msg, const char* file, unsigned line, const char* func)
|
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();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
LibC/pwd.cpp
10
LibC/pwd.cpp
|
@ -5,6 +5,8 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
struct passwd_with_strings : public passwd {
|
struct passwd_with_strings : public passwd {
|
||||||
char name_buffer[256];
|
char name_buffer[256];
|
||||||
char passwd_buffer[256];
|
char passwd_buffer[256];
|
||||||
|
@ -24,6 +26,10 @@ void setpwent()
|
||||||
rewind(__pwdb_stream);
|
rewind(__pwdb_stream);
|
||||||
} else {
|
} else {
|
||||||
__pwdb_stream = fopen("/etc/passwd", "r");
|
__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());
|
__pwdb_entry = (struct passwd_with_strings*)mmap(nullptr, getpagesize());
|
||||||
set_mmap_name(__pwdb_entry, getpagesize(), "setpwent");
|
set_mmap_name(__pwdb_entry, getpagesize(), "setpwent");
|
||||||
}
|
}
|
||||||
|
@ -67,6 +73,7 @@ struct passwd* getpwent()
|
||||||
if (!__pwdb_stream)
|
if (!__pwdb_stream)
|
||||||
setpwent();
|
setpwent();
|
||||||
|
|
||||||
|
assert(__pwdb_stream);
|
||||||
if (feof(__pwdb_stream))
|
if (feof(__pwdb_stream))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
@ -76,6 +83,7 @@ next_entry:
|
||||||
char* s = fgets(buffer, sizeof(buffer), __pwdb_stream);
|
char* s = fgets(buffer, sizeof(buffer), __pwdb_stream);
|
||||||
if (!s)
|
if (!s)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
assert(__pwdb_stream);
|
||||||
if (feof(__pwdb_stream))
|
if (feof(__pwdb_stream))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
String line(s);
|
String line(s);
|
||||||
|
@ -116,3 +124,5 @@ next_entry:
|
||||||
strncpy(__pwdb_entry->shell_buffer, e_shell.characters(), e_shell.length());
|
strncpy(__pwdb_entry->shell_buffer, e_shell.characters(), e_shell.length());
|
||||||
return __pwdb_entry;
|
return __pwdb_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -13,16 +13,19 @@ extern "C" {
|
||||||
|
|
||||||
int fileno(FILE* stream)
|
int fileno(FILE* stream)
|
||||||
{
|
{
|
||||||
|
assert(stream);
|
||||||
return stream->fd;
|
return stream->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int feof(FILE* stream)
|
int feof(FILE* stream)
|
||||||
{
|
{
|
||||||
|
assert(stream);
|
||||||
return stream->eof;
|
return stream->eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* fgets(char* buffer, int size, FILE* stream)
|
char* fgets(char* buffer, int size, FILE* stream)
|
||||||
{
|
{
|
||||||
|
assert(stream);
|
||||||
ssize_t nread = 0;
|
ssize_t nread = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (nread >= size)
|
if (nread >= size)
|
||||||
|
@ -41,6 +44,7 @@ char* fgets(char* buffer, int size, FILE* stream)
|
||||||
|
|
||||||
int fgetc(FILE* stream)
|
int fgetc(FILE* stream)
|
||||||
{
|
{
|
||||||
|
assert(stream);
|
||||||
char ch;
|
char ch;
|
||||||
fread(&ch, sizeof(char), 1, stream);
|
fread(&ch, sizeof(char), 1, stream);
|
||||||
return ch;
|
return ch;
|
||||||
|
@ -58,6 +62,7 @@ int getchar()
|
||||||
|
|
||||||
int fputc(int ch, FILE* stream)
|
int fputc(int ch, FILE* stream)
|
||||||
{
|
{
|
||||||
|
assert(stream);
|
||||||
write(stream->fd, &ch, 1);
|
write(stream->fd, &ch, 1);
|
||||||
return (byte)ch;
|
return (byte)ch;
|
||||||
}
|
}
|
||||||
|
@ -74,11 +79,13 @@ int putchar(int ch)
|
||||||
|
|
||||||
void clearerr(FILE* stream)
|
void clearerr(FILE* stream)
|
||||||
{
|
{
|
||||||
|
assert(stream);
|
||||||
stream->eof = false;
|
stream->eof = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
|
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
|
||||||
{
|
{
|
||||||
|
assert(stream);
|
||||||
ssize_t nread = read(stream->fd, ptr, nmemb * size);
|
ssize_t nread = read(stream->fd, ptr, nmemb * size);
|
||||||
if (nread < 0)
|
if (nread < 0)
|
||||||
return 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)
|
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);
|
ssize_t nwritten = write(stream->fd, ptr, nmemb * size);
|
||||||
if (nwritten < 0)
|
if (nwritten < 0)
|
||||||
return 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)
|
int fseek(FILE* stream, long offset, int whence)
|
||||||
{
|
{
|
||||||
|
assert(stream);
|
||||||
off_t off = lseek(stream->fd, offset, whence);
|
off_t off = lseek(stream->fd, offset, whence);
|
||||||
if (off < 0)
|
if (off < 0)
|
||||||
return off;
|
return off;
|
||||||
|
@ -105,6 +114,7 @@ int fseek(FILE* stream, long offset, int whence)
|
||||||
|
|
||||||
long ftell(FILE* stream)
|
long ftell(FILE* stream)
|
||||||
{
|
{
|
||||||
|
assert(stream);
|
||||||
return lseek(stream->fd, 0, SEEK_CUR);
|
return lseek(stream->fd, 0, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
#include <LibC/string.h>
|
#include <LibC/string.h>
|
||||||
#include <LibC/stdlib.h>
|
#include <LibC/stdlib.h>
|
||||||
#include <LibC/utsname.h>
|
#include <LibC/utsname.h>
|
||||||
|
#include <LibC/pwd.h>
|
||||||
#include <AK/FileSystemPath.h>
|
#include <AK/FileSystemPath.h>
|
||||||
|
|
||||||
struct GlobalState {
|
struct GlobalState {
|
||||||
String cwd;
|
String cwd;
|
||||||
|
String username;
|
||||||
char ttyname[32];
|
char ttyname[32];
|
||||||
char hostname[32];
|
char hostname[32];
|
||||||
};
|
};
|
||||||
|
@ -19,7 +21,7 @@ static void prompt()
|
||||||
if (getuid() == 0)
|
if (getuid() == 0)
|
||||||
printf("# ");
|
printf("# ");
|
||||||
else
|
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**)
|
static int sh_pwd(int, const char**)
|
||||||
|
@ -170,6 +172,12 @@ int main(int, char**)
|
||||||
rc = ttyname_r(0, g->ttyname, sizeof(g->ttyname));
|
rc = ttyname_r(0, g->ttyname, sizeof(g->ttyname));
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
perror("ttyname_r");
|
perror("ttyname_r");
|
||||||
|
{
|
||||||
|
auto* pw = getpwuid(getuid());
|
||||||
|
if (pw)
|
||||||
|
g->username = pw->pw_name;
|
||||||
|
endpwent();
|
||||||
|
}
|
||||||
|
|
||||||
greeting();
|
greeting();
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,9 @@ bool Ext2FileSystem::initialize()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Preheat the BGD cache.
|
||||||
|
blockGroupDescriptor(0);
|
||||||
|
|
||||||
#ifdef EXT2_DEBUG
|
#ifdef EXT2_DEBUG
|
||||||
for (unsigned i = 1; i <= m_blockGroupCount; ++i) {
|
for (unsigned i = 1; i <= m_blockGroupCount; ++i) {
|
||||||
auto& group = blockGroupDescriptor(i);
|
auto& group = blockGroupDescriptor(i);
|
||||||
|
|
|
@ -59,6 +59,8 @@ auto VirtualFileSystem::makeNode(InodeIdentifier inode) -> RetainPtr<Node>
|
||||||
if (!metadata.isValid())
|
if (!metadata.isValid())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
InterruptDisabler disabler;
|
||||||
|
|
||||||
CharacterDevice* characterDevice = nullptr;
|
CharacterDevice* characterDevice = nullptr;
|
||||||
if (metadata.isCharacterDevice()) {
|
if (metadata.isCharacterDevice()) {
|
||||||
auto it = m_characterDevices.find(encodedDevice(metadata.majorDevice, metadata.minorDevice));
|
auto it = m_characterDevices.find(encodedDevice(metadata.majorDevice, metadata.minorDevice));
|
||||||
|
@ -91,6 +93,7 @@ auto VirtualFileSystem::makeNode(InodeIdentifier inode) -> RetainPtr<Node>
|
||||||
|
|
||||||
auto VirtualFileSystem::makeNode(CharacterDevice& device) -> RetainPtr<Node>
|
auto VirtualFileSystem::makeNode(CharacterDevice& device) -> RetainPtr<Node>
|
||||||
{
|
{
|
||||||
|
InterruptDisabler disabler;
|
||||||
auto vnode = allocateNode();
|
auto vnode = allocateNode();
|
||||||
ASSERT(vnode);
|
ASSERT(vnode);
|
||||||
|
|
||||||
|
@ -106,17 +109,23 @@ auto VirtualFileSystem::makeNode(CharacterDevice& device) -> RetainPtr<Node>
|
||||||
|
|
||||||
auto VirtualFileSystem::getOrCreateNode(InodeIdentifier inode) -> RetainPtr<Node>
|
auto VirtualFileSystem::getOrCreateNode(InodeIdentifier inode) -> RetainPtr<Node>
|
||||||
{
|
{
|
||||||
auto it = m_inode2vnode.find(inode);
|
{
|
||||||
if (it != m_inode2vnode.end())
|
InterruptDisabler disabler;
|
||||||
return (*it).value;
|
auto it = m_inode2vnode.find(inode);
|
||||||
|
if (it != m_inode2vnode.end())
|
||||||
|
return (*it).value;
|
||||||
|
}
|
||||||
return makeNode(inode);
|
return makeNode(inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto VirtualFileSystem::getOrCreateNode(CharacterDevice& device) -> RetainPtr<Node>
|
auto VirtualFileSystem::getOrCreateNode(CharacterDevice& device) -> RetainPtr<Node>
|
||||||
{
|
{
|
||||||
auto it = m_device2vnode.find(encodedDevice(device.major(), device.minor()));
|
{
|
||||||
if (it != m_device2vnode.end())
|
InterruptDisabler disabler;
|
||||||
return (*it).value;
|
auto it = m_device2vnode.find(encodedDevice(device.major(), device.minor()));
|
||||||
|
if (it != m_device2vnode.end())
|
||||||
|
return (*it).value;
|
||||||
|
}
|
||||||
return makeNode(device);
|
return makeNode(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +161,7 @@ bool VirtualFileSystem::mountRoot(RetainPtr<FileSystem>&& fileSystem)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!node->inode.metadata().isDirectory()) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +177,6 @@ bool VirtualFileSystem::mountRoot(RetainPtr<FileSystem>&& fileSystem)
|
||||||
|
|
||||||
auto VirtualFileSystem::allocateNode() -> RetainPtr<Node>
|
auto VirtualFileSystem::allocateNode() -> RetainPtr<Node>
|
||||||
{
|
{
|
||||||
|
|
||||||
if (m_nodeFreeList.isEmpty()) {
|
if (m_nodeFreeList.isEmpty()) {
|
||||||
kprintf("VFS: allocateNode has no nodes left\n");
|
kprintf("VFS: allocateNode has no nodes left\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -182,6 +190,7 @@ auto VirtualFileSystem::allocateNode() -> RetainPtr<Node>
|
||||||
|
|
||||||
void VirtualFileSystem::freeNode(Node* node)
|
void VirtualFileSystem::freeNode(Node* node)
|
||||||
{
|
{
|
||||||
|
InterruptDisabler disabler;
|
||||||
ASSERT(node);
|
ASSERT(node);
|
||||||
ASSERT(node->inUse());
|
ASSERT(node->inUse());
|
||||||
if (node->inode.isValid()) {
|
if (node->inode.isValid()) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue