mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-23 01:32:14 -05:00
Add basic character device support. Start with null and zero.
This commit is contained in:
parent
fa3b11ac64
commit
93556d6743
Notes:
sideshowbarker
2024-07-19 18:48:27 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/93556d67437
14 changed files with 157 additions and 2 deletions
7
VirtualFileSystem/CharacterDevice.cpp
Normal file
7
VirtualFileSystem/CharacterDevice.cpp
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include "CharacterDevice.h"
|
||||
|
||||
CharacterDevice::~CharacterDevice()
|
||||
{
|
||||
}
|
||||
|
||||
|
15
VirtualFileSystem/CharacterDevice.h
Normal file
15
VirtualFileSystem/CharacterDevice.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include "Limits.h"
|
||||
|
||||
class CharacterDevice {
|
||||
public:
|
||||
virtual ~CharacterDevice();
|
||||
|
||||
virtual ssize_t read(byte* buffer, size_t bufferSize) = 0;
|
||||
virtual ssize_t write(const byte* buffer, size_t bufferSize) = 0;
|
||||
|
||||
protected:
|
||||
CharacterDevice() { }
|
||||
};
|
|
@ -1,5 +1,6 @@
|
|||
#include "FileHandle.h"
|
||||
#include "FileSystem.h"
|
||||
#include "CharacterDevice.h"
|
||||
|
||||
FileHandle::FileHandle(RetainPtr<VirtualFileSystem::Node>&& vnode)
|
||||
: m_vnode(std::move(vnode))
|
||||
|
@ -10,8 +11,15 @@ FileHandle::~FileHandle()
|
|||
{
|
||||
}
|
||||
|
||||
ByteBuffer FileHandle::read() const
|
||||
ByteBuffer FileHandle::read()
|
||||
{
|
||||
if (m_vnode->isCharacterDevice()) {
|
||||
auto buffer = ByteBuffer::createUninitialized(1024);
|
||||
ssize_t nread = m_vnode->characterDevice()->read(buffer.pointer(), buffer.size());
|
||||
buffer.trim(nread);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
return m_vnode->fileSystem()->readInode(m_vnode->inode);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ public:
|
|||
explicit FileHandle(RetainPtr<VirtualFileSystem::Node>&&);
|
||||
~FileHandle();
|
||||
|
||||
ByteBuffer read() const;
|
||||
ByteBuffer read();
|
||||
|
||||
private:
|
||||
friend class VirtualFileSystem;
|
||||
|
|
6
VirtualFileSystem/Limits.h
Normal file
6
VirtualFileSystem/Limits.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
typedef dword size_t;
|
||||
typedef signed_dword ssize_t;
|
||||
|
||||
static const size_t GoodBufferSize = 4096;
|
|
@ -20,6 +20,7 @@ VFS_OBJS = \
|
|||
InodeIdentifier.o \
|
||||
CharacterDevice.o \
|
||||
ZeroDevice.o \
|
||||
NullDevice.o \
|
||||
test.o
|
||||
|
||||
OBJS = $(AK_OBJS) $(VFS_OBJS)
|
||||
|
|
25
VirtualFileSystem/NullDevice.cpp
Normal file
25
VirtualFileSystem/NullDevice.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "NullDevice.h"
|
||||
#include "Limits.h"
|
||||
#include <AK/StdLib.h>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
NullDevice::NullDevice()
|
||||
{
|
||||
}
|
||||
|
||||
NullDevice::~NullDevice()
|
||||
{
|
||||
}
|
||||
|
||||
ssize_t NullDevice::read(byte*, size_t)
|
||||
{
|
||||
printf("read from null\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t NullDevice::write(const byte*, size_t bufferSize)
|
||||
{
|
||||
return min(GoodBufferSize, bufferSize);
|
||||
}
|
||||
|
13
VirtualFileSystem/NullDevice.h
Normal file
13
VirtualFileSystem/NullDevice.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "CharacterDevice.h"
|
||||
|
||||
class NullDevice final : public CharacterDevice {
|
||||
public:
|
||||
NullDevice();
|
||||
virtual ~NullDevice();
|
||||
|
||||
ssize_t read(byte* buffer, size_t bufferSize) override;
|
||||
ssize_t write(const byte* buffer, size_t bufferSize) override;
|
||||
};
|
||||
|
|
@ -7,6 +7,11 @@
|
|||
|
||||
//#define VFS_DEBUG
|
||||
|
||||
static dword encodedDevice(unsigned major, unsigned minor)
|
||||
{
|
||||
return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
|
||||
}
|
||||
|
||||
VirtualFileSystem::VirtualFileSystem()
|
||||
{
|
||||
m_maxNodeCount = 16;
|
||||
|
@ -28,6 +33,17 @@ auto VirtualFileSystem::makeNode(InodeIdentifier inode) -> RetainPtr<Node>
|
|||
if (!metadata.isValid())
|
||||
return nullptr;
|
||||
|
||||
CharacterDevice* characterDevice = nullptr;
|
||||
if (metadata.isCharacterDevice()) {
|
||||
auto it = m_characterDevices.find(encodedDevice(metadata.majorDevice, metadata.minorDevice));
|
||||
if (it != m_characterDevices.end()) {
|
||||
characterDevice = (*it).value;
|
||||
} else {
|
||||
printf("[VFS] makeNode() no such character device %u,%u\n", metadata.majorDevice, metadata.minorDevice);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto vnode = allocateNode();
|
||||
ASSERT(vnode);
|
||||
|
||||
|
@ -41,6 +57,7 @@ auto VirtualFileSystem::makeNode(InodeIdentifier inode) -> RetainPtr<Node>
|
|||
#endif
|
||||
|
||||
m_inode2vnode.set(inode, vnode.ptr());
|
||||
vnode->m_characterDevice = characterDevice;
|
||||
return vnode;
|
||||
}
|
||||
|
||||
|
@ -118,6 +135,7 @@ void VirtualFileSystem::freeNode(Node* node)
|
|||
m_inode2vnode.remove(node->inode);
|
||||
node->inode.fileSystem()->release();
|
||||
node->inode = InodeIdentifier();
|
||||
node->m_characterDevice = nullptr;
|
||||
m_nodeFreeList.append(std::move(node));
|
||||
}
|
||||
|
||||
|
@ -415,3 +433,7 @@ VirtualFileSystem::Mount::Mount(InodeIdentifier host, RetainPtr<FileSystem>&& gu
|
|||
{
|
||||
}
|
||||
|
||||
void VirtualFileSystem::registerCharacterDevice(unsigned major, unsigned minor, CharacterDevice& device)
|
||||
{
|
||||
m_characterDevices.set(encodedDevice(major, minor), &device);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <AK/Vector.h>
|
||||
#include "InodeIdentifier.h"
|
||||
|
||||
class CharacterDevice;
|
||||
class FileHandle;
|
||||
class FileSystem;
|
||||
|
||||
|
@ -17,6 +18,9 @@ public:
|
|||
|
||||
bool inUse() const { return inode.isValid(); }
|
||||
|
||||
bool isCharacterDevice() const { return m_characterDevice; }
|
||||
CharacterDevice* characterDevice() { return m_characterDevice; }
|
||||
|
||||
void retain();
|
||||
void release();
|
||||
|
||||
|
@ -27,6 +31,7 @@ public:
|
|||
friend class VirtualFileSystem;
|
||||
VirtualFileSystem* vfs { nullptr };
|
||||
unsigned retainCount { 0 };
|
||||
CharacterDevice* m_characterDevice { nullptr };
|
||||
};
|
||||
|
||||
VirtualFileSystem();
|
||||
|
@ -52,6 +57,8 @@ public:
|
|||
|
||||
bool touch(const String&path);
|
||||
|
||||
void registerCharacterDevice(unsigned major, unsigned minor, CharacterDevice&);
|
||||
|
||||
private:
|
||||
template<typename F> void enumerateDirectoryInode(InodeIdentifier, F func);
|
||||
InodeIdentifier resolvePath(const String& path);
|
||||
|
@ -80,6 +87,7 @@ private:
|
|||
Mount* findMountForGuest(InodeIdentifier);
|
||||
|
||||
HashMap<InodeIdentifier, Node*> m_inode2vnode;
|
||||
HashMap<dword, Node*> m_device2vnode;
|
||||
|
||||
Vector<OwnPtr<Mount>> m_mounts;
|
||||
|
||||
|
@ -89,5 +97,7 @@ private:
|
|||
Vector<Node*> m_nodeFreeList;
|
||||
|
||||
RetainPtr<Node> m_rootNode;
|
||||
|
||||
HashMap<dword, CharacterDevice*> m_characterDevices;
|
||||
};
|
||||
|
||||
|
|
27
VirtualFileSystem/ZeroDevice.cpp
Normal file
27
VirtualFileSystem/ZeroDevice.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include "ZeroDevice.h"
|
||||
#include "Limits.h"
|
||||
#include <AK/StdLib.h>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
ZeroDevice::ZeroDevice()
|
||||
{
|
||||
}
|
||||
|
||||
ZeroDevice::~ZeroDevice()
|
||||
{
|
||||
}
|
||||
|
||||
ssize_t ZeroDevice::read(byte* buffer, size_t bufferSize)
|
||||
{
|
||||
printf("read from zero device\n");
|
||||
size_t count = min(GoodBufferSize, bufferSize);
|
||||
memset(buffer, 0, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
ssize_t ZeroDevice::write(const byte*, size_t bufferSize)
|
||||
{
|
||||
return min(GoodBufferSize, bufferSize);
|
||||
}
|
||||
|
13
VirtualFileSystem/ZeroDevice.h
Normal file
13
VirtualFileSystem/ZeroDevice.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "CharacterDevice.h"
|
||||
|
||||
class ZeroDevice final : public CharacterDevice {
|
||||
public:
|
||||
ZeroDevice();
|
||||
virtual ~ZeroDevice();
|
||||
|
||||
ssize_t read(byte* buffer, size_t bufferSize) override;
|
||||
ssize_t write(const byte* buffer, size_t bufferSize) override;
|
||||
};
|
||||
|
Binary file not shown.
|
@ -3,6 +3,8 @@
|
|||
#include "VirtualFileSystem.h"
|
||||
#include "FileHandle.h"
|
||||
#include "SyntheticFileSystem.h"
|
||||
#include "ZeroDevice.h"
|
||||
#include "NullDevice.h"
|
||||
#include <cstring>
|
||||
#include <AK/SimpleMalloc.h>
|
||||
#include <AK/kmalloc.h>
|
||||
|
@ -17,6 +19,12 @@ int main(int c, char** v)
|
|||
|
||||
VirtualFileSystem vfs;
|
||||
|
||||
auto zero = make<ZeroDevice>();
|
||||
vfs.registerCharacterDevice(1, 5, *zero);
|
||||
|
||||
auto null = make<NullDevice>();
|
||||
vfs.registerCharacterDevice(1, 3, *null);
|
||||
|
||||
if (!vfs.mountRoot(makeFileSystem(filename))) {
|
||||
printf("Failed to mount root :(\n");
|
||||
return 1;
|
||||
|
|
Loading…
Reference in a new issue