2020-01-18 05:38:21 -03:00
|
|
|
/*
|
2020-01-24 10:45:29 -03:00
|
|
|
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
2021-08-16 17:13:58 -03:00
|
|
|
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
2020-01-18 05:38:21 -03:00
|
|
|
*
|
2021-04-22 05:24:48 -03:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-01-18 05:38:21 -03:00
|
|
|
*/
|
|
|
|
|
|
2021-09-11 03:19:20 -03:00
|
|
|
#include <Kernel/Devices/DeviceManagement.h>
|
2022-10-24 04:38:41 -03:00
|
|
|
#include <Kernel/FileSystem/DevPtsFS/Inode.h>
|
Kernel/FileSystem: Send proper filetypes when traversing RAM-backed FSes
SysFS, ProcFS and DevPtsFS were all sending filetype 0 when traversing
their directories, but it is actually very easy to send proper filetypes
in these filesystems.
This patch binds all RAM backed filesystems to use only one enum for
their internal filetype, to simplify the implementation and allow
sharing of code.
Please note that the Plan9FS case is currently not solved as I am not
familiar with this filesystem and its constructs.
The ProcFS mostly keeps track of the filetype, and a fix was needed for
the /proc root directory - all processes exhibit a directory inside it
which makes it very easy to hardcode the directory filetype for them.
There's also the `self` symlink inode which is now exposed as DT_LNK.
As for SysFS, we could leverage the fact everything inherits from the
SysFSComponent class, so we could have a virtual const method to return
the proper filetype.
Most of the files in SysFS are "regular" files though, so the base class
has a non-pure virtual method.
Lastly, the DevPtsFS simply hardcodes '.' and '..' as directory file
type, and everything else is hardcoded to send the character device file
type, as this filesystem is only exposing character pts device files.
2024-01-05 06:18:02 -03:00
|
|
|
#include <Kernel/FileSystem/RAMBackedFileType.h>
|
2019-01-29 21:49:20 -02:00
|
|
|
|
2020-02-15 21:27:42 -03:00
|
|
|
namespace Kernel {
|
|
|
|
|
|
2021-02-12 05:18:47 -03:00
|
|
|
static InodeIndex pty_index_to_inode_index(unsigned pty_index)
|
2019-08-16 12:46:18 -03:00
|
|
|
{
|
|
|
|
|
return pty_index + 2;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-04 16:19:31 -03:00
|
|
|
// NOTE: This constructor is used for the root inode only.
|
|
|
|
|
DevPtsFSInode::DevPtsFSInode(DevPtsFS& fs)
|
|
|
|
|
: Inode(fs, 1)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DevPtsFSInode::DevPtsFSInode(DevPtsFS& fs, InodeIndex index, SlavePTY& pty)
|
2019-08-16 12:46:18 -03:00
|
|
|
: Inode(fs, index)
|
2024-03-04 16:19:31 -03:00
|
|
|
, m_pty(pty)
|
2019-08-16 12:46:18 -03:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-16 16:15:15 -03:00
|
|
|
DevPtsFSInode::~DevPtsFSInode() = default;
|
2019-08-16 12:46:18 -03:00
|
|
|
|
2022-08-05 22:22:20 -03:00
|
|
|
ErrorOr<size_t> DevPtsFSInode::read_bytes_locked(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const
|
2019-08-16 12:46:18 -03:00
|
|
|
{
|
2021-02-23 16:42:32 -03:00
|
|
|
VERIFY_NOT_REACHED();
|
2019-08-16 12:46:18 -03:00
|
|
|
}
|
|
|
|
|
|
2022-08-05 22:22:20 -03:00
|
|
|
ErrorOr<size_t> DevPtsFSInode::write_bytes_locked(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*)
|
2019-08-16 12:46:18 -03:00
|
|
|
{
|
2021-02-23 16:42:32 -03:00
|
|
|
VERIFY_NOT_REACHED();
|
2019-08-16 12:46:18 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InodeMetadata DevPtsFSInode::metadata() const
|
|
|
|
|
{
|
AK: Make RefPtr, NonnullRefPtr, WeakPtr thread safe
This makes most operations thread safe, especially so that they
can safely be used in the Kernel. This includes obtaining a strong
reference from a weak reference, which now requires an explicit
call to WeakPtr::strong_ref(). Another major change is that
Weakable::make_weak_ref() may require the explicit target type.
Previously we used reinterpret_cast in WeakPtr, assuming that it
can be properly converted. But WeakPtr does not necessarily have
the knowledge to be able to do this. Instead, we now ask the class
itself to deliver a WeakPtr to the type that we want.
Also, WeakLink is no longer specific to a target type. The reason
for this is that we want to be able to safely convert e.g. WeakPtr<T>
to WeakPtr<U>, and before this we just reinterpret_cast the internal
WeakLink<T> to WeakLink<U>, which is a bold assumption that it would
actually produce the correct code. Instead, WeakLink now operates
on just a raw pointer and we only make those constructors/operators
available if we can verify that it can be safely cast.
In order to guarantee thread safety, we now use the least significant
bit in the pointer for locking purposes. This also means that only
properly aligned pointers can be used.
2020-09-29 19:26:13 -03:00
|
|
|
if (auto pty = m_pty.strong_ref()) {
|
2020-09-06 13:48:24 -03:00
|
|
|
auto metadata = m_metadata;
|
2023-03-13 18:11:13 -03:00
|
|
|
metadata.mtime = pty->time_of_last_write();
|
2020-09-06 13:48:24 -03:00
|
|
|
return metadata;
|
|
|
|
|
}
|
2019-08-16 12:46:18 -03:00
|
|
|
return m_metadata;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-10 11:42:39 -03:00
|
|
|
ErrorOr<void> DevPtsFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
|
2019-08-16 12:46:18 -03:00
|
|
|
{
|
|
|
|
|
if (identifier().index() > 1)
|
2021-01-20 19:11:17 -03:00
|
|
|
return ENOTDIR;
|
2019-08-16 12:46:18 -03:00
|
|
|
|
Kernel/FileSystem: Send proper filetypes when traversing RAM-backed FSes
SysFS, ProcFS and DevPtsFS were all sending filetype 0 when traversing
their directories, but it is actually very easy to send proper filetypes
in these filesystems.
This patch binds all RAM backed filesystems to use only one enum for
their internal filetype, to simplify the implementation and allow
sharing of code.
Please note that the Plan9FS case is currently not solved as I am not
familiar with this filesystem and its constructs.
The ProcFS mostly keeps track of the filetype, and a fix was needed for
the /proc root directory - all processes exhibit a directory inside it
which makes it very easy to hardcode the directory filetype for them.
There's also the `self` symlink inode which is now exposed as DT_LNK.
As for SysFS, we could leverage the fact everything inherits from the
SysFSComponent class, so we could have a virtual const method to return
the proper filetype.
Most of the files in SysFS are "regular" files though, so the base class
has a non-pure virtual method.
Lastly, the DevPtsFS simply hardcodes '.' and '..' as directory file
type, and everything else is hardcoded to send the character device file
type, as this filesystem is only exposing character pts device files.
2024-01-05 06:18:02 -03:00
|
|
|
TRY(callback({ "."sv, identifier(), to_underlying(RAMBackedFileType::Directory) }));
|
|
|
|
|
TRY(callback({ ".."sv, identifier(), to_underlying(RAMBackedFileType::Directory) }));
|
2019-08-16 12:46:18 -03:00
|
|
|
|
2021-11-10 11:42:39 -03:00
|
|
|
return SlavePTY::all_instances().with([&](auto& list) -> ErrorOr<void> {
|
2022-01-09 07:59:20 -03:00
|
|
|
StringBuilder builder;
|
2021-08-16 17:13:58 -03:00
|
|
|
for (SlavePTY& slave_pty : list) {
|
2022-01-09 07:59:20 -03:00
|
|
|
builder.clear();
|
|
|
|
|
TRY(builder.try_appendff("{}", slave_pty.index()));
|
Kernel/FileSystem: Send proper filetypes when traversing RAM-backed FSes
SysFS, ProcFS and DevPtsFS were all sending filetype 0 when traversing
their directories, but it is actually very easy to send proper filetypes
in these filesystems.
This patch binds all RAM backed filesystems to use only one enum for
their internal filetype, to simplify the implementation and allow
sharing of code.
Please note that the Plan9FS case is currently not solved as I am not
familiar with this filesystem and its constructs.
The ProcFS mostly keeps track of the filetype, and a fix was needed for
the /proc root directory - all processes exhibit a directory inside it
which makes it very easy to hardcode the directory filetype for them.
There's also the `self` symlink inode which is now exposed as DT_LNK.
As for SysFS, we could leverage the fact everything inherits from the
SysFSComponent class, so we could have a virtual const method to return
the proper filetype.
Most of the files in SysFS are "regular" files though, so the base class
has a non-pure virtual method.
Lastly, the DevPtsFS simply hardcodes '.' and '..' as directory file
type, and everything else is hardcoded to send the character device file
type, as this filesystem is only exposing character pts device files.
2024-01-05 06:18:02 -03:00
|
|
|
// NOTE: We represent directory entries with DT_CHR as all
|
|
|
|
|
// inodes in this filesystem are assumed to be char devices.
|
|
|
|
|
TRY(callback({ builder.string_view(), { fsid(), pty_index_to_inode_index(slave_pty.index()) }, to_underlying(RAMBackedFileType::Character) }));
|
2021-08-16 17:13:58 -03:00
|
|
|
}
|
2021-11-10 11:42:39 -03:00
|
|
|
return {};
|
2021-08-16 17:13:58 -03:00
|
|
|
});
|
2019-08-16 12:46:18 -03:00
|
|
|
}
|
|
|
|
|
|
2023-03-07 08:25:00 -03:00
|
|
|
ErrorOr<NonnullRefPtr<Inode>> DevPtsFSInode::lookup(StringView name)
|
2019-08-16 12:46:18 -03:00
|
|
|
{
|
2021-02-23 16:42:32 -03:00
|
|
|
VERIFY(identifier().index() == 1);
|
2019-08-16 12:46:18 -03:00
|
|
|
|
|
|
|
|
if (name == "." || name == "..")
|
2021-08-14 08:32:35 -03:00
|
|
|
return *this;
|
2020-06-24 17:35:56 -03:00
|
|
|
|
2023-12-22 23:59:14 -03:00
|
|
|
auto pty_index = name.to_number<unsigned>();
|
2021-08-16 17:13:58 -03:00
|
|
|
if (!pty_index.has_value())
|
|
|
|
|
return ENOENT;
|
|
|
|
|
|
2023-03-07 08:25:00 -03:00
|
|
|
return SlavePTY::all_instances().with([&](auto& list) -> ErrorOr<NonnullRefPtr<Inode>> {
|
2021-08-16 17:13:58 -03:00
|
|
|
for (SlavePTY& slave_pty : list) {
|
|
|
|
|
if (slave_pty.index() != pty_index.value())
|
|
|
|
|
continue;
|
2021-09-05 13:55:55 -03:00
|
|
|
return fs().get_inode({ fsid(), pty_index_to_inode_index(pty_index.value()) });
|
2021-08-16 17:13:58 -03:00
|
|
|
}
|
|
|
|
|
return ENOENT;
|
|
|
|
|
});
|
2019-08-16 12:46:18 -03:00
|
|
|
}
|
|
|
|
|
|
2021-11-07 20:51:39 -03:00
|
|
|
ErrorOr<void> DevPtsFSInode::flush_metadata()
|
2019-08-16 12:46:18 -03:00
|
|
|
{
|
2021-11-07 20:51:39 -03:00
|
|
|
return {};
|
2019-08-16 12:46:18 -03:00
|
|
|
}
|
|
|
|
|
|
2021-11-10 20:55:02 -03:00
|
|
|
ErrorOr<void> DevPtsFSInode::add_child(Inode&, StringView, mode_t)
|
2020-06-24 17:35:56 -03:00
|
|
|
{
|
2021-01-20 19:11:17 -03:00
|
|
|
return EROFS;
|
2020-06-24 17:35:56 -03:00
|
|
|
}
|
|
|
|
|
|
2023-03-07 08:25:00 -03:00
|
|
|
ErrorOr<NonnullRefPtr<Inode>> DevPtsFSInode::create_child(StringView, mode_t, dev_t, UserID, GroupID)
|
2019-08-16 12:46:18 -03:00
|
|
|
{
|
2021-01-20 19:11:17 -03:00
|
|
|
return EROFS;
|
2019-08-16 12:46:18 -03:00
|
|
|
}
|
|
|
|
|
|
2021-11-10 20:55:02 -03:00
|
|
|
ErrorOr<void> DevPtsFSInode::remove_child(StringView)
|
2019-08-16 12:46:18 -03:00
|
|
|
{
|
2021-01-20 19:11:17 -03:00
|
|
|
return EROFS;
|
2019-08-16 12:46:18 -03:00
|
|
|
}
|
|
|
|
|
|
2022-10-08 06:22:12 -03:00
|
|
|
ErrorOr<void> DevPtsFSInode::replace_child(StringView, Inode&)
|
|
|
|
|
{
|
|
|
|
|
return EROFS;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-07 20:51:39 -03:00
|
|
|
ErrorOr<void> DevPtsFSInode::chmod(mode_t)
|
2019-08-16 12:46:18 -03:00
|
|
|
{
|
2021-04-29 22:39:39 -03:00
|
|
|
return EROFS;
|
2019-08-16 12:46:18 -03:00
|
|
|
}
|
|
|
|
|
|
2021-11-07 20:51:39 -03:00
|
|
|
ErrorOr<void> DevPtsFSInode::chown(UserID, GroupID)
|
2019-08-16 12:46:18 -03:00
|
|
|
{
|
2021-04-29 22:39:39 -03:00
|
|
|
return EROFS;
|
2019-01-29 21:49:20 -02:00
|
|
|
}
|
2020-02-15 21:27:42 -03:00
|
|
|
|
|
|
|
|
}
|