Files
serenity/Kernel/FileSystem/ISO9660FS/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

63 lines
2.6 KiB
C++

/*
* Copyright (c) 2021, sin-ack <sin-ack@protonmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <Kernel/FileSystem/ISO9660FS/FileSystem.h>
#include <Kernel/FileSystem/Inode.h>
namespace Kernel {
class ISO9660Inode final : public Inode {
friend ISO9660FS;
public:
virtual ~ISO9660Inode() override;
ISO9660FS& fs() { return static_cast<ISO9660FS&>(Inode::fs()); }
ISO9660FS const& fs() const { return static_cast<ISO9660FS const&>(Inode::fs()); }
// ^Inode
virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override;
virtual ErrorOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
virtual ErrorOr<void> add_child(Inode&, StringView name, mode_t) override;
virtual ErrorOr<void> remove_child(StringView name) override;
virtual ErrorOr<void> chmod(mode_t) override;
virtual ErrorOr<void> chown(UserID, GroupID) override;
virtual ErrorOr<void> truncate_locked(u64) override;
virtual ErrorOr<void> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime) override;
private:
// HACK: The base ISO 9660 standard says the maximum filename length is 37
// bytes large; however, we can read filenames longer than that right now
// without any problems, so let's allow it anyway.
static constexpr size_t max_file_identifier_length = 256 - sizeof(ISO::DirectoryRecordHeader);
// ^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;
ISO9660Inode(ISO9660FS&, ISO::DirectoryRecordHeader const& record, StringView name);
static ErrorOr<NonnullRefPtr<ISO9660Inode>> try_create_from_directory_record(ISO9660FS&, ISO::DirectoryRecordHeader const& record, StringView name);
static InodeIndex get_inode_index(ISO::DirectoryRecordHeader const& record, StringView name);
static StringView get_normalized_filename(ISO::DirectoryRecordHeader const& record, Bytes buffer);
void create_metadata();
UnixDateTime parse_numerical_date_time(ISO::NumericalDateAndTime const&);
InodeMetadata m_metadata;
ISO::DirectoryRecordHeader m_record;
};
}
using Kernel::ISO::has_any_flag;
using Kernel::ISO::has_flag;