Files
serenity/Kernel/FileSystem/ProcFS/Inode.h
implicitfield 0e94887b2c Kernel/VFS: Make filesystem implementations responsible for renames
Previously, the VFS layer would try to handle renames more-or-less by
itself, which really only worked for ext2, and even that was only due to
the replace_child kludge existing specifically for this purpose. This
never worked properly for FATFS, since the VFS layer effectively
depended on filesystems having some kind of reference-counting for
inodes, which is something that simply doesn't exist on any FAT variant
we support.

To resolve various issues with the existing scheme, this commit makes
filesystem implementations themselves responsible for the actual rename
operation, while keeping all the existing validation inside the VFS
layer. The only intended behavior change here is that rename operations
should actually properly work on FATFS.
2024-12-17 19:02:15 -05:00

82 lines
3.2 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <Kernel/FileSystem/Inode.h>
#include <Kernel/FileSystem/OpenFileDescription.h>
#include <Kernel/FileSystem/ProcFS/Definitions.h>
#include <Kernel/FileSystem/ProcFS/FileSystem.h>
#include <Kernel/Library/KBufferBuilder.h>
#include <Kernel/UnixTypes.h>
namespace Kernel {
struct ProcFSInodeData : public OpenFileDescriptionData {
OwnPtr<KBuffer> buffer;
};
class ProcFSInode final : public Inode {
friend class ProcFS;
public:
enum class Type {
RootDirectory,
SelfProcessLink,
ProcessProperty,
ProcessDirectory,
ProcessSubdirectory,
};
static InodeIndex create_index_from_global_directory_entry(segmented_global_inode_index entry);
static InodeIndex create_index_from_process_directory_entry(ProcessID pid, segmented_process_directory_entry entry);
virtual ~ProcFSInode() override;
private:
ProcFSInode(ProcFS const&, InodeIndex);
ProcFS& procfs() { return static_cast<ProcFS&>(Inode::fs()); }
ProcFS const& procfs() const { return static_cast<ProcFS const&>(Inode::fs()); }
// ^Inode (EROFS handling)
virtual ErrorOr<NonnullRefPtr<Inode>> create_child(StringView, mode_t, dev_t, UserID, GroupID) override { return EROFS; }
virtual ErrorOr<void> add_child(Inode&, StringView, mode_t) override { return EROFS; }
virtual ErrorOr<void> remove_child(StringView) override { return EROFS; }
virtual ErrorOr<void> chmod(mode_t) override { return EROFS; }
virtual ErrorOr<void> chown(UserID, GroupID) override { return EROFS; }
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) override { return EROFS; }
virtual ErrorOr<void> truncate_locked(u64) override { return EROFS; }
// ^Inode (Silent ignore handling)
virtual ErrorOr<void> flush_metadata() override { return {}; }
virtual ErrorOr<void> update_timestamps(Optional<UnixDateTime>, Optional<UnixDateTime>, Optional<UnixDateTime>) override { return {}; }
// ^Inode
virtual ErrorOr<void> attach(OpenFileDescription& description) override;
virtual void did_seek(OpenFileDescription&, off_t) override;
ErrorOr<void> traverse_as_root_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual InodeMetadata metadata() const override;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
ErrorOr<NonnullRefPtr<Inode>> lookup_as_root_directory(StringView name);
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override final;
ErrorOr<void> refresh_process_property_data(OpenFileDescription& description);
ErrorOr<void> try_fetch_process_property_data(NonnullRefPtr<Process>, KBufferBuilder& builder) const;
Type m_type;
Optional<ProcessID> const m_associated_pid {};
u16 const m_subdirectory { 0 };
u32 const m_property { 0 };
mutable Mutex m_refresh_lock;
};
}