mirror of
https://github.com/SerenityOS/serenity
synced 2026-05-09 00:22:43 +02:00
Instead of using a raw `KBuffer` and letting each implementation to populating the specific flags on its own, we change things so we only let each FileSystem implementation to validate the flag and its value but then store it in a HashMap which its key is the flag name and the value is a special new class called `FileSystemSpecificOption` which wraps around `AK::Variant<...>`. This approach has multiple advantages over the previous: - It allows runtime inspection of what the user has set on a `MountFile` description for a specific filesystem. - It ensures accidental overriding of filesystem specific option that was already set is not possible - It removes ugly casting of a `KBuffer` contents to a strongly-typed values. Instead, a strongly-typed `AK::Variant` is used which ensures we always get a value without doing any casting. Please note that we have removed support for ASCII string-oriented flags as there were no actual use cases, and supporting such type would make `FileSystemSpecificOption` more complicated unnecessarily for now.
70 lines
2.3 KiB
C++
70 lines
2.3 KiB
C++
/*
|
|
* Copyright (c) 2021, sin-ack <sin-ack@protonmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/EnumBits.h>
|
|
#include <AK/Error.h>
|
|
#include <AK/HashMap.h>
|
|
#include <AK/RecursionDecision.h>
|
|
#include <AK/StringView.h>
|
|
#include <AK/Types.h>
|
|
#include <Kernel/FileSystem/BlockBasedFileSystem.h>
|
|
#include <Kernel/FileSystem/FileSystemSpecificOption.h>
|
|
#include <Kernel/FileSystem/ISO9660FS/Definitions.h>
|
|
#include <Kernel/FileSystem/ISO9660FS/DirectoryEntry.h>
|
|
#include <Kernel/FileSystem/Inode.h>
|
|
#include <Kernel/Library/KBuffer.h>
|
|
#include <Kernel/Library/NonnullLockRefPtr.h>
|
|
|
|
namespace Kernel {
|
|
|
|
class ISO9660Inode;
|
|
class ISO9660DirectoryIterator;
|
|
|
|
class ISO9660FS final : public BlockBasedFileSystem {
|
|
friend ISO9660Inode;
|
|
friend ISO9660DirectoryIterator;
|
|
|
|
public:
|
|
static ErrorOr<NonnullRefPtr<FileSystem>> try_create(OpenFileDescription&, FileSystemSpecificOptions const&);
|
|
|
|
virtual ~ISO9660FS() override;
|
|
virtual StringView class_name() const override { return "ISO9660FS"sv; }
|
|
virtual Inode& root_inode() override;
|
|
|
|
virtual unsigned total_block_count() const override;
|
|
virtual unsigned total_inode_count() const override;
|
|
|
|
virtual u8 internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const override;
|
|
|
|
ErrorOr<NonnullLockRefPtr<ISO9660FSDirectoryEntry>> directory_entry_for_record(Badge<ISO9660DirectoryIterator>, ISO::DirectoryRecordHeader const* record);
|
|
|
|
private:
|
|
ISO9660FS(OpenFileDescription&);
|
|
|
|
virtual ErrorOr<void> prepare_to_clear_last_mount(Inode&) override;
|
|
|
|
virtual bool is_initialized_while_locked() override;
|
|
virtual ErrorOr<void> initialize_while_locked() override;
|
|
|
|
ErrorOr<void> parse_volume_set();
|
|
ErrorOr<void> create_root_inode();
|
|
ErrorOr<void> calculate_inode_count() const;
|
|
|
|
u32 calculate_directory_entry_cache_key(ISO::DirectoryRecordHeader const&);
|
|
|
|
ErrorOr<void> visit_directory_record(ISO::DirectoryRecordHeader const& record, Function<ErrorOr<RecursionDecision>(ISO::DirectoryRecordHeader const*)> const& visitor) const;
|
|
|
|
OwnPtr<ISO::PrimaryVolumeDescriptor> m_primary_volume;
|
|
RefPtr<ISO9660Inode> m_root_inode;
|
|
|
|
mutable u32 m_cached_inode_count { 0 };
|
|
HashMap<u32, NonnullLockRefPtr<ISO9660FSDirectoryEntry>> m_directory_entry_cache;
|
|
};
|
|
|
|
}
|