2020-01-18 09:38:21 +01:00
|
|
|
/*
|
2020-01-24 16:45:29 +03:00
|
|
|
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
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.
2023-01-28 19:00:54 +02:00
|
|
|
* Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il>
|
2020-01-18 09:38:21 +01:00
|
|
|
*
|
2021-04-22 01:24:48 -07:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-01-18 09:38:21 +01:00
|
|
|
*/
|
|
|
|
|
2019-08-15 18:16:45 +03:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <Kernel/FileSystem/Inode.h>
|
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.
2023-01-28 19:00:54 +02:00
|
|
|
#include <Kernel/FileSystem/RAMFS/FileSystem.h>
|
|
|
|
#include <Kernel/Forward.h>
|
2022-09-09 06:58:44 +03:00
|
|
|
#include <Kernel/Memory/AnonymousVMObject.h>
|
2019-08-15 18:16:45 +03:00
|
|
|
|
2020-02-16 01:27:42 +01:00
|
|
|
namespace Kernel {
|
|
|
|
|
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.
2023-01-28 19:00:54 +02:00
|
|
|
class RAMFSInode final : public Inode {
|
|
|
|
friend class RAMFS;
|
2019-08-15 18:16:45 +03:00
|
|
|
|
|
|
|
public:
|
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.
2023-01-28 19:00:54 +02:00
|
|
|
virtual ~RAMFSInode() override;
|
2019-08-15 18:16:45 +03: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.
2023-01-28 19:00:54 +02:00
|
|
|
RAMFS& fs() { return static_cast<RAMFS&>(Inode::fs()); }
|
|
|
|
RAMFS const& fs() const { return static_cast<RAMFS const&>(Inode::fs()); }
|
2019-08-15 18:16:45 +03:00
|
|
|
|
|
|
|
// ^Inode
|
|
|
|
virtual InodeMetadata metadata() const override;
|
2021-11-10 15:42:39 +01:00
|
|
|
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
|
2023-03-07 12:25:00 +01:00
|
|
|
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
|
2021-11-08 00:51:39 +01:00
|
|
|
virtual ErrorOr<void> flush_metadata() override;
|
2023-03-07 12:25:00 +01:00
|
|
|
virtual ErrorOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
|
2021-11-11 00:55:02 +01:00
|
|
|
virtual ErrorOr<void> add_child(Inode&, StringView name, mode_t) override;
|
|
|
|
virtual ErrorOr<void> remove_child(StringView name) override;
|
2022-10-08 11:22:12 +02:00
|
|
|
virtual ErrorOr<void> replace_child(StringView name, Inode& child) override;
|
2021-11-08 00:51:39 +01:00
|
|
|
virtual ErrorOr<void> chmod(mode_t) override;
|
|
|
|
virtual ErrorOr<void> chown(UserID, GroupID) override;
|
|
|
|
virtual ErrorOr<void> truncate(u64) override;
|
2022-11-22 21:01:45 +01:00
|
|
|
virtual ErrorOr<void> update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime) override;
|
2019-08-15 18:16:45 +03:00
|
|
|
|
|
|
|
private:
|
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.
2023-01-28 19:00:54 +02:00
|
|
|
RAMFSInode(RAMFS& fs, InodeMetadata const& metadata, LockWeakPtr<RAMFSInode> parent);
|
|
|
|
explicit RAMFSInode(RAMFS& fs);
|
2023-03-07 12:25:00 +01:00
|
|
|
static ErrorOr<NonnullRefPtr<RAMFSInode>> try_create(RAMFS&, InodeMetadata const& metadata, LockWeakPtr<RAMFSInode> parent);
|
|
|
|
static ErrorOr<NonnullRefPtr<RAMFSInode>> try_create_root(RAMFS&);
|
2020-06-24 23:35:56 +03:00
|
|
|
|
2022-08-06 04:22:20 +03:00
|
|
|
// ^Inode
|
|
|
|
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
|
|
|
|
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
|
|
|
|
|
2022-09-09 06:58:44 +03:00
|
|
|
ErrorOr<size_t> do_io_on_content_space(Memory::Region& mapping_region, size_t offset, size_t io_size, UserOrKernelBuffer& buffer, bool write);
|
|
|
|
|
2021-07-18 13:47:18 +02:00
|
|
|
struct Child {
|
|
|
|
NonnullOwnPtr<KString> name;
|
2023-03-07 12:25:00 +01:00
|
|
|
NonnullRefPtr<RAMFSInode> inode;
|
2021-07-18 13:47:18 +02:00
|
|
|
IntrusiveListNode<Child> list_node {};
|
2021-09-09 16:30:59 +04:30
|
|
|
using List = IntrusiveList<&Child::list_node>;
|
2021-07-18 13:47:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
Child* find_child_by_name(StringView);
|
|
|
|
|
2019-08-15 18:16:45 +03:00
|
|
|
InodeMetadata m_metadata;
|
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.
2023-01-28 19:00:54 +02:00
|
|
|
LockWeakPtr<RAMFSInode> m_parent;
|
2019-08-15 18:16:45 +03:00
|
|
|
|
2022-09-09 06:58:44 +03:00
|
|
|
ErrorOr<void> ensure_allocated_blocks(size_t offset, size_t io_size);
|
|
|
|
ErrorOr<void> truncate_to_block_index(size_t block_index);
|
|
|
|
ErrorOr<size_t> read_bytes_from_content_space(size_t offset, size_t io_size, UserOrKernelBuffer& buffer) const;
|
|
|
|
ErrorOr<size_t> write_bytes_to_content_space(size_t offset, size_t io_size, UserOrKernelBuffer const& buffer);
|
|
|
|
|
|
|
|
struct DataBlock {
|
|
|
|
public:
|
|
|
|
using List = Vector<OwnPtr<DataBlock>>;
|
|
|
|
|
|
|
|
static ErrorOr<NonnullOwnPtr<DataBlock>> create();
|
|
|
|
|
|
|
|
constexpr static size_t block_size = 128 * KiB;
|
|
|
|
|
|
|
|
Memory::AnonymousVMObject& vmobject() { return *m_content_buffer_vmobject; }
|
|
|
|
Memory::AnonymousVMObject const& vmobject() const { return *m_content_buffer_vmobject; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
explicit DataBlock(NonnullLockRefPtr<Memory::AnonymousVMObject> content_buffer_vmobject)
|
|
|
|
: m_content_buffer_vmobject(move(content_buffer_vmobject))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NonnullLockRefPtr<Memory::AnonymousVMObject> m_content_buffer_vmobject;
|
|
|
|
};
|
2021-07-18 13:47:18 +02:00
|
|
|
|
2022-12-04 10:27:19 +02:00
|
|
|
bool const m_root_directory_inode { false };
|
|
|
|
|
2022-09-09 06:58:44 +03:00
|
|
|
DataBlock::List m_blocks;
|
2021-07-18 13:47:18 +02:00
|
|
|
Child::List m_children;
|
2019-08-15 18:16:45 +03:00
|
|
|
};
|
2020-02-16 01:27:42 +01:00
|
|
|
|
|
|
|
}
|