mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-22 10:36:24 +00:00
Kernel+SystemServer+Base: Introduce the RAMFS filesystem
This filesystem is based on the code of the long-lived TmpFS. It differs from that filesystem in one keypoint - its root inode doesn't have a sticky bit on it. Therefore, we mount it on /dev, to ensure only root can modify files on that directory. In addition to that, /tmp is mounted directly in the SystemServer main (start) code, so it's no longer specified in the fstab file. We ensure that /tmp has a sticky bit and has the value 0777 for root directory permissions, which is certainly a special case when using RAM-backed (and in general other) filesystems. Because of these 2 changes, it's no longer needed to maintain the TmpFS filesystem, hence it's removed (renamed to RAMFS), because the RAMFS represents the purpose of this filesystem in a much better way - it relies on being backed by RAM "storage", and therefore it's easy to conclude it's temporary and volatile, so its content is gone on either system shutdown or unmounting of the filesystem.
This commit is contained in:
parent
fa637e29d2
commit
ed67a877a3
|
@ -11,4 +11,3 @@
|
||||||
/usr/Tests /usr/Tests bind bind,nodev,ro
|
/usr/Tests /usr/Tests bind bind,nodev,ro
|
||||||
/usr/local /usr/local bind bind,nodev,nosuid
|
/usr/local /usr/local bind bind,nodev,nosuid
|
||||||
|
|
||||||
none /tmp tmp nodev,nosuid
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ over `target`.
|
||||||
* `Ext2FS` (or `ext2`): The ext2 filesystem.
|
* `Ext2FS` (or `ext2`): The ext2 filesystem.
|
||||||
* `ProcFS` (or `proc`): The process pseudo-filesystem (normally mounted at `/proc`).
|
* `ProcFS` (or `proc`): The process pseudo-filesystem (normally mounted at `/proc`).
|
||||||
* `DevPtsFS` (or `devpts`): The pseudoterminal pseudo-filesystem (normally mounted at `/dev/pts`).
|
* `DevPtsFS` (or `devpts`): The pseudoterminal pseudo-filesystem (normally mounted at `/dev/pts`).
|
||||||
* `TmpFS` (or `tmp`): A non-persistent filesystem that stores all its data in RAM. An instance of this filesystem is normally mounted at `/tmp`.
|
* `RAMFS` (or `ram`): A non-persistent filesystem that stores all its data in RAM. An instance of this filesystem is normally mounted at `/tmp`.
|
||||||
* `Plan9FS` (or `9p`): A remote filesystem served over the 9P protocol.
|
* `Plan9FS` (or `9p`): A remote filesystem served over the 9P protocol.
|
||||||
|
|
||||||
For Ext2FS, `source_fd` must refer to an open file descriptor to a file
|
For Ext2FS, `source_fd` must refer to an open file descriptor to a file
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
# `TmpFS` filesystem and its purposes
|
# `RAMFS` filesystem and its purposes
|
||||||
|
|
||||||
`TmpFS` is a RAM-backed filesystem. It is used to hold files and directories in the `/tmp` directory and
|
`RAMFS` is a RAM-backed filesystem. It is used to hold files and directories in the `/tmp` directory and
|
||||||
device nodes in the `/dev` directory.
|
device nodes in the `/dev` directory.
|
||||||
|
|
||||||
## What are the `TmpFS` filesystem characteristics?
|
## What are the `RAMFS` filesystem characteristics?
|
||||||
|
|
||||||
`TmpFS` is a pure RAM-backed filesystem, which means all files and directories
|
`RAMFS` is a pure RAM-backed filesystem, which means all files and directories
|
||||||
actually live in memory, each in its own `TmpFS` instance in the kernel.
|
actually live in memory, each in its own `RAMFS` instance in the kernel.
|
||||||
|
|
||||||
The `TmpFS` in its current design is very conservative about allocating virtual memory ranges
|
The `RAMFS` in its current design is very conservative about allocating virtual memory ranges
|
||||||
for itself, and instead it uses the `AnonymousVMObject` object to hold physical pages containing
|
for itself, and instead it uses the `AnonymousVMObject` object to hold physical pages containing
|
||||||
data for its inodes. When doing actual IO, the `TmpFS` code temporarily allocates a small virtual memory
|
data for its inodes. When doing actual IO, the `RAMFS` code temporarily allocates a small virtual memory
|
||||||
`Memory::Region` to perform the task, which works quite well although it puts a strain on the virtual memory
|
`Memory::Region` to perform the task, which works quite well although it puts a strain on the virtual memory
|
||||||
mapping code. The current design also ensures that fabricated huge files can be easily created in the filesystem
|
mapping code. The current design also ensures that fabricated huge files can be easily created in the filesystem
|
||||||
with very small overhead until actual IO is performed.
|
with very small overhead until actual IO is performed.
|
||||||
|
@ -24,10 +24,10 @@ Many test suites in the project leverage the `/tmp` for placing their test files
|
||||||
when trying to check the correctness of many system-related functionality.
|
when trying to check the correctness of many system-related functionality.
|
||||||
Other programs rely on `/tmp` for placing their temporary files to properly function.
|
Other programs rely on `/tmp` for placing their temporary files to properly function.
|
||||||
|
|
||||||
### Why does the `TmpFS` work well for the `/dev` directory?
|
### Why does the `RAMFS` work well for the `/dev` directory?
|
||||||
|
|
||||||
To understand why `TmpFS` works reliably when mounted on `/dev`, we must understand
|
To understand why `RAMFS` works reliably when mounted on `/dev`, we must understand
|
||||||
first what we did in the past and how `TmpFS` solves many of the issues with the previous design.
|
first what we did in the past and how `RAMFS` solves many of the issues with the previous design.
|
||||||
|
|
||||||
At first, we didn't have any special filesystem mounted in `/dev` as the image build
|
At first, we didn't have any special filesystem mounted in `/dev` as the image build
|
||||||
script generated all the required device nodes in `/dev`. This was quite sufficient in
|
script generated all the required device nodes in `/dev`. This was quite sufficient in
|
||||||
|
@ -54,7 +54,7 @@ The `DevFS` solution was short-lived, and was quickly replaced by the `DevTmpFS`
|
||||||
That new shiny filesystem was again specific to `/dev`, but it solved many of the issues
|
That new shiny filesystem was again specific to `/dev`, but it solved many of the issues
|
||||||
`DevFS` suffered from - no more hardcoded permissions and now the design has flexible filesystem
|
`DevFS` suffered from - no more hardcoded permissions and now the design has flexible filesystem
|
||||||
layout in its mindset.
|
layout in its mindset.
|
||||||
This was achieved by implementing from scratch a filesystem that resembles the `TmpFS`
|
This was achieved by implementing from scratch a filesystem that resembles the `RAMFS`
|
||||||
filesystem, but was different in one major aspect - only device nodes and directories are allowed
|
filesystem, but was different in one major aspect - only device nodes and directories are allowed
|
||||||
to be in `/dev`. This strict requirement has been mandated to ensure the user doesn't
|
to be in `/dev`. This strict requirement has been mandated to ensure the user doesn't
|
||||||
accidentally put unrelated files in `/dev`. When the `DevTmpFS` was invented, it clearly
|
accidentally put unrelated files in `/dev`. When the `DevTmpFS` was invented, it clearly
|
||||||
|
@ -65,6 +65,6 @@ in this document, but ultimately evolved to be flexible enough to work quite wel
|
||||||
Everything worked quite well, but there was still a prominent problem with `DevTmpFS` -
|
Everything worked quite well, but there was still a prominent problem with `DevTmpFS` -
|
||||||
it was an entire filesystem solution just for `/dev` and nobody else used it.
|
it was an entire filesystem solution just for `/dev` and nobody else used it.
|
||||||
Testing the filesystem was quite clunky and truthfully lacking from the beginning until its removal.
|
Testing the filesystem was quite clunky and truthfully lacking from the beginning until its removal.
|
||||||
To solve this problem, it was decided to stop using it, and instead just use `TmpFS`.
|
To solve this problem, it was decided to stop using it, and instead just use `RAMFS`.
|
||||||
To ensure the current behavior of disallowing regular files in `/dev`, a new mount flag called
|
To ensure the current behavior of disallowing regular files in `/dev`, a new mount flag called
|
||||||
`MS_NOREGULAR` was invented, so it could be mounted with it.
|
`MS_NOREGULAR` was invented, so it could be mounted with it.
|
|
@ -135,6 +135,8 @@ set(KERNEL_SOURCES
|
||||||
FileSystem/ProcFS/ComponentRegistry.cpp
|
FileSystem/ProcFS/ComponentRegistry.cpp
|
||||||
FileSystem/ProcFS/FileSystem.cpp
|
FileSystem/ProcFS/FileSystem.cpp
|
||||||
FileSystem/ProcFS/Inode.cpp
|
FileSystem/ProcFS/Inode.cpp
|
||||||
|
FileSystem/RAMFS/FileSystem.cpp
|
||||||
|
FileSystem/RAMFS/Inode.cpp
|
||||||
FileSystem/SysFS/Component.cpp
|
FileSystem/SysFS/Component.cpp
|
||||||
FileSystem/SysFS/DirectoryInode.cpp
|
FileSystem/SysFS/DirectoryInode.cpp
|
||||||
FileSystem/SysFS/FileSystem.cpp
|
FileSystem/SysFS/FileSystem.cpp
|
||||||
|
@ -196,8 +198,6 @@ set(KERNEL_SOURCES
|
||||||
FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.cpp
|
FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.cpp
|
||||||
FileSystem/SysFS/Subsystems/Kernel/Variables/StringVariable.cpp
|
FileSystem/SysFS/Subsystems/Kernel/Variables/StringVariable.cpp
|
||||||
FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.cpp
|
FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.cpp
|
||||||
FileSystem/TmpFS/FileSystem.cpp
|
|
||||||
FileSystem/TmpFS/Inode.cpp
|
|
||||||
FileSystem/VirtualFileSystem.cpp
|
FileSystem/VirtualFileSystem.cpp
|
||||||
Firmware/BIOS.cpp
|
Firmware/BIOS.cpp
|
||||||
Firmware/ACPI/Initialize.cpp
|
Firmware/ACPI/Initialize.cpp
|
||||||
|
|
40
Kernel/FileSystem/RAMFS/FileSystem.cpp
Normal file
40
Kernel/FileSystem/RAMFS/FileSystem.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
||||||
|
* Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Kernel/FileSystem/RAMFS/FileSystem.h>
|
||||||
|
#include <Kernel/FileSystem/RAMFS/Inode.h>
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
ErrorOr<NonnullLockRefPtr<FileSystem>> RAMFS::try_create()
|
||||||
|
{
|
||||||
|
return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) RAMFS));
|
||||||
|
}
|
||||||
|
|
||||||
|
RAMFS::RAMFS() = default;
|
||||||
|
RAMFS::~RAMFS() = default;
|
||||||
|
|
||||||
|
ErrorOr<void> RAMFS::initialize()
|
||||||
|
{
|
||||||
|
m_root_inode = TRY(RAMFSInode::try_create_root(*this));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Inode& RAMFS::root_inode()
|
||||||
|
{
|
||||||
|
VERIFY(!m_root_inode.is_null());
|
||||||
|
return *m_root_inode;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned RAMFS::next_inode_index()
|
||||||
|
{
|
||||||
|
MutexLocker locker(m_lock);
|
||||||
|
|
||||||
|
return m_next_inode_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
||||||
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
* Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -13,24 +13,24 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
class TmpFS final : public FileSystem {
|
class RAMFS final : public FileSystem {
|
||||||
friend class TmpFSInode;
|
friend class RAMFSInode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~TmpFS() override;
|
virtual ~RAMFS() override;
|
||||||
static ErrorOr<NonnullLockRefPtr<FileSystem>> try_create();
|
static ErrorOr<NonnullLockRefPtr<FileSystem>> try_create();
|
||||||
virtual ErrorOr<void> initialize() override;
|
virtual ErrorOr<void> initialize() override;
|
||||||
|
|
||||||
virtual StringView class_name() const override { return "TmpFS"sv; }
|
virtual StringView class_name() const override { return "RAMFS"sv; }
|
||||||
|
|
||||||
virtual bool supports_watchers() const override { return true; }
|
virtual bool supports_watchers() const override { return true; }
|
||||||
|
|
||||||
virtual Inode& root_inode() override;
|
virtual Inode& root_inode() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TmpFS();
|
RAMFS();
|
||||||
|
|
||||||
LockRefPtr<TmpFSInode> m_root_inode;
|
LockRefPtr<RAMFSInode> m_root_inode;
|
||||||
|
|
||||||
// NOTE: We start by assigning InodeIndex of 2, because 0 is invalid and 1
|
// NOTE: We start by assigning InodeIndex of 2, because 0 is invalid and 1
|
||||||
// is reserved for the root directory inode.
|
// is reserved for the root directory inode.
|
|
@ -1,16 +1,16 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
||||||
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
* Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Kernel/FileSystem/TmpFS/Inode.h>
|
#include <Kernel/FileSystem/RAMFS/Inode.h>
|
||||||
#include <Kernel/Process.h>
|
#include <Kernel/Process.h>
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
TmpFSInode::TmpFSInode(TmpFS& fs, InodeMetadata const& metadata, LockWeakPtr<TmpFSInode> parent)
|
RAMFSInode::RAMFSInode(RAMFS& fs, InodeMetadata const& metadata, LockWeakPtr<RAMFSInode> parent)
|
||||||
: Inode(fs, fs.next_inode_index())
|
: Inode(fs, fs.next_inode_index())
|
||||||
, m_metadata(metadata)
|
, m_metadata(metadata)
|
||||||
, m_parent(move(parent))
|
, m_parent(move(parent))
|
||||||
|
@ -18,7 +18,7 @@ TmpFSInode::TmpFSInode(TmpFS& fs, InodeMetadata const& metadata, LockWeakPtr<Tmp
|
||||||
m_metadata.inode = identifier();
|
m_metadata.inode = identifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
TmpFSInode::TmpFSInode(TmpFS& fs)
|
RAMFSInode::RAMFSInode(RAMFS& fs)
|
||||||
: Inode(fs, 1)
|
: Inode(fs, 1)
|
||||||
, m_root_directory_inode(true)
|
, m_root_directory_inode(true)
|
||||||
{
|
{
|
||||||
|
@ -27,29 +27,29 @@ TmpFSInode::TmpFSInode(TmpFS& fs)
|
||||||
m_metadata.atime = now;
|
m_metadata.atime = now;
|
||||||
m_metadata.ctime = now;
|
m_metadata.ctime = now;
|
||||||
m_metadata.mtime = now;
|
m_metadata.mtime = now;
|
||||||
m_metadata.mode = S_IFDIR | S_ISVTX | 0777;
|
m_metadata.mode = S_IFDIR | 0755;
|
||||||
}
|
}
|
||||||
|
|
||||||
TmpFSInode::~TmpFSInode() = default;
|
RAMFSInode::~RAMFSInode() = default;
|
||||||
|
|
||||||
ErrorOr<NonnullLockRefPtr<TmpFSInode>> TmpFSInode::try_create(TmpFS& fs, InodeMetadata const& metadata, LockWeakPtr<TmpFSInode> parent)
|
ErrorOr<NonnullLockRefPtr<RAMFSInode>> RAMFSInode::try_create(RAMFS& fs, InodeMetadata const& metadata, LockWeakPtr<RAMFSInode> parent)
|
||||||
{
|
{
|
||||||
return adopt_nonnull_lock_ref_or_enomem(new (nothrow) TmpFSInode(fs, metadata, move(parent)));
|
return adopt_nonnull_lock_ref_or_enomem(new (nothrow) RAMFSInode(fs, metadata, move(parent)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullLockRefPtr<TmpFSInode>> TmpFSInode::try_create_root(TmpFS& fs)
|
ErrorOr<NonnullLockRefPtr<RAMFSInode>> RAMFSInode::try_create_root(RAMFS& fs)
|
||||||
{
|
{
|
||||||
return adopt_nonnull_lock_ref_or_enomem(new (nothrow) TmpFSInode(fs));
|
return adopt_nonnull_lock_ref_or_enomem(new (nothrow) RAMFSInode(fs));
|
||||||
}
|
}
|
||||||
|
|
||||||
InodeMetadata TmpFSInode::metadata() const
|
InodeMetadata RAMFSInode::metadata() const
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock, Mutex::Mode::Shared);
|
MutexLocker locker(m_inode_lock, Mutex::Mode::Shared);
|
||||||
|
|
||||||
return m_metadata;
|
return m_metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
|
ErrorOr<void> RAMFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock, Mutex::Mode::Shared);
|
MutexLocker locker(m_inode_lock, Mutex::Mode::Shared);
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ ErrorOr<void> TmpFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSyste
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::replace_child(StringView name, Inode& new_child)
|
ErrorOr<void> RAMFSInode::replace_child(StringView name, Inode& new_child)
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
VERIFY(is_directory());
|
VERIFY(is_directory());
|
||||||
|
@ -80,7 +80,7 @@ ErrorOr<void> TmpFSInode::replace_child(StringView name, Inode& new_child)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
|
|
||||||
auto old_child = child->inode;
|
auto old_child = child->inode;
|
||||||
child->inode = static_cast<TmpFSInode&>(new_child);
|
child->inode = static_cast<RAMFSInode&>(new_child);
|
||||||
|
|
||||||
old_child->did_delete_self();
|
old_child->did_delete_self();
|
||||||
|
|
||||||
|
@ -89,13 +89,13 @@ ErrorOr<void> TmpFSInode::replace_child(StringView name, Inode& new_child)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullOwnPtr<TmpFSInode::DataBlock>> TmpFSInode::DataBlock::create()
|
ErrorOr<NonnullOwnPtr<RAMFSInode::DataBlock>> RAMFSInode::DataBlock::create()
|
||||||
{
|
{
|
||||||
auto data_block_buffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_with_size(DataBlock::block_size, AllocationStrategy::AllocateNow));
|
auto data_block_buffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_with_size(DataBlock::block_size, AllocationStrategy::AllocateNow));
|
||||||
return TRY(adopt_nonnull_own_or_enomem(new (nothrow) DataBlock(move(data_block_buffer_vmobject))));
|
return TRY(adopt_nonnull_own_or_enomem(new (nothrow) DataBlock(move(data_block_buffer_vmobject))));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::ensure_allocated_blocks(size_t offset, size_t io_size)
|
ErrorOr<void> RAMFSInode::ensure_allocated_blocks(size_t offset, size_t io_size)
|
||||||
{
|
{
|
||||||
VERIFY(m_inode_lock.is_locked());
|
VERIFY(m_inode_lock.is_locked());
|
||||||
size_t block_start_index = offset / DataBlock::block_size;
|
size_t block_start_index = offset / DataBlock::block_size;
|
||||||
|
@ -123,31 +123,31 @@ ErrorOr<void> TmpFSInode::ensure_allocated_blocks(size_t offset, size_t io_size)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<size_t> TmpFSInode::read_bytes_from_content_space(size_t offset, size_t io_size, UserOrKernelBuffer& buffer) const
|
ErrorOr<size_t> RAMFSInode::read_bytes_from_content_space(size_t offset, size_t io_size, UserOrKernelBuffer& buffer) const
|
||||||
{
|
{
|
||||||
VERIFY(m_inode_lock.is_locked());
|
VERIFY(m_inode_lock.is_locked());
|
||||||
VERIFY(m_metadata.size >= 0);
|
VERIFY(m_metadata.size >= 0);
|
||||||
if (static_cast<size_t>(m_metadata.size) < offset)
|
if (static_cast<size_t>(m_metadata.size) < offset)
|
||||||
return 0;
|
return 0;
|
||||||
auto mapping_region = TRY(MM.allocate_kernel_region(DataBlock::block_size, "TmpFSInode Mapping Region"sv, Memory::Region::Access::Read, AllocationStrategy::Reserve));
|
auto mapping_region = TRY(MM.allocate_kernel_region(DataBlock::block_size, "RAMFSInode Mapping Region"sv, Memory::Region::Access::Read, AllocationStrategy::Reserve));
|
||||||
return const_cast<TmpFSInode&>(*this).do_io_on_content_space(*mapping_region, offset, io_size, buffer, false);
|
return const_cast<RAMFSInode&>(*this).do_io_on_content_space(*mapping_region, offset, io_size, buffer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<size_t> TmpFSInode::read_bytes_locked(off_t offset, size_t size, UserOrKernelBuffer& buffer, OpenFileDescription*) const
|
ErrorOr<size_t> RAMFSInode::read_bytes_locked(off_t offset, size_t size, UserOrKernelBuffer& buffer, OpenFileDescription*) const
|
||||||
{
|
{
|
||||||
VERIFY(m_inode_lock.is_locked());
|
VERIFY(m_inode_lock.is_locked());
|
||||||
VERIFY(!is_directory());
|
VERIFY(!is_directory());
|
||||||
return read_bytes_from_content_space(offset, size, buffer);
|
return read_bytes_from_content_space(offset, size, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<size_t> TmpFSInode::write_bytes_to_content_space(size_t offset, size_t io_size, UserOrKernelBuffer const& buffer)
|
ErrorOr<size_t> RAMFSInode::write_bytes_to_content_space(size_t offset, size_t io_size, UserOrKernelBuffer const& buffer)
|
||||||
{
|
{
|
||||||
VERIFY(m_inode_lock.is_locked());
|
VERIFY(m_inode_lock.is_locked());
|
||||||
auto mapping_region = TRY(MM.allocate_kernel_region(DataBlock::block_size, "TmpFSInode Mapping Region"sv, Memory::Region::Access::Write, AllocationStrategy::Reserve));
|
auto mapping_region = TRY(MM.allocate_kernel_region(DataBlock::block_size, "RAMFSInode Mapping Region"sv, Memory::Region::Access::Write, AllocationStrategy::Reserve));
|
||||||
return do_io_on_content_space(*mapping_region, offset, io_size, const_cast<UserOrKernelBuffer&>(buffer), true);
|
return do_io_on_content_space(*mapping_region, offset, io_size, const_cast<UserOrKernelBuffer&>(buffer), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<size_t> TmpFSInode::write_bytes_locked(off_t offset, size_t size, UserOrKernelBuffer const& buffer, OpenFileDescription*)
|
ErrorOr<size_t> RAMFSInode::write_bytes_locked(off_t offset, size_t size, UserOrKernelBuffer const& buffer, OpenFileDescription*)
|
||||||
{
|
{
|
||||||
VERIFY(m_inode_lock.is_locked());
|
VERIFY(m_inode_lock.is_locked());
|
||||||
VERIFY(!is_directory());
|
VERIFY(!is_directory());
|
||||||
|
@ -169,7 +169,7 @@ ErrorOr<size_t> TmpFSInode::write_bytes_locked(off_t offset, size_t size, UserOr
|
||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<size_t> TmpFSInode::do_io_on_content_space(Memory::Region& mapping_region, size_t offset, size_t io_size, UserOrKernelBuffer& buffer, bool write)
|
ErrorOr<size_t> RAMFSInode::do_io_on_content_space(Memory::Region& mapping_region, size_t offset, size_t io_size, UserOrKernelBuffer& buffer, bool write)
|
||||||
{
|
{
|
||||||
VERIFY(m_inode_lock.is_locked());
|
VERIFY(m_inode_lock.is_locked());
|
||||||
size_t remaining_bytes = 0;
|
size_t remaining_bytes = 0;
|
||||||
|
@ -227,14 +227,14 @@ ErrorOr<size_t> TmpFSInode::do_io_on_content_space(Memory::Region& mapping_regio
|
||||||
return nio;
|
return nio;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::truncate_to_block_index(size_t block_index)
|
ErrorOr<void> RAMFSInode::truncate_to_block_index(size_t block_index)
|
||||||
{
|
{
|
||||||
VERIFY(m_inode_lock.is_locked());
|
VERIFY(m_inode_lock.is_locked());
|
||||||
TRY(m_blocks.try_resize(block_index));
|
TRY(m_blocks.try_resize(block_index));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullLockRefPtr<Inode>> TmpFSInode::lookup(StringView name)
|
ErrorOr<NonnullLockRefPtr<Inode>> RAMFSInode::lookup(StringView name)
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock, Mutex::Mode::Shared);
|
MutexLocker locker(m_inode_lock, Mutex::Mode::Shared);
|
||||||
VERIFY(is_directory());
|
VERIFY(is_directory());
|
||||||
|
@ -253,7 +253,7 @@ ErrorOr<NonnullLockRefPtr<Inode>> TmpFSInode::lookup(StringView name)
|
||||||
return child->inode;
|
return child->inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
TmpFSInode::Child* TmpFSInode::find_child_by_name(StringView name)
|
RAMFSInode::Child* RAMFSInode::find_child_by_name(StringView name)
|
||||||
{
|
{
|
||||||
for (auto& child : m_children) {
|
for (auto& child : m_children) {
|
||||||
if (child.name->view() == name)
|
if (child.name->view() == name)
|
||||||
|
@ -262,7 +262,7 @@ TmpFSInode::Child* TmpFSInode::find_child_by_name(StringView name)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::flush_metadata()
|
ErrorOr<void> RAMFSInode::flush_metadata()
|
||||||
{
|
{
|
||||||
// We don't really have any metadata that could become dirty.
|
// We don't really have any metadata that could become dirty.
|
||||||
// The only reason we even call set_metadata_dirty() is
|
// The only reason we even call set_metadata_dirty() is
|
||||||
|
@ -273,7 +273,7 @@ ErrorOr<void> TmpFSInode::flush_metadata()
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::chmod(mode_t mode)
|
ErrorOr<void> RAMFSInode::chmod(mode_t mode)
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
|
|
||||||
|
@ -282,7 +282,7 @@ ErrorOr<void> TmpFSInode::chmod(mode_t mode)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::chown(UserID uid, GroupID gid)
|
ErrorOr<void> RAMFSInode::chown(UserID uid, GroupID gid)
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ ErrorOr<void> TmpFSInode::chown(UserID uid, GroupID gid)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullLockRefPtr<Inode>> TmpFSInode::create_child(StringView name, mode_t mode, dev_t dev, UserID uid, GroupID gid)
|
ErrorOr<NonnullLockRefPtr<Inode>> RAMFSInode::create_child(StringView name, mode_t mode, dev_t dev, UserID uid, GroupID gid)
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
auto now = kgettimeofday();
|
auto now = kgettimeofday();
|
||||||
|
@ -307,12 +307,12 @@ ErrorOr<NonnullLockRefPtr<Inode>> TmpFSInode::create_child(StringView name, mode
|
||||||
metadata.major_device = major_from_encoded_device(dev);
|
metadata.major_device = major_from_encoded_device(dev);
|
||||||
metadata.minor_device = minor_from_encoded_device(dev);
|
metadata.minor_device = minor_from_encoded_device(dev);
|
||||||
|
|
||||||
auto child = TRY(TmpFSInode::try_create(fs(), metadata, *this));
|
auto child = TRY(RAMFSInode::try_create(fs(), metadata, *this));
|
||||||
TRY(add_child(*child, name, mode));
|
TRY(add_child(*child, name, mode));
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::add_child(Inode& child, StringView name, mode_t)
|
ErrorOr<void> RAMFSInode::add_child(Inode& child, StringView name, mode_t)
|
||||||
{
|
{
|
||||||
VERIFY(is_directory());
|
VERIFY(is_directory());
|
||||||
VERIFY(child.fsid() == fsid());
|
VERIFY(child.fsid() == fsid());
|
||||||
|
@ -329,7 +329,7 @@ ErrorOr<void> TmpFSInode::add_child(Inode& child, StringView name, mode_t)
|
||||||
auto name_kstring = TRY(KString::try_create(name));
|
auto name_kstring = TRY(KString::try_create(name));
|
||||||
// Balanced by `delete` in remove_child()
|
// Balanced by `delete` in remove_child()
|
||||||
|
|
||||||
auto* child_entry = new (nothrow) Child { move(name_kstring), static_cast<TmpFSInode&>(child) };
|
auto* child_entry = new (nothrow) Child { move(name_kstring), static_cast<RAMFSInode&>(child) };
|
||||||
if (!child_entry)
|
if (!child_entry)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ ErrorOr<void> TmpFSInode::add_child(Inode& child, StringView name, mode_t)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::remove_child(StringView name)
|
ErrorOr<void> RAMFSInode::remove_child(StringView name)
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
VERIFY(is_directory());
|
VERIFY(is_directory());
|
||||||
|
@ -359,7 +359,7 @@ ErrorOr<void> TmpFSInode::remove_child(StringView name)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::truncate(u64 size)
|
ErrorOr<void> RAMFSInode::truncate(u64 size)
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
VERIFY(!is_directory());
|
VERIFY(!is_directory());
|
||||||
|
@ -369,7 +369,7 @@ ErrorOr<void> TmpFSInode::truncate(u64 size)
|
||||||
|
|
||||||
u64 last_possible_block_index = size / DataBlock::block_size;
|
u64 last_possible_block_index = size / DataBlock::block_size;
|
||||||
if ((size % DataBlock::block_size != 0) && m_blocks[last_possible_block_index]) {
|
if ((size % DataBlock::block_size != 0) && m_blocks[last_possible_block_index]) {
|
||||||
auto mapping_region = TRY(MM.allocate_kernel_region(DataBlock::block_size, "TmpFSInode Mapping Region"sv, Memory::Region::Access::Write, AllocationStrategy::Reserve));
|
auto mapping_region = TRY(MM.allocate_kernel_region(DataBlock::block_size, "RAMFSInode Mapping Region"sv, Memory::Region::Access::Write, AllocationStrategy::Reserve));
|
||||||
VERIFY(m_blocks[last_possible_block_index]);
|
VERIFY(m_blocks[last_possible_block_index]);
|
||||||
NonnullLockRefPtr<Memory::AnonymousVMObject> block_vmobject = m_blocks[last_possible_block_index]->vmobject();
|
NonnullLockRefPtr<Memory::AnonymousVMObject> block_vmobject = m_blocks[last_possible_block_index]->vmobject();
|
||||||
mapping_region->set_vmobject(block_vmobject);
|
mapping_region->set_vmobject(block_vmobject);
|
||||||
|
@ -381,7 +381,7 @@ ErrorOr<void> TmpFSInode::truncate(u64 size)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime)
|
ErrorOr<void> RAMFSInode::update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime)
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
||||||
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
* Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -8,19 +8,20 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Kernel/FileSystem/Inode.h>
|
#include <Kernel/FileSystem/Inode.h>
|
||||||
#include <Kernel/FileSystem/TmpFS/FileSystem.h>
|
#include <Kernel/FileSystem/RAMFS/FileSystem.h>
|
||||||
|
#include <Kernel/Forward.h>
|
||||||
#include <Kernel/Memory/AnonymousVMObject.h>
|
#include <Kernel/Memory/AnonymousVMObject.h>
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
class TmpFSInode final : public Inode {
|
class RAMFSInode final : public Inode {
|
||||||
friend class TmpFS;
|
friend class RAMFS;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~TmpFSInode() override;
|
virtual ~RAMFSInode() override;
|
||||||
|
|
||||||
TmpFS& fs() { return static_cast<TmpFS&>(Inode::fs()); }
|
RAMFS& fs() { return static_cast<RAMFS&>(Inode::fs()); }
|
||||||
TmpFS const& fs() const { return static_cast<TmpFS const&>(Inode::fs()); }
|
RAMFS const& fs() const { return static_cast<RAMFS const&>(Inode::fs()); }
|
||||||
|
|
||||||
// ^Inode
|
// ^Inode
|
||||||
virtual InodeMetadata metadata() const override;
|
virtual InodeMetadata metadata() const override;
|
||||||
|
@ -37,10 +38,10 @@ public:
|
||||||
virtual ErrorOr<void> update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime) override;
|
virtual ErrorOr<void> update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TmpFSInode(TmpFS& fs, InodeMetadata const& metadata, LockWeakPtr<TmpFSInode> parent);
|
RAMFSInode(RAMFS& fs, InodeMetadata const& metadata, LockWeakPtr<RAMFSInode> parent);
|
||||||
explicit TmpFSInode(TmpFS& fs);
|
explicit RAMFSInode(RAMFS& fs);
|
||||||
static ErrorOr<NonnullLockRefPtr<TmpFSInode>> try_create(TmpFS&, InodeMetadata const& metadata, LockWeakPtr<TmpFSInode> parent);
|
static ErrorOr<NonnullLockRefPtr<RAMFSInode>> try_create(RAMFS&, InodeMetadata const& metadata, LockWeakPtr<RAMFSInode> parent);
|
||||||
static ErrorOr<NonnullLockRefPtr<TmpFSInode>> try_create_root(TmpFS&);
|
static ErrorOr<NonnullLockRefPtr<RAMFSInode>> try_create_root(RAMFS&);
|
||||||
|
|
||||||
// ^Inode
|
// ^Inode
|
||||||
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
|
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
|
||||||
|
@ -50,7 +51,7 @@ private:
|
||||||
|
|
||||||
struct Child {
|
struct Child {
|
||||||
NonnullOwnPtr<KString> name;
|
NonnullOwnPtr<KString> name;
|
||||||
NonnullLockRefPtr<TmpFSInode> inode;
|
NonnullLockRefPtr<RAMFSInode> inode;
|
||||||
IntrusiveListNode<Child> list_node {};
|
IntrusiveListNode<Child> list_node {};
|
||||||
using List = IntrusiveList<&Child::list_node>;
|
using List = IntrusiveList<&Child::list_node>;
|
||||||
};
|
};
|
||||||
|
@ -58,7 +59,7 @@ private:
|
||||||
Child* find_child_by_name(StringView);
|
Child* find_child_by_name(StringView);
|
||||||
|
|
||||||
InodeMetadata m_metadata;
|
InodeMetadata m_metadata;
|
||||||
LockWeakPtr<TmpFSInode> m_parent;
|
LockWeakPtr<RAMFSInode> m_parent;
|
||||||
|
|
||||||
ErrorOr<void> ensure_allocated_blocks(size_t offset, size_t io_size);
|
ErrorOr<void> ensure_allocated_blocks(size_t offset, size_t io_size);
|
||||||
ErrorOr<void> truncate_to_block_index(size_t block_index);
|
ErrorOr<void> truncate_to_block_index(size_t block_index);
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
|
||||||
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <Kernel/FileSystem/TmpFS/FileSystem.h>
|
|
||||||
#include <Kernel/FileSystem/TmpFS/Inode.h>
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
|
|
||||||
ErrorOr<NonnullLockRefPtr<FileSystem>> TmpFS::try_create()
|
|
||||||
{
|
|
||||||
return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) TmpFS));
|
|
||||||
}
|
|
||||||
|
|
||||||
TmpFS::TmpFS() = default;
|
|
||||||
TmpFS::~TmpFS() = default;
|
|
||||||
|
|
||||||
ErrorOr<void> TmpFS::initialize()
|
|
||||||
{
|
|
||||||
m_root_inode = TRY(TmpFSInode::try_create_root(*this));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Inode& TmpFS::root_inode()
|
|
||||||
{
|
|
||||||
VERIFY(!m_root_inode.is_null());
|
|
||||||
return *m_root_inode;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned TmpFS::next_inode_index()
|
|
||||||
{
|
|
||||||
MutexLocker locker(m_lock);
|
|
||||||
|
|
||||||
return m_next_inode_index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -49,6 +49,7 @@ class ProcFSSystemBoolean;
|
||||||
class ProcFSSystemDirectory;
|
class ProcFSSystemDirectory;
|
||||||
class Process;
|
class Process;
|
||||||
class ProcessGroup;
|
class ProcessGroup;
|
||||||
|
class RAMFS;
|
||||||
template<LockRank Rank>
|
template<LockRank Rank>
|
||||||
class RecursiveSpinlock;
|
class RecursiveSpinlock;
|
||||||
class Scheduler;
|
class Scheduler;
|
||||||
|
@ -64,7 +65,7 @@ class TCPSocket;
|
||||||
class TTY;
|
class TTY;
|
||||||
class Thread;
|
class Thread;
|
||||||
class ThreadTracer;
|
class ThreadTracer;
|
||||||
class TmpFSInode;
|
class RAMFSInode;
|
||||||
class UDPSocket;
|
class UDPSocket;
|
||||||
class UserOrKernelBuffer;
|
class UserOrKernelBuffer;
|
||||||
class VirtualFileSystem;
|
class VirtualFileSystem;
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
#include <Kernel/FileSystem/ISO9660FS/FileSystem.h>
|
#include <Kernel/FileSystem/ISO9660FS/FileSystem.h>
|
||||||
#include <Kernel/FileSystem/Plan9FS/FileSystem.h>
|
#include <Kernel/FileSystem/Plan9FS/FileSystem.h>
|
||||||
#include <Kernel/FileSystem/ProcFS/FileSystem.h>
|
#include <Kernel/FileSystem/ProcFS/FileSystem.h>
|
||||||
|
#include <Kernel/FileSystem/RAMFS/FileSystem.h>
|
||||||
#include <Kernel/FileSystem/SysFS/FileSystem.h>
|
#include <Kernel/FileSystem/SysFS/FileSystem.h>
|
||||||
#include <Kernel/FileSystem/TmpFS/FileSystem.h>
|
|
||||||
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
||||||
#include <Kernel/Process.h>
|
#include <Kernel/Process.h>
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ static constexpr FileSystemInitializer s_initializers[] = {
|
||||||
{ "proc"sv, "ProcFS"sv, false, false, false, {}, ProcFS::try_create },
|
{ "proc"sv, "ProcFS"sv, false, false, false, {}, ProcFS::try_create },
|
||||||
{ "devpts"sv, "DevPtsFS"sv, false, false, false, {}, DevPtsFS::try_create },
|
{ "devpts"sv, "DevPtsFS"sv, false, false, false, {}, DevPtsFS::try_create },
|
||||||
{ "sys"sv, "SysFS"sv, false, false, false, {}, SysFS::try_create },
|
{ "sys"sv, "SysFS"sv, false, false, false, {}, SysFS::try_create },
|
||||||
{ "tmp"sv, "TmpFS"sv, false, false, false, {}, TmpFS::try_create },
|
{ "ram"sv, "RAMFS"sv, false, false, false, {}, RAMFS::try_create },
|
||||||
{ "ext2"sv, "Ext2FS"sv, true, true, true, Ext2FS::try_create, {} },
|
{ "ext2"sv, "Ext2FS"sv, true, true, true, Ext2FS::try_create, {} },
|
||||||
{ "9p"sv, "Plan9FS"sv, true, true, true, Plan9FS::try_create, {} },
|
{ "9p"sv, "Plan9FS"sv, true, true, true, Plan9FS::try_create, {} },
|
||||||
{ "iso9660"sv, "ISO9660FS"sv, true, true, true, ISO9660FS::try_create, {} },
|
{ "iso9660"sv, "ISO9660FS"sv, true, true, true, ISO9660FS::try_create, {} },
|
||||||
|
|
|
@ -389,7 +389,11 @@ static ErrorOr<void> prepare_synthetic_filesystems()
|
||||||
// FIXME: Find a better way to all of this stuff, without hardcoding all of this!
|
// FIXME: Find a better way to all of this stuff, without hardcoding all of this!
|
||||||
TRY(Core::System::mount(-1, "/proc"sv, "proc"sv, MS_NOSUID));
|
TRY(Core::System::mount(-1, "/proc"sv, "proc"sv, MS_NOSUID));
|
||||||
TRY(Core::System::mount(-1, "/sys"sv, "sys"sv, 0));
|
TRY(Core::System::mount(-1, "/sys"sv, "sys"sv, 0));
|
||||||
TRY(Core::System::mount(-1, "/dev"sv, "tmp"sv, MS_NOSUID | MS_NOEXEC | MS_NOREGULAR));
|
TRY(Core::System::mount(-1, "/dev"sv, "ram"sv, MS_NOSUID | MS_NOEXEC | MS_NOREGULAR));
|
||||||
|
|
||||||
|
TRY(Core::System::mount(-1, "/tmp"sv, "ram"sv, MS_NOSUID | MS_NODEV));
|
||||||
|
// NOTE: Set /tmp to have a sticky bit with 0777 permissions.
|
||||||
|
TRY(Core::System::chmod("/tmp"sv, 01777));
|
||||||
|
|
||||||
TRY(Core::System::mkdir("/dev/audio"sv, 0755));
|
TRY(Core::System::mkdir("/dev/audio"sv, 0755));
|
||||||
TRY(Core::System::mkdir("/dev/input"sv, 0755));
|
TRY(Core::System::mkdir("/dev/input"sv, 0755));
|
||||||
|
|
Loading…
Reference in a new issue