From 961c6d09326162b22d07f570c56dadadcbeaea41 Mon Sep 17 00:00:00 2001 From: koolkdev Date: Tue, 19 Nov 2024 21:33:07 +0200 Subject: [PATCH] Rename Attributes to EntryMetadata --- include/wfslib/directory.h | 2 +- include/wfslib/entry.h | 26 ++++++------ include/wfslib/file.h | 4 +- include/wfslib/link.h | 4 +- src/directory.cpp | 4 +- src/directory_iterator.cpp | 4 +- src/directory_leaf_tree.cpp | 8 ++-- src/directory_map.cpp | 12 +++--- src/directory_map.h | 2 +- src/directory_map_iterator.h | 4 +- src/entry.cpp | 29 +++++++------ src/file.cpp | 46 ++++++++++----------- src/quota_area.cpp | 8 ++-- src/quota_area.h | 4 +- src/recovery.cpp | 14 +++---- src/structs.cpp | 2 +- src/structs.h | 12 +++--- src/wfs_device.cpp | 7 ++-- tests/directory_map_tests.cpp | 78 +++++++++++++++++------------------ 19 files changed, 135 insertions(+), 135 deletions(-) diff --git a/include/wfslib/directory.h b/include/wfslib/directory.h index 682dd53..0dfe9d1 100644 --- a/include/wfslib/directory.h +++ b/include/wfslib/directory.h @@ -25,7 +25,7 @@ class Directory : public Entry, public std::enable_shared_from_this { using iterator = DirectoryIterator; // TODO: Replace name with tree iterator? - Directory(std::string name, AttributesRef attributes, std::shared_ptr quota, std::shared_ptr block); + Directory(std::string name, MetadataRef metadata, std::shared_ptr quota, std::shared_ptr block); std::expected, WfsError> GetEntry(const std::string& name) const; std::expected, WfsError> GetDirectory(const std::string& name) const; diff --git a/include/wfslib/entry.h b/include/wfslib/entry.h index f75619c..c4879f9 100644 --- a/include/wfslib/entry.h +++ b/include/wfslib/entry.h @@ -16,29 +16,29 @@ class QuotaArea; -using AttributesRef = Block::DataRef; - class Entry { public: - Entry(std::string name, AttributesRef block); + using MetadataRef = Block::DataRef; + + Entry(std::string name, MetadataRef block); virtual ~Entry(); const std::string& name() const { return name_; } - bool is_directory() const { return !attributes()->is_link() && attributes()->is_directory(); } - bool is_file() const { return !attributes()->is_link() && !attributes()->is_directory(); } - bool is_link() const { return attributes()->is_link(); } - bool is_quota() const { return attributes()->is_directory() && attributes()->is_quota(); } + bool is_directory() const { return !metadata()->is_link() && metadata()->is_directory(); } + bool is_file() const { return !metadata()->is_link() && !metadata()->is_directory(); } + bool is_link() const { return metadata()->is_link(); } + bool is_quota() const { return metadata()->is_directory() && metadata()->is_quota(); } static std::expected, WfsError> Load(std::shared_ptr quota, std::string name, - AttributesRef attributes_ref); + MetadataRef metadata_ref); protected: - // TODO: Attributes copy as it can change? - Attributes* mutable_attributes() { return attributes_.get_mutable(); } - const Attributes* attributes() const { return attributes_.get(); } - const std::shared_ptr& attributes_block() const { return attributes_.block; } + // TODO: Metadata copy as it can change? + EntryMetadata* mutable_metadata() { return metadata_.get_mutable(); } + const EntryMetadata* metadata() const { return metadata_.get(); } + const std::shared_ptr& metadata_block() const { return metadata_.block; } std::string name_; - AttributesRef attributes_; + MetadataRef metadata_; }; diff --git a/include/wfslib/file.h b/include/wfslib/file.h index 51ccef7..d2ae347 100644 --- a/include/wfslib/file.h +++ b/include/wfslib/file.h @@ -26,8 +26,8 @@ class File : public Entry, public std::enable_shared_from_this { class DataCategory3Reader; class DataCategory4Reader; - File(std::string name, AttributesRef attributes, std::shared_ptr quota) - : Entry(std::move(name), std::move(attributes)), quota_(std::move(quota)) {} + File(std::string name, MetadataRef metadata, std::shared_ptr quota) + : Entry(std::move(name), std::move(metadata)), quota_(std::move(quota)) {} uint32_t Size() const; uint32_t SizeOnDisk() const; diff --git a/include/wfslib/link.h b/include/wfslib/link.h index fea266b..f197dfa 100644 --- a/include/wfslib/link.h +++ b/include/wfslib/link.h @@ -15,8 +15,8 @@ class QuotaArea; class Link : public Entry, public std::enable_shared_from_this { public: - Link(std::string name, AttributesRef attributes, std::shared_ptr quota) - : Entry(std::move(name), std::move(attributes)), quota_(std::move(quota)) {} + Link(std::string name, MetadataRef metadata, std::shared_ptr quota) + : Entry(std::move(name), std::move(metadata)), quota_(std::move(quota)) {} private: // TODO: We may have cyclic reference here if we do cache in area. diff --git a/src/directory.cpp b/src/directory.cpp index f8f94ab..84efda2 100644 --- a/src/directory.cpp +++ b/src/directory.cpp @@ -15,10 +15,10 @@ #include "structs.h" Directory::Directory(std::string name, - AttributesRef attributes, + MetadataRef metadata, std::shared_ptr quota, std::shared_ptr block) - : Entry(std::move(name), std::move(attributes)), + : Entry(std::move(name), std::move(metadata)), quota_(std::move(quota)), block_(std::move(block)), map_{quota_, block_} {} diff --git a/src/directory_iterator.cpp b/src/directory_iterator.cpp index 36b460e..c09f096 100644 --- a/src/directory_iterator.cpp +++ b/src/directory_iterator.cpp @@ -14,8 +14,8 @@ DirectoryIterator::DirectoryIterator(DirectoryMapIterator base) : base_(base) {} DirectoryIterator::reference DirectoryIterator::operator*() const { auto val = *base_; - auto name = val.attributes.get()->GetCaseSensitiveName(val.name); - return {name, Entry::Load(base_.quota(), name, val.attributes)}; + auto name = val.metadata.get()->GetCaseSensitiveName(val.name); + return {name, Entry::Load(base_.quota(), name, val.metadata)}; } DirectoryIterator& DirectoryIterator::operator++() { diff --git a/src/directory_leaf_tree.cpp b/src/directory_leaf_tree.cpp index 2cdd804..fffe1c7 100644 --- a/src/directory_leaf_tree.cpp +++ b/src/directory_leaf_tree.cpp @@ -17,11 +17,11 @@ void DirectoryLeafTree::Init(bool is_root) { void DirectoryLeafTree::copy_value(DirectoryTree& new_tree, parent_node& new_node, dir_leaf_tree_value_type value) const { - Block::RawDataRef attributes{block().get(), value}; - auto size = 1 << attributes.get()->entry_log2_size.value(); + Block::RawDataRef metadata{block().get(), value}; + auto size = 1 << metadata.get()->metadata_log2_size.value(); auto new_offset = new_tree.Alloc(static_cast(size)); assert(new_offset.has_value()); - Block::RawDataRef new_attributes{new_tree.block().get(), *new_offset}; - std::memcpy(new_attributes.get_mutable(), attributes.get(), size); + Block::RawDataRef new_metadata{new_tree.block().get(), *new_offset}; + std::memcpy(new_metadata.get_mutable(), metadata.get(), size); new_node.set_leaf(*new_offset); } diff --git a/src/directory_map.cpp b/src/directory_map.cpp index 6e6b5ce..4db583f 100644 --- a/src/directory_map.cpp +++ b/src/directory_map.cpp @@ -74,7 +74,7 @@ size_t DirectoryMap::CalcSizeOfDirectoryBlock(std::shared_ptr block) cons } }; -bool DirectoryMap::insert(std::string_view name, const Attributes* attributes) { +bool DirectoryMap::insert(std::string_view name, const EntryMetadata* metadata) { auto it = find(name); if (!it.is_end()) { // Already in tree @@ -83,12 +83,12 @@ bool DirectoryMap::insert(std::string_view name, const Attributes* attributes) { auto parents = it.parents(); auto leaf_tree = it.leaf().node; while (true) { - auto size = static_cast(1 << attributes->entry_log2_size.value()); + auto size = static_cast(1 << metadata->metadata_log2_size.value()); auto new_offset = leaf_tree.Alloc(size); if (new_offset.has_value()) { - Block::RawDataRef new_attributes{leaf_tree.block().get(), *new_offset}; + Block::RawDataRef new_metadata{leaf_tree.block().get(), *new_offset}; if (leaf_tree.insert({name | std::ranges::to(), *new_offset})) { - std::memcpy(new_attributes.get_mutable(), attributes, size); + std::memcpy(new_metadata.get_mutable(), metadata, size); return true; } leaf_tree.Free(*new_offset, size); @@ -104,9 +104,9 @@ bool DirectoryMap::erase(std::string_view name) { return false; } auto parents = it.parents(); - // Free the entry attributes first + // Free the entry metadata first it.leaf().node.Free((*it.leaf().iterator).value(), - static_cast(1 << (*it).attributes->entry_log2_size.value())); + static_cast(1 << (*it).metadata->metadata_log2_size.value())); it.leaf().node.erase(it.leaf().iterator); bool last_empty = it.leaf().node.empty(); if (!last_empty) diff --git a/src/directory_map.h b/src/directory_map.h index 70c0366..b795601 100644 --- a/src/directory_map.h +++ b/src/directory_map.h @@ -25,7 +25,7 @@ class DirectoryMap { iterator find(std::string_view key) const; - bool insert(std::string_view name, const Attributes* attributes); + bool insert(std::string_view name, const EntryMetadata* metadata); bool erase(std::string_view name); void Init(); diff --git a/src/directory_map_iterator.h b/src/directory_map_iterator.h index aa8b682..31d4b87 100644 --- a/src/directory_map_iterator.h +++ b/src/directory_map_iterator.h @@ -12,11 +12,11 @@ #include "directory_parent_tree.h" class QuotaArea; -struct Attributes; +struct EntryMetadata; struct DiretoryMapEntry { std::string name; - Block::DataRef attributes; + Block::DataRef metadata; }; class DirectoryMapIterator { diff --git a/src/entry.cpp b/src/entry.cpp index feaf3d6..7f3513f 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -12,35 +12,34 @@ #include "link.h" #include "quota_area.h" -Entry::Entry(std::string name, AttributesRef attributes) : name_(std::move(name)), attributes_(std::move(attributes)) {} +Entry::Entry(std::string name, MetadataRef metadata) : name_(std::move(name)), metadata_(std::move(metadata)) {} Entry::~Entry() = default; // static std::expected, WfsError> Entry::Load(std::shared_ptr quota, std::string name, - AttributesRef attributes_ref) { - auto* attributes = attributes_ref.get(); - if (attributes->is_link()) { - // TODO, I think that the link info is in the attributes metadata - return std::make_shared(std::move(name), std::move(attributes_ref), std::move(quota)); - } else if (attributes->is_directory()) { - if (attributes->flags.value() & attributes->Flags::QUOTA) { + MetadataRef metadata_ref) { + auto* metadata = metadata_ref.get(); + if (metadata->is_link()) { + // TODO, I think that the link info is in the metadata metadata + return std::make_shared(std::move(name), std::move(metadata_ref), std::move(quota)); + } else if (metadata->is_directory()) { + if (metadata->flags.value() & metadata->Flags::QUOTA) { // The directory is quota, aka new area auto block_size = BlockSize::Physical; - if (!(attributes->flags.value() & attributes->Flags::AREA_SIZE_BASIC) && - (attributes->flags.value() & attributes->Flags::AREA_SIZE_REGULAR)) + if (!(metadata->flags.value() & metadata->Flags::AREA_SIZE_BASIC) && + (metadata->flags.value() & metadata->Flags::AREA_SIZE_REGULAR)) block_size = BlockSize::Logical; - auto new_quota = quota->LoadQuotaArea(attributes->directory_block_number.value(), block_size); + auto new_quota = quota->LoadQuotaArea(metadata->directory_block_number.value(), block_size); if (!new_quota.has_value()) return std::unexpected(new_quota.error()); - return (*new_quota)->LoadRootDirectory(std::move(name), std::move(attributes_ref)); + return (*new_quota)->LoadRootDirectory(std::move(name), std::move(metadata_ref)); } else { - return quota->LoadDirectory(attributes->directory_block_number.value(), std::move(name), - std::move(attributes_ref)); + return quota->LoadDirectory(metadata->directory_block_number.value(), std::move(name), std::move(metadata_ref)); } } else { // IsFile() - return std::make_shared(std::move(name), std::move(attributes_ref), std::move(quota)); + return std::make_shared(std::move(name), std::move(metadata_ref), std::move(quota)); } } diff --git a/src/file.cpp b/src/file.cpp index 2d9c950..abddee9 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -19,11 +19,11 @@ struct FileDataChunkInfo { }; uint32_t File::Size() const { - return attributes()->file_size.value(); + return metadata()->file_size.value(); } uint32_t File::SizeOnDisk() const { - return attributes()->size_on_disk.value(); + return metadata()->size_on_disk.value(); } class File::DataCategoryReader { @@ -52,16 +52,16 @@ class File::DataCategoryReader { std::shared_ptr file_; size_t GetAttributesMetadataOffset() const { - return file_->attributes_block()->to_offset(file_->attributes()) + file_->attributes()->size(); + return file_->metadata_block()->to_offset(file_->metadata()) + file_->metadata()->size(); } size_t GetAttributesMetadataEndOffset() const { - return file_->attributes_block()->to_offset(file_->attributes()) + - align_to_power_of_2(file_->attributes()->size() + GetAttributesMetadataSize()); + return file_->metadata_block()->to_offset(file_->metadata()) + + align_to_power_of_2(file_->metadata()->size() + GetAttributesMetadataSize()); } const std::byte* GetAttributesMetadataEnd() const { // We can't do get_object because it might point to data.end(), so in debug it will cause an // error - return file_->attributes_block()->data().data() + GetAttributesMetadataEndOffset(); + return file_->metadata_block()->data().data() + GetAttributesMetadataEndOffset(); } }; @@ -70,15 +70,15 @@ class File::DataCategory0Reader : public File::DataCategoryReader { public: DataCategory0Reader(const std::shared_ptr& file) : DataCategoryReader(file) {} - virtual size_t GetAttributesMetadataSize() const { return file_->attributes()->size_on_disk.value(); } + virtual size_t GetAttributesMetadataSize() const { return file_->metadata()->size_on_disk.value(); } virtual FileDataChunkInfo GetFileDataChunkInfo(size_t offset, size_t size) { - return FileDataChunkInfo{file_->attributes_block(), GetAttributesMetadataOffset() + offset, size}; + return FileDataChunkInfo{file_->metadata_block(), GetAttributesMetadataOffset() + offset, size}; } virtual void Resize(size_t new_size) { // Just update the attribute, the data in the metadata block - file_->mutable_attributes()->file_size = static_cast(new_size); + file_->mutable_metadata()->file_size = static_cast(new_size); } }; @@ -88,7 +88,7 @@ class File::RegularDataCategoryReader : public File::DataCategoryReader { virtual size_t GetAttributesMetadataSize() const { // round up dividation - size_t data_blocks_count = ((file_->attributes()->size_on_disk.value() - 1) >> GetDataBlockSize()) + 1; + size_t data_blocks_count = ((file_->metadata()->size_on_disk.value() - 1) >> GetDataBlockSize()) + 1; return sizeof(DataBlockMetadata) * data_blocks_count; } @@ -96,19 +96,19 @@ class File::RegularDataCategoryReader : public File::DataCategoryReader { auto blocks_list = reinterpret_cast(GetAttributesMetadataEnd()); int64_t block_index = offset >> GetDataBlockSize(); size_t offset_in_block = offset & ((1 << GetDataBlockSize()) - 1); - auto hash_block = file_->attributes_block(); + auto hash_block = file_->metadata_block(); uint32_t block_offset = static_cast((offset >> GetDataBlockSize()) << GetDataBlockSize()); LoadDataBlock(blocks_list[-block_index - 1].block_number.value(), static_cast( - std::min(1U << GetDataBlockSize(), file_->attributes()->file_size.value() - block_offset)), + std::min(1U << GetDataBlockSize(), file_->metadata()->file_size.value() - block_offset)), {hash_block, hash_block->to_offset(&blocks_list[-block_index - 1].hash)}); size = std::min(size, current_data_block->size() - offset_in_block); return FileDataChunkInfo{current_data_block, offset_in_block, size}; } virtual void Resize(size_t new_size) { - size_t old_size = file_->attributes()->file_size.value(); + size_t old_size = file_->metadata()->file_size.value(); while (old_size != new_size) { std::shared_ptr current_block; size_t new_block_size = 0; @@ -139,7 +139,7 @@ class File::RegularDataCategoryReader : public File::DataCategoryReader { old_size += new_block_size; } } - file_->mutable_attributes()->file_size = static_cast(old_size); + file_->mutable_metadata()->file_size = static_cast(old_size); if (current_block) { current_block->Resize(static_cast(new_block_size)); } @@ -159,7 +159,7 @@ class File::RegularDataCategoryReader : public File::DataCategoryReader { return; auto block = file_->quota()->LoadDataBlock(block_number, static_cast(file_->quota()->block_size_log2()), GetBlocksLog2CountInDataBlock(), data_size, std::move(data_hash), - !(file_->attributes()->flags.value() & Attributes::UNENCRYPTED_FILE)); + !(file_->metadata()->flags.value() & EntryMetadata::UNENCRYPTED_FILE)); if (!block.has_value()) throw WfsException(WfsError::kFileDataCorrupted); current_data_block = std::move(*block); @@ -194,13 +194,13 @@ class File::DataCategory3Reader : public File::DataCategory2Reader { DataCategory3Reader(const std::shared_ptr& file) : DataCategory2Reader(file) {} virtual size_t GetAttributesMetadataSize() const { - size_t data_blocks_clusters_count = ((file_->attributes()->size_on_disk.value() - 1) >> ClusterDataLog2Size()) + 1; + size_t data_blocks_clusters_count = ((file_->metadata()->size_on_disk.value() - 1) >> ClusterDataLog2Size()) + 1; return sizeof(DataBlocksClusterMetadata) * data_blocks_clusters_count; } virtual FileDataChunkInfo GetFileDataChunkInfo(size_t offset, size_t size) { return GetFileDataChunkInfoFromClustersList( - offset, offset, size, file_->attributes_block(), + offset, offset, size, file_->metadata_block(), reinterpret_cast(GetAttributesMetadataEnd()), true); } @@ -225,7 +225,7 @@ class File::DataCategory3Reader : public File::DataCategory2Reader { LoadDataBlock(cluster->block_number.value() + static_cast(block_index << log2_size(GetBlocksLog2CountInDataBlock())), static_cast( - std::min(1U << GetDataBlockSize(), file_->attributes()->file_size.value() - block_offset)), + std::min(1U << GetDataBlockSize(), file_->metadata()->file_size.value() - block_offset)), {metadata_block, metadata_block->to_offset(&cluster->hash[block_index])}); size = std::min(size, current_data_block->size() - offset_in_block); return FileDataChunkInfo{current_data_block, offset_in_block, size}; @@ -242,7 +242,7 @@ class File::DataCategory4Reader : public File::DataCategory3Reader { DataCategory4Reader(const std::shared_ptr& file) : DataCategory3Reader(file) {} virtual size_t GetAttributesMetadataSize() const { - size_t data_blocks_clusters_count = ((file_->attributes()->size_on_disk.value() - 1) >> ClusterDataLog2Size()) + 1; + size_t data_blocks_clusters_count = ((file_->metadata()->size_on_disk.value() - 1) >> ClusterDataLog2Size()) + 1; size_t blocks_count = ((data_blocks_clusters_count - 1) / ClustersInBlock()) + 1; return sizeof(uint32_be_t) * blocks_count; } @@ -279,7 +279,7 @@ class File::DataCategory4Reader : public File::DataCategory3Reader { }; std::shared_ptr File::CreateReader(std::shared_ptr file) { - switch (file->attributes()->size_category.value()) { + switch (file->metadata()->size_category.value()) { case 0: return std::make_shared(file); case 1: @@ -297,8 +297,8 @@ std::shared_ptr File::CreateReader(std::shared_ptr(attributes_.get()->size_on_disk.value())); - size_t old_size = attributes_.get()->file_size.value(); + new_size = std::min(new_size, static_cast(metadata_.get()->size_on_disk.value())); + size_t old_size = metadata_.get()->file_size.value(); if (new_size != old_size) { CreateReader(shared_from_this())->Resize(new_size); } @@ -307,7 +307,7 @@ void File::Resize(size_t new_size) { File::file_device::file_device(const std::shared_ptr& file) : file_(file), reader_(CreateReader(file)), pos_(0) {} size_t File::file_device::size() const { - return file_->attributes()->file_size.value(); + return file_->metadata()->file_size.value(); } std::streamsize File::file_device::read(char_type* s, std::streamsize n) { diff --git a/src/quota_area.cpp b/src/quota_area.cpp index 9ad73b7..067f05a 100644 --- a/src/quota_area.cpp +++ b/src/quota_area.cpp @@ -41,16 +41,16 @@ std::expected, WfsError> QuotaArea::Create(std::share std::expected, WfsError> QuotaArea::LoadDirectory(uint32_t area_block_number, std::string name, - AttributesRef attributes) { + Entry::MetadataRef metadata) { auto block = LoadMetadataBlock(area_block_number); if (!block.has_value()) return std::unexpected(WfsError::kDirectoryCorrupted); - return std::make_shared(std::move(name), std::move(attributes), shared_from_this(), std::move(*block)); + return std::make_shared(std::move(name), std::move(metadata), shared_from_this(), std::move(*block)); } std::expected, WfsError> QuotaArea::LoadRootDirectory(std::string name, - AttributesRef attributes) { - return LoadDirectory(header()->root_directory_block_number.value(), std::move(name), std::move(attributes)); + Entry::MetadataRef metadata) { + return LoadDirectory(header()->root_directory_block_number.value(), std::move(name), std::move(metadata)); } std::expected, WfsError> QuotaArea::GetShadowDirectory1() { diff --git a/src/quota_area.h b/src/quota_area.h index 54f497f..37e9884 100644 --- a/src/quota_area.h +++ b/src/quota_area.h @@ -34,13 +34,13 @@ class QuotaArea : public Area, public std::enable_shared_from_this { std::expected, WfsError> LoadQuotaArea(uint32_t area_block_number, BlockSize block_size); - std::expected, WfsError> LoadRootDirectory(std::string name, AttributesRef attributes); + std::expected, WfsError> LoadRootDirectory(std::string name, Entry::MetadataRef metadata); std::expected, WfsError> GetShadowDirectory1(); std::expected, WfsError> GetShadowDirectory2(); std::expected, WfsError> LoadDirectory(uint32_t area_block_number, std::string name, - AttributesRef attributes); + Entry::MetadataRef metadata); std::expected, WfsError> AllocMetadataBlock(); std::expected, WfsError> AllocDataBlocks(uint32_t count, BlockType block_type); diff --git a/src/recovery.cpp b/src/recovery.cpp index 325220c..f4c3875 100644 --- a/src/recovery.cpp +++ b/src/recovery.cpp @@ -105,8 +105,8 @@ std::optional Recovery::DetectDeviceParams(std::shared_ptr /*load_data=*/true, /*check_hash=*/false); auto wfs_header = block->get_object(sizeof(MetadataBlockHeader)); auto block_size = BlockSize::Physical; - if (!(wfs_header->root_quota_attributes.flags.value() & Attributes::Flags::AREA_SIZE_BASIC) && - (wfs_header->root_quota_attributes.flags.value() & Attributes::Flags::AREA_SIZE_REGULAR)) + if (!(wfs_header->root_quota_metadata.flags.value() & EntryMetadata::Flags::AREA_SIZE_BASIC) && + (wfs_header->root_quota_metadata.flags.value() & EntryMetadata::Flags::AREA_SIZE_REGULAR)) block_size = BlockSize::Logical; block.reset(); uint32_t area_xor_wfs_iv; @@ -193,8 +193,8 @@ std::expected, WfsError> Recovery::OpenUsrDirectoryWi std::memset(&wfs_header, 0, sizeof(wfs_header)); wfs_header.iv = 0; wfs_header.version = 0x01010800; - wfs_header.root_quota_attributes.flags = static_cast( - Attributes::Flags::AREA_SIZE_REGULAR | Attributes::Flags::QUOTA | Attributes::Flags::DIRECTORY); + wfs_header.root_quota_metadata.flags = static_cast( + EntryMetadata::Flags::AREA_SIZE_REGULAR | EntryMetadata::Flags::QUOTA | EntryMetadata::Flags::DIRECTORY); WfsAreaHeader area_header; std::memset(&area_header, 0, sizeof(area_header)); // This is the initial iv until we correct it @@ -226,13 +226,13 @@ std::expected, WfsError> Recovery::OpenUsrDirectoryWi throw std::logic_error("Failed to find /usr/save/system"); } std::shared_ptr sub_area; - for (const auto& [name, attributes] : system_save_dir->map_) { + for (const auto& [name, metadata] : system_save_dir->map_) { // this is probably a corrupted quota, let's check - if (!attributes.get()->is_quota()) + if (!metadata.get()->is_quota()) continue; // ok this is quota auto new_quota = - system_save_dir->quota()->LoadQuotaArea(attributes.get()->directory_block_number.value(), BlockSize::Logical); + system_save_dir->quota()->LoadQuotaArea(metadata.get()->directory_block_number.value(), BlockSize::Logical); if (!new_quota.has_value()) return std::unexpected(new_quota.error()); sub_area = std::move(*new_quota); diff --git a/src/structs.cpp b/src/structs.cpp index 0cc0079..e66aa9d 100644 --- a/src/structs.cpp +++ b/src/structs.cpp @@ -10,7 +10,7 @@ #include "structs.h" -std::string Attributes::GetCaseSensitiveName(const std::string& name) const { +std::string EntryMetadata::GetCaseSensitiveName(const std::string& name) const { std::string real_filename = ""; if (filename_length.value() != name.size()) { // TODO: return WfsError diff --git a/src/structs.h b/src/structs.h index dab1960..0123965 100644 --- a/src/structs.h +++ b/src/structs.h @@ -60,7 +60,7 @@ struct Permissions { static_assert(sizeof(Permissions) == 0xc, "Incorrect sizeof Permissions"); // sizeof 0x2c -struct Attributes { +struct EntryMetadata { enum Flags : uint32_t { UNENCRYPTED_FILE = 0x2000000, LINK = 0x4000000, @@ -80,8 +80,8 @@ struct Attributes { }; uint32_be_t directory_block_number; // in case of directory Permissions permissions; - uint8_be_t entry_log2_size; // log2 size of the whole entry, including this attributes - uint8_be_t size_category; // 0-4, see File.c + uint8_be_t metadata_log2_size; // log2 size of the whole metadata + uint8_be_t size_category; // 0-4, see File.c uint8_be_t filename_length; uint8_be_t case_bitmap; // This byte in the struct also behave as padding, it isn't really a // byte, it is a bitmap of filename_length @@ -91,11 +91,11 @@ struct Attributes { bool is_link() const { return !!(flags.value() & Flags::LINK); } bool is_quota() const { return !!(flags.value() & Flags::QUOTA); } - size_t size() const { return offsetof(Attributes, case_bitmap) + div_ceil(filename_length.value(), 8); } + size_t size() const { return offsetof(EntryMetadata, case_bitmap) + div_ceil(filename_length.value(), 8); } std::string GetCaseSensitiveName(const std::string& name) const; }; -static_assert(sizeof(Attributes) == 0x2C, "Incorrect sizeof Attributes"); +static_assert(sizeof(EntryMetadata) == 0x2C, "Incorrect sizeof EntryMetadata"); enum class DeviceType : uint16_t { MLC = 0x136a, @@ -108,7 +108,7 @@ struct WfsDeviceHeader { uint32_be_t version; // should be 0x01010800 uint16_be_t device_type; // usb - 0x16a2. mlc - 0x136a? uint16_be_t _pad; - Attributes root_quota_attributes; + EntryMetadata root_quota_metadata; uint32_be_t transactions_area_block_number; // must be 6 or 12 (6*2, when regular block size used) uint32_be_t transactions_area_blocks_count; uint32_be_t unknown[2]; // not used?? diff --git a/src/wfs_device.cpp b/src/wfs_device.cpp index c8a9fc7..c7ee931 100644 --- a/src/wfs_device.cpp +++ b/src/wfs_device.cpp @@ -93,7 +93,7 @@ std::shared_ptr WfsDevice::GetRootArea() { } std::expected, WfsError> WfsDevice::GetRootDirectory() { - return GetRootArea()->LoadRootDirectory("", {root_block_, root_block_->to_offset(&header()->root_quota_attributes)}); + return GetRootArea()->LoadRootDirectory("", {root_block_, root_block_->to_offset(&header()->root_quota_metadata)}); } // static @@ -187,8 +187,9 @@ void WfsDevice::Init() { header->iv = random_iv_generator(rand_engine); header->device_type = static_cast(DeviceType::USB); // TODO header->version = WFS_VERSION; - header->root_quota_attributes.flags = Attributes::DIRECTORY | Attributes::AREA_SIZE_REGULAR | Attributes::QUOTA; - header->root_quota_attributes.quota_blocks_count = blocks_count; + header->root_quota_metadata.flags = + EntryMetadata::DIRECTORY | EntryMetadata::AREA_SIZE_REGULAR | EntryMetadata::QUOTA; + header->root_quota_metadata.quota_blocks_count = blocks_count; header->transactions_area_block_number = QuotaArea::kReservedAreaBlocks << (log2_size(BlockSize::Logical) - log2_size(BlockSize::Physical)); header->transactions_area_blocks_count = kTransactionsAreaEnd - header->transactions_area_block_number.value(); diff --git a/tests/directory_map_tests.cpp b/tests/directory_map_tests.cpp index 84faa1a..f4845ca 100644 --- a/tests/directory_map_tests.cpp +++ b/tests/directory_map_tests.cpp @@ -23,14 +23,14 @@ namespace { -class TestAttributes { +class TestEntryMetadata { public: - TestAttributes(uint8_t log2_size = 6) : data_{static_cast(1u << log2_size), std::byte{0}} { + TestEntryMetadata(uint8_t log2_size = 6) : data_{static_cast(1u << log2_size), std::byte{0}} { assert(log2_size >= 6 && log2_size <= 10); - data()->entry_log2_size = log2_size; + data()->metadata_log2_size = log2_size; } - Attributes* data() { return reinterpret_cast(data_.data()); } + EntryMetadata* data() { return reinterpret_cast(data_.data()); } private: std::vector data_; @@ -51,26 +51,26 @@ TEST_CASE("DirectoryMapTests") { SECTION("insert entries sorted") { const int kEntriesCount = 100000; - TestAttributes attributes(6); + TestEntryMetadata metadata(6); for (uint32_t i = 0; i < kEntriesCount; ++i) { - attributes.data()->flags = i; - REQUIRE(dir_tree.insert(std::format("{:05}", i), attributes.data())); + metadata.data()->flags = i; + REQUIRE(dir_tree.insert(std::format("{:05}", i), metadata.data())); } REQUIRE(dir_tree.size() == kEntriesCount); REQUIRE(std::ranges::distance(dir_tree.begin(), dir_tree.end()) == kEntriesCount); for (auto [i, entry] : std::views::enumerate(dir_tree)) { CHECK(entry.name == std::format("{:05}", i)); - CHECK(entry.attributes.get()->flags.value() == i); - CHECK(entry.attributes.get()->entry_log2_size.value() == 6); + CHECK(entry.metadata.get()->flags.value() == i); + CHECK(entry.metadata.get()->metadata_log2_size.value() == 6); } REQUIRE(std::ranges::equal( std::views::transform(std::views::reverse(dir_tree), - [](const auto& entry) -> int { return entry.attributes.get()->flags.value(); }), + [](const auto& entry) -> int { return entry.metadata.get()->flags.value(); }), std::views::reverse(std::views::iota(0, kEntriesCount)))); for (uint32_t i = 0; i < kEntriesCount; ++i) { auto entry = dir_tree.find(std::format("{:05}", i)); REQUIRE(!entry.is_end()); - CHECK((*entry).attributes.get()->flags.value() == i); + CHECK((*entry).metadata.get()->flags.value() == i); CHECK((*entry).name == std::format("{:05}", i)); } } @@ -78,11 +78,11 @@ TEST_CASE("DirectoryMapTests") { SECTION("insert and remove one two entries") { SubBlockAllocator allocator{root_block}; auto free_bytes_1 = allocator.GetFreeBytes(); - TestAttributes attributes(6); - REQUIRE(dir_tree.insert("a", attributes.data())); + TestEntryMetadata metadata(6); + REQUIRE(dir_tree.insert("a", metadata.data())); auto free_bytes_2 = allocator.GetFreeBytes(); CHECK(free_bytes_2 != free_bytes_1); - REQUIRE(dir_tree.insert("aa", attributes.data())); + REQUIRE(dir_tree.insert("aa", metadata.data())); CHECK(free_bytes_2 != allocator.GetFreeBytes()); REQUIRE(dir_tree.erase("aa")); CHECK(free_bytes_2 == allocator.GetFreeBytes()); @@ -93,50 +93,50 @@ TEST_CASE("DirectoryMapTests") { SECTION("insert entries unsorted") { constexpr int kEntriesCount = 100000; auto unsorted_keys = createShuffledKeysArray(); - TestAttributes attributes(6); + TestEntryMetadata metadata(6); for (auto i : unsorted_keys) { - attributes.data()->flags = i; - REQUIRE(dir_tree.insert(std::format("{:05}", i), attributes.data())); + metadata.data()->flags = i; + REQUIRE(dir_tree.insert(std::format("{:05}", i), metadata.data())); } REQUIRE(dir_tree.size() == kEntriesCount); REQUIRE(std::ranges::distance(dir_tree.begin(), dir_tree.end()) == kEntriesCount); for (auto [i, entry] : std::views::enumerate(dir_tree)) { CHECK(entry.name == std::format("{:05}", i)); - CHECK(entry.attributes.get()->flags.value() == i); - CHECK(entry.attributes.get()->entry_log2_size.value() == 6); + CHECK(entry.metadata.get()->flags.value() == i); + CHECK(entry.metadata.get()->metadata_log2_size.value() == 6); } for (uint32_t i = 0; i < kEntriesCount; ++i) { auto entry = dir_tree.find(std::format("{:05}", i)); REQUIRE(!entry.is_end()); - CHECK((*entry).attributes.get()->flags.value() == i); + CHECK((*entry).metadata.get()->flags.value() == i); CHECK((*entry).name == std::format("{:05}", i)); } } - SECTION("insert entries unsorted different attributes size") { + SECTION("insert entries unsorted different metadata size") { constexpr int kEntriesCount = 10000; auto unsorted_keys = createShuffledKeysArray(); for (auto i : unsorted_keys) { - TestAttributes attributes((i % 5) + 6); - attributes.data()->flags = i; - REQUIRE(dir_tree.insert(std::format("{:04}", i), attributes.data())); + TestEntryMetadata metadata((i % 5) + 6); + metadata.data()->flags = i; + REQUIRE(dir_tree.insert(std::format("{:04}", i), metadata.data())); } REQUIRE(dir_tree.size() == kEntriesCount); REQUIRE(std::ranges::distance(dir_tree.begin(), dir_tree.end()) == kEntriesCount); for (auto [i, entry] : std::views::enumerate(dir_tree)) { CHECK(entry.name == std::format("{:04}", i)); - CHECK(entry.attributes.get()->flags.value() == i); - CHECK(entry.attributes.get()->entry_log2_size.value() == (i % 5) + 6); + CHECK(entry.metadata.get()->flags.value() == i); + CHECK(entry.metadata.get()->metadata_log2_size.value() == (i % 5) + 6); } } SECTION("remove entries randomly") { constexpr int kEntriesCount = 100000; auto free_blocks = (*wfs_device->GetRootArea()->GetFreeBlocksAllocator())->free_blocks_count(); - TestAttributes attributes(6); + TestEntryMetadata metadata(6); for (uint32_t i = 0; i < kEntriesCount; ++i) { - attributes.data()->flags = i; - REQUIRE(dir_tree.insert(std::format("{:05}", i), attributes.data())); + metadata.data()->flags = i; + REQUIRE(dir_tree.insert(std::format("{:05}", i), metadata.data())); } CHECK(free_blocks != (*wfs_device->GetRootArea()->GetFreeBlocksAllocator())->free_blocks_count()); @@ -151,7 +151,7 @@ TEST_CASE("DirectoryMapTests") { std::ranges::sort(sorted_upper_half); // Ensure that the right entries were deleted REQUIRE(std::ranges::equal( - std::views::transform(dir_tree, [](const auto& entry) -> int { return entry.attributes.get()->flags.value(); }), + std::views::transform(dir_tree, [](const auto& entry) -> int { return entry.metadata.get()->flags.value(); }), sorted_upper_half)); // Remove the second half @@ -169,10 +169,10 @@ TEST_CASE("DirectoryMapTests") { SECTION("remove entries randomly") { constexpr int kEntriesCount = 100000; auto free_blocks = (*wfs_device->GetRootArea()->GetFreeBlocksAllocator())->free_blocks_count(); - TestAttributes attributes(6); + TestEntryMetadata metadata(6); for (uint32_t i = 0; i < kEntriesCount; ++i) { - attributes.data()->flags = i; - REQUIRE(dir_tree.insert(std::format("{:05}", i), attributes.data())); + metadata.data()->flags = i; + REQUIRE(dir_tree.insert(std::format("{:05}", i), metadata.data())); } CHECK(free_blocks != (*wfs_device->GetRootArea()->GetFreeBlocksAllocator())->free_blocks_count()); @@ -187,7 +187,7 @@ TEST_CASE("DirectoryMapTests") { std::ranges::sort(sorted_upper_half); // Ensure that the right entries were deleted REQUIRE(std::ranges::equal( - std::views::transform(dir_tree, [](const auto& entry) -> int { return entry.attributes.get()->flags.value(); }), + std::views::transform(dir_tree, [](const auto& entry) -> int { return entry.metadata.get()->flags.value(); }), sorted_upper_half)); // Remove the second half @@ -204,9 +204,9 @@ TEST_CASE("DirectoryMapTests") { SECTION("check backward/forward iterator") { constexpr int kEntriesCount = 100000; - TestAttributes attributes(6); + TestEntryMetadata metadata(6); for (uint32_t i = 0; i < kEntriesCount; ++i) { - REQUIRE(dir_tree.insert(std::format("{:05}", i), attributes.data())); + REQUIRE(dir_tree.insert(std::format("{:05}", i), metadata.data())); } auto it = dir_tree.begin(); @@ -240,12 +240,12 @@ TEST_CASE("DirectoryMapTests") { } SECTION("split tree during erase") { - TestAttributes attributes(6); + TestEntryMetadata metadata(6); for (uint32_t i = 0; i < 80; ++i) { - REQUIRE(dir_tree.insert(std::format("{:05}", 10000 + i), attributes.data())); + REQUIRE(dir_tree.insert(std::format("{:05}", 10000 + i), metadata.data())); } for (uint32_t i = 0; i < 200; ++i) { - REQUIRE(dir_tree.insert(std::format("{:05}", 11000 + i), attributes.data())); + REQUIRE(dir_tree.insert(std::format("{:05}", 11000 + i), metadata.data())); } SubBlockAllocator allocator{*wfs_device->GetRootArea()->LoadMetadataBlock(10)}; // Fill it so we won't be able to go to the merge flow