Merge "liblp: Add a ResizePartition helper to MetadataBuilder."

This commit is contained in:
Treehugger Robot 2018-08-02 16:01:24 +00:00 committed by Gerrit Code Review
commit ddcee93c01
4 changed files with 57 additions and 66 deletions

View file

@ -82,11 +82,7 @@ void Partition::RemoveExtents() {
extents_.clear();
}
void Partition::ShrinkTo(uint64_t requested_size) {
uint64_t aligned_size = AlignTo(requested_size, LP_SECTOR_SIZE);
if (size_ <= aligned_size) {
return;
}
void Partition::ShrinkTo(uint64_t aligned_size) {
if (aligned_size == 0) {
RemoveExtents();
return;
@ -106,7 +102,7 @@ void Partition::ShrinkTo(uint64_t requested_size) {
sectors_to_remove -= extent->num_sectors();
extents_.pop_back();
}
DCHECK(size_ == requested_size);
DCHECK(size_ == aligned_size);
}
std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const std::string& block_device,
@ -290,13 +286,7 @@ void MetadataBuilder::RemovePartition(const std::string& name) {
}
}
bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t requested_size) {
// Align the space needed up to the nearest sector.
uint64_t aligned_size = AlignTo(requested_size, LP_SECTOR_SIZE);
if (partition->size() >= aligned_size) {
return true;
}
bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) {
// Figure out how much we need to allocate.
uint64_t space_needed = aligned_size - partition->size();
uint64_t sectors_needed = space_needed / LP_SECTOR_SIZE;
@ -394,8 +384,8 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t requested_siz
return true;
}
void MetadataBuilder::ShrinkPartition(Partition* partition, uint64_t requested_size) {
partition->ShrinkTo(requested_size);
void MetadataBuilder::ShrinkPartition(Partition* partition, uint64_t aligned_size) {
partition->ShrinkTo(aligned_size);
}
std::unique_ptr<LpMetadata> MetadataBuilder::Export() {
@ -465,5 +455,18 @@ void MetadataBuilder::set_block_device_info(const BlockDeviceInfo& device_info)
}
}
bool MetadataBuilder::ResizePartition(Partition* partition, uint64_t requested_size) {
// Align the space needed up to the nearest sector.
uint64_t aligned_size = AlignTo(requested_size, LP_SECTOR_SIZE);
if (aligned_size > partition->size()) {
return GrowPartition(partition, aligned_size);
}
if (aligned_size < partition->size()) {
ShrinkPartition(partition, aligned_size);
}
return true;
}
} // namespace fs_mgr
} // namespace android

View file

