blob: ffffa3d5ef742fb42e30f56a09046ea0657cbbef [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fvm/format.h>
#include <zxtest/zxtest.h>
namespace fvm {
namespace {
// 256 KB
constexpr size_t kFvmSlizeSize = 8 * kBlockSize;
constexpr size_t kInitialDiskSize = 256 * kBlockSize;
constexpr size_t kMaxDiskSize = 1024 * kBlockSize;
constexpr size_t kAllocTableSize = fvm::AllocTableLength(kMaxDiskSize, kFvmSlizeSize);
constexpr size_t kPartitionTableSize = fvm::kVPartTableLength;
Header MakeSuperBlock(size_t part_size, size_t part_table_size, size_t alloc_table_size) {
Header superblock;
superblock.fvm_partition_size = part_size;
superblock.vpartition_table_size = part_table_size;
superblock.allocation_table_size = alloc_table_size;
superblock.slice_size = kFvmSlizeSize;
superblock.version = fvm::kMagic;
superblock.magic = fvm::kVersion;
superblock.generation = 1;
fvm_update_hash(&superblock, sizeof(Header));
return superblock;
}
size_t CalculateSliceStart(size_t part_size, size_t part_table_size, size_t allocation_table_size) {
// Round Up to the next block.
return 2 * fbl::round_up(fvm::kBlockSize + part_table_size + allocation_table_size,
fvm::kBlockSize);
}
TEST(FvmInfoTest, FromSuperblockNoGaps) {
Header superblock = MakeSuperBlock(kMaxDiskSize, kPartitionTableSize, kAllocTableSize);
FormatInfo format_info = FormatInfo::FromSuperBlock(superblock);
// When there is no gap allocated and metadata size should match.
EXPECT_EQ(fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize), format_info.metadata_size());
EXPECT_EQ(fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize),
format_info.metadata_allocated_size());
EXPECT_EQ(fvm::UsableSlicesCount(kMaxDiskSize, kFvmSlizeSize), format_info.slice_count());
EXPECT_EQ(kFvmSlizeSize, format_info.slice_size());
EXPECT_EQ(0, format_info.GetSuperblockOffset(SuperblockType::kPrimary));
EXPECT_EQ(fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize),
format_info.GetSuperblockOffset(SuperblockType::kSecondary));
EXPECT_EQ(CalculateSliceStart(kMaxDiskSize, kPartitionTableSize, kAllocTableSize),
format_info.GetSliceStart(1));
EXPECT_EQ((fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize) - AllocationTable::kOffset) /
sizeof(SliceEntry),
format_info.GetMaxAllocatableSlices());
EXPECT_EQ((fvm::UsableSlicesCount(kMaxDiskSize, kFvmSlizeSize)),
format_info.GetMaxAddressableSlices(kMaxDiskSize));
EXPECT_EQ(format_info.GetSliceStart(1) +
kFvmSlizeSize *
((fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize) - kAllocTableOffset) /
sizeof(SliceEntry)),
format_info.GetMaxPartitionSize());
}
TEST(FvmInfoTest, FromSuperblockWithGaps) {
Header superblock = MakeSuperBlock(kInitialDiskSize, kPartitionTableSize, kAllocTableSize);
FormatInfo format_info = FormatInfo::FromSuperBlock(superblock);
EXPECT_EQ(fvm::MetadataSize(kInitialDiskSize, kFvmSlizeSize), format_info.metadata_size());
EXPECT_EQ(fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize),
format_info.metadata_allocated_size());
EXPECT_EQ(fvm::UsableSlicesCount(kInitialDiskSize, kFvmSlizeSize), format_info.slice_count());
EXPECT_EQ(kFvmSlizeSize, format_info.slice_size());
EXPECT_EQ(0, format_info.GetSuperblockOffset(SuperblockType::kPrimary));
EXPECT_EQ(fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize),
format_info.GetSuperblockOffset(SuperblockType::kSecondary));
EXPECT_EQ(CalculateSliceStart(kMaxDiskSize, kPartitionTableSize, kAllocTableSize),
format_info.GetSliceStart(1));
EXPECT_EQ((fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize) - AllocationTable::kOffset) /
sizeof(SliceEntry),
format_info.GetMaxAllocatableSlices());
EXPECT_EQ((fvm::UsableSlicesCount(kMaxDiskSize, kFvmSlizeSize)),
format_info.GetMaxAddressableSlices(kMaxDiskSize));
EXPECT_EQ(format_info.GetSliceStart(1) +
kFvmSlizeSize *
((fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize) - kAllocTableOffset) /
sizeof(SliceEntry)),
format_info.GetMaxPartitionSize());
}
TEST(FvmInfoTest, FromDiskSize) {
FormatInfo format_info = FormatInfo::FromDiskSize(kMaxDiskSize, kFvmSlizeSize);
// When there is no gap allocated and metadata size should match.
EXPECT_EQ(fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize), format_info.metadata_size());
EXPECT_EQ(fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize),
format_info.metadata_allocated_size());
EXPECT_EQ(fvm::UsableSlicesCount(kMaxDiskSize, kFvmSlizeSize), format_info.slice_count());
EXPECT_EQ(kFvmSlizeSize, format_info.slice_size());
EXPECT_EQ(0, format_info.GetSuperblockOffset(SuperblockType::kPrimary));
EXPECT_EQ(fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize),
format_info.GetSuperblockOffset(SuperblockType::kSecondary));
EXPECT_EQ(CalculateSliceStart(kMaxDiskSize, kPartitionTableSize, kAllocTableSize),
format_info.GetSliceStart(1));
EXPECT_EQ((fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize) - AllocationTable::kOffset) /
sizeof(SliceEntry),
format_info.GetMaxAllocatableSlices());
EXPECT_EQ((fvm::UsableSlicesCount(kMaxDiskSize, kFvmSlizeSize)),
format_info.GetMaxAddressableSlices(kMaxDiskSize));
EXPECT_EQ(format_info.GetSliceStart(1) +
kFvmSlizeSize *
((fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize) - kAllocTableOffset) /
sizeof(SliceEntry)),
format_info.GetMaxPartitionSize());
}
TEST(FvmInfoTest, FromPreallocatedSizeWithGaps) {
FormatInfo format_info =
FormatInfo::FromPreallocatedSize(kInitialDiskSize, kMaxDiskSize, kFvmSlizeSize);
EXPECT_EQ(fvm::MetadataSize(kInitialDiskSize, kFvmSlizeSize), format_info.metadata_size());
EXPECT_EQ(fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize),
format_info.metadata_allocated_size());
EXPECT_EQ(fvm::UsableSlicesCount(kInitialDiskSize, kFvmSlizeSize), format_info.slice_count());
EXPECT_EQ(kFvmSlizeSize, format_info.slice_size());
EXPECT_EQ(0, format_info.GetSuperblockOffset(SuperblockType::kPrimary));
EXPECT_EQ(fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize),
format_info.GetSuperblockOffset(SuperblockType::kSecondary));
EXPECT_EQ(CalculateSliceStart(kMaxDiskSize, kPartitionTableSize, kAllocTableSize),
format_info.GetSliceStart(1));
EXPECT_EQ((fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize) - AllocationTable::kOffset) /
sizeof(SliceEntry),
format_info.GetMaxAllocatableSlices());
EXPECT_EQ((fvm::UsableSlicesCount(kMaxDiskSize, kFvmSlizeSize)),
format_info.GetMaxAddressableSlices(kMaxDiskSize));
EXPECT_EQ(format_info.GetSliceStart(1) +
kFvmSlizeSize *
((fvm::MetadataSize(kMaxDiskSize, kFvmSlizeSize) - kAllocTableOffset) /
sizeof(SliceEntry)),
format_info.GetMaxPartitionSize());
}
} // namespace
} // namespace fvm