Loading fs_mgr/liblp/builder.cpp +12 −30 Original line number Diff line number Diff line Loading @@ -268,39 +268,19 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata } // Compute the first free sector, factoring in alignment. uint64_t free_area = uint64_t free_area_start = AlignTo(total_reserved, device_info.alignment, device_info.alignment_offset); uint64_t first_sector = free_area / LP_SECTOR_SIZE; // Compute the last free sector, which is inclusive. We subtract 1 to make // sure that logical partitions won't overlap with the same sector as the // backup metadata, which could happen if the block device was not aligned // to LP_SECTOR_SIZE. uint64_t last_sector = (device_info.size / LP_SECTOR_SIZE) - 1; // If this check fails, it means either (1) we did not have free space to // allocate a single sector, or (2) we did, but the alignment was high // enough to bump the first sector out of range. Either way, we cannot // continue. if (first_sector > last_sector) { LERROR << "Not enough space to allocate any partition tables."; return false; } uint64_t first_sector = free_area_start / LP_SECTOR_SIZE; // Finally, the size of the allocatable space must be a multiple of the // logical block size. If we have no more free space after this // computation, then we abort. Note that the last sector is inclusive, // so we have to account for that. uint64_t num_free_sectors = last_sector - first_sector + 1; uint64_t sectors_per_block = device_info.logical_block_size / LP_SECTOR_SIZE; if (num_free_sectors < sectors_per_block) { LERROR << "Not enough space to allocate any partition tables."; // There must be one logical block of free space remaining (enough for one partition). uint64_t minimum_disk_size = (first_sector * LP_SECTOR_SIZE) + device_info.logical_block_size; if (device_info.size < minimum_disk_size) { LERROR << "Device must be at least " << minimum_disk_size << " bytes, only has " << device_info.size; return false; } last_sector = first_sector + (num_free_sectors / sectors_per_block) * sectors_per_block - 1; geometry_.first_logical_sector = first_sector; geometry_.last_logical_sector = last_sector; geometry_.metadata_max_size = metadata_max_size; geometry_.metadata_slot_count = metadata_slot_count; geometry_.alignment = device_info.alignment; Loading Loading @@ -452,8 +432,10 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) uint64_t last_free_extent_start = extents.empty() ? geometry_.first_logical_sector : extents.back().end; last_free_extent_start = AlignSector(last_free_extent_start); if (last_free_extent_start <= geometry_.last_logical_sector) { free_regions.emplace_back(last_free_extent_start, geometry_.last_logical_sector + 1); uint64_t last_sector = geometry_.block_device_size / LP_SECTOR_SIZE; if (last_free_extent_start < last_sector) { free_regions.emplace_back(last_free_extent_start, last_sector); } const uint64_t sectors_per_block = geometry_.logical_block_size / LP_SECTOR_SIZE; Loading Loading @@ -559,7 +541,7 @@ std::unique_ptr<LpMetadata> MetadataBuilder::Export() { } uint64_t MetadataBuilder::AllocatableSpace() const { return (geometry_.last_logical_sector - geometry_.first_logical_sector + 1) * LP_SECTOR_SIZE; return geometry_.block_device_size - (geometry_.first_logical_sector * LP_SECTOR_SIZE); } uint64_t MetadataBuilder::UsedSpace() const { Loading fs_mgr/liblp/builder_test.cpp +0 −5 Original line number Diff line number Diff line Loading @@ -127,7 +127,6 @@ TEST(liblp, InternalAlignment) { unique_ptr<LpMetadata> exported = builder->Export(); ASSERT_NE(exported, nullptr); EXPECT_EQ(exported->geometry.first_logical_sector, 1536); EXPECT_EQ(exported->geometry.last_logical_sector, 2047); // Test a large alignment offset thrown in. device_info.alignment_offset = 753664; Loading @@ -136,7 +135,6 @@ TEST(liblp, InternalAlignment) { exported = builder->Export(); ASSERT_NE(exported, nullptr); EXPECT_EQ(exported->geometry.first_logical_sector, 1472); EXPECT_EQ(exported->geometry.last_logical_sector, 2047); // Alignment offset without alignment doesn't mean anything. device_info.alignment = 0; Loading @@ -151,7 +149,6 @@ TEST(liblp, InternalAlignment) { exported = builder->Export(); ASSERT_NE(exported, nullptr); EXPECT_EQ(exported->geometry.first_logical_sector, 150); EXPECT_EQ(exported->geometry.last_logical_sector, 2045); // Test a small alignment with no alignment offset. device_info.alignment = 11 * 1024; Loading @@ -160,7 +157,6 @@ TEST(liblp, InternalAlignment) { exported = builder->Export(); ASSERT_NE(exported, nullptr); EXPECT_EQ(exported->geometry.first_logical_sector, 160); EXPECT_EQ(exported->geometry.last_logical_sector, 2047); } TEST(liblp, InternalPartitionAlignment) { Loading Loading @@ -298,7 +294,6 @@ TEST(liblp, BuilderExport) { EXPECT_EQ(geometry.metadata_max_size, 1024); EXPECT_EQ(geometry.metadata_slot_count, 2); EXPECT_EQ(geometry.first_logical_sector, 24); EXPECT_EQ(geometry.last_logical_sector, 2047); static const size_t kMetadataSpace = ((kMetadataSize * kMetadataSlots) + LP_METADATA_GEOMETRY_SIZE) * 2; Loading fs_mgr/liblp/include/liblp/metadata_format.h +1 −7 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ extern "C" { #define LP_METADATA_HEADER_MAGIC 0x414C5030 /* Current metadata version. */ #define LP_METADATA_MAJOR_VERSION 4 #define LP_METADATA_MAJOR_VERSION 5 #define LP_METADATA_MINOR_VERSION 0 /* Attributes for the LpMetadataPartition::attributes field. Loading Loading @@ -104,12 +104,6 @@ typedef struct LpMetadataGeometry { */ uint64_t first_logical_sector; /* 56: Last usable sector, inclusive, for allocating logical partitions. * At the end of this sector will follow backup metadata slots and the * backup geometry block at the very end. */ uint64_t last_logical_sector; /* 64: Alignment for defining partitions or partition extents. For example, * an alignment of 1MiB will require that all partitions have a size evenly * divisible by 1MiB, and that the smallest unit the partition can grow by Loading fs_mgr/liblp/io_test.cpp +3 −8 Original line number Diff line number Diff line Loading @@ -161,7 +161,6 @@ TEST(liblp, FlashAndReadback) { EXPECT_EQ(exported->geometry.metadata_max_size, imported->geometry.metadata_max_size); EXPECT_EQ(exported->geometry.metadata_slot_count, imported->geometry.metadata_slot_count); EXPECT_EQ(exported->geometry.first_logical_sector, imported->geometry.first_logical_sector); EXPECT_EQ(exported->geometry.last_logical_sector, imported->geometry.last_logical_sector); EXPECT_EQ(exported->header.major_version, imported->header.major_version); EXPECT_EQ(exported->header.minor_version, imported->header.minor_version); EXPECT_EQ(exported->header.header_size, imported->header.header_size); Loading Loading @@ -207,13 +206,14 @@ TEST(liblp, UpdateAnyMetadataSlot) { ASSERT_EQ(imported->partitions.size(), 1); EXPECT_EQ(GetPartitionName(imported->partitions[0]), "vendor"); uint64_t last_sector = imported->geometry.block_device_size / LP_SECTOR_SIZE; // Verify that we didn't overwrite anything in the logical paritition area. // We expect the disk to be filled with 0xcc on creation so we can read // this back and compare it. char expected[LP_SECTOR_SIZE]; memset(expected, 0xcc, sizeof(expected)); for (uint64_t i = imported->geometry.first_logical_sector; i <= imported->geometry.last_logical_sector; i++) { for (uint64_t i = imported->geometry.first_logical_sector; i < last_sector; i++) { char buffer[LP_SECTOR_SIZE]; ASSERT_GE(lseek(fd, i * LP_SECTOR_SIZE, SEEK_SET), 0); ASSERT_TRUE(android::base::ReadFully(fd, buffer, sizeof(buffer))); Loading Loading @@ -261,8 +261,6 @@ TEST(liblp, NoChangingGeometry) { imported = ReadMetadata(fd, 0); ASSERT_NE(imported, nullptr); imported->geometry.last_logical_sector--; ASSERT_FALSE(UpdatePartitionTable(fd, *imported.get(), 1)); } // Test that changing one bit of metadata is enough to break the checksum. Loading Loading @@ -370,9 +368,6 @@ TEST(liblp, TooManyPartitions) { ASSERT_GE(lseek(fd, exported->geometry.first_logical_sector * LP_SECTOR_SIZE, SEEK_SET), 0); ASSERT_TRUE(android::base::ReadFully(fd, buffer, sizeof(buffer))); EXPECT_EQ(memcmp(expected, buffer, LP_SECTOR_SIZE), 0); ASSERT_GE(lseek(fd, exported->geometry.last_logical_sector * LP_SECTOR_SIZE, SEEK_SET), 0); ASSERT_TRUE(android::base::ReadFully(fd, buffer, sizeof(buffer))); EXPECT_EQ(memcmp(expected, buffer, LP_SECTOR_SIZE), 0); } // Test that we can read and write image files. Loading fs_mgr/liblp/utility_test.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ TEST(liblp, GetMetadataOffset) { 16384, 4, 10000, 80000, 0, 0, 1024 * 1024, Loading Loading
fs_mgr/liblp/builder.cpp +12 −30 Original line number Diff line number Diff line Loading @@ -268,39 +268,19 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata } // Compute the first free sector, factoring in alignment. uint64_t free_area = uint64_t free_area_start = AlignTo(total_reserved, device_info.alignment, device_info.alignment_offset); uint64_t first_sector = free_area / LP_SECTOR_SIZE; // Compute the last free sector, which is inclusive. We subtract 1 to make // sure that logical partitions won't overlap with the same sector as the // backup metadata, which could happen if the block device was not aligned // to LP_SECTOR_SIZE. uint64_t last_sector = (device_info.size / LP_SECTOR_SIZE) - 1; // If this check fails, it means either (1) we did not have free space to // allocate a single sector, or (2) we did, but the alignment was high // enough to bump the first sector out of range. Either way, we cannot // continue. if (first_sector > last_sector) { LERROR << "Not enough space to allocate any partition tables."; return false; } uint64_t first_sector = free_area_start / LP_SECTOR_SIZE; // Finally, the size of the allocatable space must be a multiple of the // logical block size. If we have no more free space after this // computation, then we abort. Note that the last sector is inclusive, // so we have to account for that. uint64_t num_free_sectors = last_sector - first_sector + 1; uint64_t sectors_per_block = device_info.logical_block_size / LP_SECTOR_SIZE; if (num_free_sectors < sectors_per_block) { LERROR << "Not enough space to allocate any partition tables."; // There must be one logical block of free space remaining (enough for one partition). uint64_t minimum_disk_size = (first_sector * LP_SECTOR_SIZE) + device_info.logical_block_size; if (device_info.size < minimum_disk_size) { LERROR << "Device must be at least " << minimum_disk_size << " bytes, only has " << device_info.size; return false; } last_sector = first_sector + (num_free_sectors / sectors_per_block) * sectors_per_block - 1; geometry_.first_logical_sector = first_sector; geometry_.last_logical_sector = last_sector; geometry_.metadata_max_size = metadata_max_size; geometry_.metadata_slot_count = metadata_slot_count; geometry_.alignment = device_info.alignment; Loading Loading @@ -452,8 +432,10 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) uint64_t last_free_extent_start = extents.empty() ? geometry_.first_logical_sector : extents.back().end; last_free_extent_start = AlignSector(last_free_extent_start); if (last_free_extent_start <= geometry_.last_logical_sector) { free_regions.emplace_back(last_free_extent_start, geometry_.last_logical_sector + 1); uint64_t last_sector = geometry_.block_device_size / LP_SECTOR_SIZE; if (last_free_extent_start < last_sector) { free_regions.emplace_back(last_free_extent_start, last_sector); } const uint64_t sectors_per_block = geometry_.logical_block_size / LP_SECTOR_SIZE; Loading Loading @@ -559,7 +541,7 @@ std::unique_ptr<LpMetadata> MetadataBuilder::Export() { } uint64_t MetadataBuilder::AllocatableSpace() const { return (geometry_.last_logical_sector - geometry_.first_logical_sector + 1) * LP_SECTOR_SIZE; return geometry_.block_device_size - (geometry_.first_logical_sector * LP_SECTOR_SIZE); } uint64_t MetadataBuilder::UsedSpace() const { Loading
fs_mgr/liblp/builder_test.cpp +0 −5 Original line number Diff line number Diff line Loading @@ -127,7 +127,6 @@ TEST(liblp, InternalAlignment) { unique_ptr<LpMetadata> exported = builder->Export(); ASSERT_NE(exported, nullptr); EXPECT_EQ(exported->geometry.first_logical_sector, 1536); EXPECT_EQ(exported->geometry.last_logical_sector, 2047); // Test a large alignment offset thrown in. device_info.alignment_offset = 753664; Loading @@ -136,7 +135,6 @@ TEST(liblp, InternalAlignment) { exported = builder->Export(); ASSERT_NE(exported, nullptr); EXPECT_EQ(exported->geometry.first_logical_sector, 1472); EXPECT_EQ(exported->geometry.last_logical_sector, 2047); // Alignment offset without alignment doesn't mean anything. device_info.alignment = 0; Loading @@ -151,7 +149,6 @@ TEST(liblp, InternalAlignment) { exported = builder->Export(); ASSERT_NE(exported, nullptr); EXPECT_EQ(exported->geometry.first_logical_sector, 150); EXPECT_EQ(exported->geometry.last_logical_sector, 2045); // Test a small alignment with no alignment offset. device_info.alignment = 11 * 1024; Loading @@ -160,7 +157,6 @@ TEST(liblp, InternalAlignment) { exported = builder->Export(); ASSERT_NE(exported, nullptr); EXPECT_EQ(exported->geometry.first_logical_sector, 160); EXPECT_EQ(exported->geometry.last_logical_sector, 2047); } TEST(liblp, InternalPartitionAlignment) { Loading Loading @@ -298,7 +294,6 @@ TEST(liblp, BuilderExport) { EXPECT_EQ(geometry.metadata_max_size, 1024); EXPECT_EQ(geometry.metadata_slot_count, 2); EXPECT_EQ(geometry.first_logical_sector, 24); EXPECT_EQ(geometry.last_logical_sector, 2047); static const size_t kMetadataSpace = ((kMetadataSize * kMetadataSlots) + LP_METADATA_GEOMETRY_SIZE) * 2; Loading
fs_mgr/liblp/include/liblp/metadata_format.h +1 −7 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ extern "C" { #define LP_METADATA_HEADER_MAGIC 0x414C5030 /* Current metadata version. */ #define LP_METADATA_MAJOR_VERSION 4 #define LP_METADATA_MAJOR_VERSION 5 #define LP_METADATA_MINOR_VERSION 0 /* Attributes for the LpMetadataPartition::attributes field. Loading Loading @@ -104,12 +104,6 @@ typedef struct LpMetadataGeometry { */ uint64_t first_logical_sector; /* 56: Last usable sector, inclusive, for allocating logical partitions. * At the end of this sector will follow backup metadata slots and the * backup geometry block at the very end. */ uint64_t last_logical_sector; /* 64: Alignment for defining partitions or partition extents. For example, * an alignment of 1MiB will require that all partitions have a size evenly * divisible by 1MiB, and that the smallest unit the partition can grow by Loading
fs_mgr/liblp/io_test.cpp +3 −8 Original line number Diff line number Diff line Loading @@ -161,7 +161,6 @@ TEST(liblp, FlashAndReadback) { EXPECT_EQ(exported->geometry.metadata_max_size, imported->geometry.metadata_max_size); EXPECT_EQ(exported->geometry.metadata_slot_count, imported->geometry.metadata_slot_count); EXPECT_EQ(exported->geometry.first_logical_sector, imported->geometry.first_logical_sector); EXPECT_EQ(exported->geometry.last_logical_sector, imported->geometry.last_logical_sector); EXPECT_EQ(exported->header.major_version, imported->header.major_version); EXPECT_EQ(exported->header.minor_version, imported->header.minor_version); EXPECT_EQ(exported->header.header_size, imported->header.header_size); Loading Loading @@ -207,13 +206,14 @@ TEST(liblp, UpdateAnyMetadataSlot) { ASSERT_EQ(imported->partitions.size(), 1); EXPECT_EQ(GetPartitionName(imported->partitions[0]), "vendor"); uint64_t last_sector = imported->geometry.block_device_size / LP_SECTOR_SIZE; // Verify that we didn't overwrite anything in the logical paritition area. // We expect the disk to be filled with 0xcc on creation so we can read // this back and compare it. char expected[LP_SECTOR_SIZE]; memset(expected, 0xcc, sizeof(expected)); for (uint64_t i = imported->geometry.first_logical_sector; i <= imported->geometry.last_logical_sector; i++) { for (uint64_t i = imported->geometry.first_logical_sector; i < last_sector; i++) { char buffer[LP_SECTOR_SIZE]; ASSERT_GE(lseek(fd, i * LP_SECTOR_SIZE, SEEK_SET), 0); ASSERT_TRUE(android::base::ReadFully(fd, buffer, sizeof(buffer))); Loading Loading @@ -261,8 +261,6 @@ TEST(liblp, NoChangingGeometry) { imported = ReadMetadata(fd, 0); ASSERT_NE(imported, nullptr); imported->geometry.last_logical_sector--; ASSERT_FALSE(UpdatePartitionTable(fd, *imported.get(), 1)); } // Test that changing one bit of metadata is enough to break the checksum. Loading Loading @@ -370,9 +368,6 @@ TEST(liblp, TooManyPartitions) { ASSERT_GE(lseek(fd, exported->geometry.first_logical_sector * LP_SECTOR_SIZE, SEEK_SET), 0); ASSERT_TRUE(android::base::ReadFully(fd, buffer, sizeof(buffer))); EXPECT_EQ(memcmp(expected, buffer, LP_SECTOR_SIZE), 0); ASSERT_GE(lseek(fd, exported->geometry.last_logical_sector * LP_SECTOR_SIZE, SEEK_SET), 0); ASSERT_TRUE(android::base::ReadFully(fd, buffer, sizeof(buffer))); EXPECT_EQ(memcmp(expected, buffer, LP_SECTOR_SIZE), 0); } // Test that we can read and write image files. Loading
fs_mgr/liblp/utility_test.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ TEST(liblp, GetMetadataOffset) { 16384, 4, 10000, 80000, 0, 0, 1024 * 1024, Loading