@ -45,7 +45,7 @@ TEST(liblp, ResizePartition) {
Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
ASSERT_NE(system, nullptr);
EXPECT_EQ(builder->GrowPartition(system, 65536), true);
EXPECT_EQ(builder->ResizePartition(system, 65536), true);
EXPECT_EQ(system->size(), 65536);
ASSERT_EQ(system->extents().size(), 1);
@ -55,24 +55,23 @@ TEST(liblp, ResizePartition) {
// The first logical sector will be (4096+1024*2)/512 = 12.
EXPECT_EQ(extent->physical_sector(), 12);
// Test growing to the same size.
EXPECT_EQ(builder->GrowPartition(system, 65536), true);
// Test resizing to the same size.
EXPECT_EQ(builder->ResizePartition(system, 65536), true);
EXPECT_EQ(system->size(), 65536);
EXPECT_EQ(system->extents().size(), 1);
EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
// Test growing to a smaller size.
EXPECT_EQ(builder->GrowPartition(system, 0), true);
EXPECT_EQ(system->size(), 65536);
// Test resizing to a smaller size.
EXPECT_EQ(builder->ResizePartition(system, 0), true);
EXPECT_EQ(system->size(), 0);
EXPECT_EQ(system->extents().size(), 0);
// Test resizing to a greater size.
builder->ResizePartition(system, 131072);
EXPECT_EQ(system->size(), 131072);
EXPECT_EQ(system->extents().size(), 1);
EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
// Test shrinking to a greater size.
builder->ShrinkPartition(system, 131072);
EXPECT_EQ(system->size(), 65536);
EXPECT_EQ(system->extents().size(), 1);
EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
EXPECT_EQ(system->extents()[0]->num_sectors(), 131072 / LP_SECTOR_SIZE);
// Test shrinking within the same extent.
builder->ShrinkPartition(system, 32768);
builder->ResizePartition(system, 32768);
EXPECT_EQ(system->size(), 32768);
EXPECT_EQ(system->extents().size(), 1);
extent = system->extents()[0]->AsLinearExtent();
@ -81,7 +80,7 @@ TEST(liblp, ResizePartition) {
EXPECT_EQ(extent->physical_sector(), 12);
// Test shrinking to 0.
builder->ShrinkPartition(system, 0);
builder->ResizePartition(system, 0);
EXPECT_EQ(system->size(), 0);
EXPECT_EQ(system->extents().size(), 0);
}
@ -92,11 +91,11 @@ TEST(liblp, PartitionAlignment) {
// Test that we align up to one sector.
Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
ASSERT_NE(system, nullptr);
EXPECT_EQ(builder->GrowPartition(system, 10000), true);
EXPECT_EQ(builder->ResizePartition(system, 10000), true);
EXPECT_EQ(system->size(), 10240);
EXPECT_EQ(system->extents().size(), 1);
builder->ShrinkPartition(system, 9000);
builder->ResizePartition(system, 9000);
EXPECT_EQ(system->size(), 9216);
EXPECT_EQ(system->extents().size(), 1);
}
@ -174,8 +173,8 @@ TEST(liblp, InternalPartitionAlignment) {
// Add a bunch of small extents to each, interleaving.
for (size_t i = 0; i < 10; i++) {
ASSERT_TRUE(builder->GrowPartition(a, a->size() + 4096));
ASSERT_TRUE(builder->GrowPartition(b, b->size() + 4096));
ASSERT_TRUE(builder->ResizePartition(a, a->size() + 4096));
ASSERT_TRUE(builder->ResizePartition(b, b->size() + 4096));
}
EXPECT_EQ(a->size(), 40960);
EXPECT_EQ(b->size(), 40960);
@ -203,9 +202,9 @@ TEST(liblp, UseAllDiskSpace) {
Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
ASSERT_NE(system, nullptr);
EXPECT_EQ(builder->GrowPartition(system, 1036288), true);
EXPECT_EQ(builder->ResizePartition(system, 1036288), true);
EXPECT_EQ(system->size(), 1036288);
EXPECT_EQ(builder->GrowPartition(system, 1036289), false);
EXPECT_EQ(builder->ResizePartition(system, 1036289), false);
}
TEST(liblp, BuildComplex) {
@ -215,9 +214,9 @@ TEST(liblp, BuildComplex) {
Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
ASSERT_NE(system, nullptr);
ASSERT_NE(vendor, nullptr);
EXPECT_EQ(builder->GrowPartition(system, 65536), true);
EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
EXPECT_EQ(builder->GrowPartition(system, 98304), true);
EXPECT_EQ(builder->ResizePartition(system, 65536), true);
EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
EXPECT_EQ(builder->ResizePartition(system, 98304), true);
EXPECT_EQ(system->size(), 98304);
EXPECT_EQ(vendor->size(), 32768);
@ -268,9 +267,9 @@ TEST(liblp, BuilderExport) {
Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
ASSERT_NE(system, nullptr);
ASSERT_NE(vendor, nullptr);
EXPECT_EQ(builder->GrowPartition(system, 65536), true);
EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
EXPECT_EQ(builder->GrowPartition(system, 98304), true);
EXPECT_EQ(builder->ResizePartition(system, 65536), true);
EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
EXPECT_EQ(builder->ResizePartition(system, 98304), true);
unique_ptr<LpMetadata> exported = builder->Export();
EXPECT_NE(exported, nullptr);
@ -323,9 +322,9 @@ TEST(liblp, BuilderImport) {
Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
ASSERT_NE(system, nullptr);
ASSERT_NE(vendor, nullptr);
EXPECT_EQ(builder->GrowPartition(system, 65536), true);
EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
EXPECT_EQ(builder->GrowPartition(system, 98304), true);
EXPECT_EQ(builder->ResizePartition(system, 65536), true);
EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
EXPECT_EQ(builder->ResizePartition(system, 98304), true);
unique_ptr<LpMetadata> exported = builder->Export();
ASSERT_NE(exported, nullptr);

View file

@ -162,29 +162,17 @@ class MetadataBuilder {
// Find a partition by name. If no partition is found, nullptr is returned.
Partition* FindPartition(const std::string& name);
// Grow a partition to the requested size. If the partition's size is already
// greater or equal to the requested size, this will return true and the
// partition table will not be changed. Otherwise, a greedy algorithm is
// used to find free gaps in the partition table and allocate them for this
// partition. If not enough space can be allocated, false is returned, and
// the parition table will not be modified.
// Grow or shrink a partition to the requested size. This size will be
// rounded UP to the nearest block (512 bytes).
//
// The size will be rounded UP to the nearest sector.
// When growing a partition, a greedy algorithm is used to find free gaps
// in the partition table and allocate them. If not enough space can be
// allocated, false is returned, and the parition table will not be
// modified.
//
// Note, this is an in-memory operation, and it does not alter the
// underlying filesystem or contents of the partition on disk.
bool GrowPartition(Partition* partition, uint64_t requested_size);
// Shrink a partition to the requested size. If the partition is already
// smaller than the given size, this will return and the partition table
// will not be changed. Otherwise, extents will be removed and/or shrunk
// from the end of the partition until it is the requested size.
//
// The size will be rounded UP to the nearest sector.
//
// Note, this is an in-memory operation, and it does not alter the
// underlying filesystem or contents of the partition on disk.
void ShrinkPartition(Partition* partition, uint64_t requested_size);
bool ResizePartition(Partition* partition, uint64_t requested_size);
// Amount of space that can be allocated to logical partitions.
uint64_t AllocatableSpace() const;
@ -198,7 +186,8 @@ class MetadataBuilder {
MetadataBuilder();
bool Init(const BlockDeviceInfo& info, uint32_t metadata_max_size, uint32_t metadata_slot_count);
bool Init(const LpMetadata& metadata);
bool GrowPartition(Partition* partition, uint64_t aligned_size);
void ShrinkPartition(Partition* partition, uint64_t aligned_size);
uint64_t AlignSector(uint64_t sector);
LpMetadataGeometry geometry_;

View file

@ -85,7 +85,7 @@ static bool AddDefaultPartitions(MetadataBuilder* builder) {
if (!system) {
return false;
}
return builder->GrowPartition(system, 24 * 1024);
return builder->ResizePartition(system, 24 * 1024);
}
// Create a temporary disk and flash it with the default partition setup.
@ -345,7 +345,7 @@ TEST(liblp, TooManyPartitions) {
ASSERT_NE(partition, nullptr);
// Add one extent to any partition to fill up more space - we're at 508
// bytes after this, out of 512.
ASSERT_TRUE(builder->GrowPartition(partition, 1024));
ASSERT_TRUE(builder->ResizePartition(partition, 1024));
unique_ptr<LpMetadata> exported = builder->Export();
ASSERT_NE(exported, nullptr);